From: antirez Date: Wed, 13 Apr 2011 08:39:06 +0000 (+0200) Subject: Merge branch 'unstable' of github.com:antirez/redis into unstable X-Git-Url: https://git.saurik.com/redis.git/commitdiff_plain/a54d9805ee1c46d574aab8e349fd778d3a4bc67b?hp=1087227d4140a3bf5f0248e411fa084ba3fe2bf4 Merge branch 'unstable' of github.com:antirez/redis into unstable --- diff --git a/TODO b/TODO index 3032392e..92b6ea93 100644 --- a/TODO +++ b/TODO @@ -9,19 +9,13 @@ WARNING: are you a possible Redis contributor? us, and *how* exactly this can be implemented to have good changes of a merge. Otherwise it is probably wasted work! Thank you -DISKSTORE TODO -============== -* Fix FLUSHALL/FLUSHDB: the queue of pending reads/writes should be handled. -* Check that 00/00 and ff/ff exist at startup, otherwise exit with error. -* Implement sync flush option, where data is written synchronously on disk when a command is executed. -* Implement MULTI/EXEC as transaction abstract API to diskstore.c, with transaction_start, transaction_end, and a journal to recover. -* Stop BGSAVE thread on shutdown and any other condition where the child is killed during normal bgsave. -* Fix RANDOMKEY to really do something interesting -* Fix DBSIZE to really do something interesting -* Add a DEBUG command to check if an entry is or not in memory currently +API CHANGES +=========== -* dscache.c near 236, kobj = createStringObject... we could use static obj. +* Turn commands into variadic versions when it makes sense, that is, when + the variable number of arguments represent values, and there is no conflict + with the return value of the command. APPEND ONLY FILE ================ @@ -61,3 +55,15 @@ KNOWN BUGS or alike) too many time passes? We should prevent expires while the AOF is loading. +DISKSTORE TODO +============== + +* Fix FLUSHALL/FLUSHDB: the queue of pending reads/writes should be handled. +* Check that 00/00 and ff/ff exist at startup, otherwise exit with error. +* Implement sync flush option, where data is written synchronously on disk when a command is executed. +* Implement MULTI/EXEC as transaction abstract API to diskstore.c, with transaction_start, transaction_end, and a journal to recover. +* Stop BGSAVE thread on shutdown and any other condition where the child is killed during normal bgsave. +* Fix RANDOMKEY to really do something interesting +* Fix DBSIZE to really do something interesting +* Add a DEBUG command to check if an entry is or not in memory currently +* dscache.c near 236, kobj = createStringObject... we could use static obj. diff --git a/src/cluster.c b/src/cluster.c index 0a580fa7..4e3cf746 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -943,6 +943,7 @@ void clusterCron(void) { node->flags &= ~REDIS_NODE_PFAIL; } else if (node->flags & REDIS_NODE_FAIL && !node->numslaves) { node->flags &= ~REDIS_NODE_FAIL; + clusterUpdateState(); } } else { /* Timeout reached. Set the noad se possibly failing if it is diff --git a/src/redis-trib.rb b/src/redis-trib.rb index f2e14010..cd35587f 100755 --- a/src/redis-trib.rb +++ b/src/redis-trib.rb @@ -3,6 +3,8 @@ require 'rubygems' require 'redis' +ClusterHashSlots = 4096 + def xputs(s) printf s STDOUT.flush @@ -17,6 +19,8 @@ class ClusterNode end @host = s[0] @port = s[1] + @slots = {} + @dirty = false end def to_s @@ -51,12 +55,55 @@ class ClusterNode end end + def add_slots(slots) + slots.each{|s| + @slots[s] = :new + } + @dirty = true + end + + def flush_node_config + return if !@dirty + new = [] + @slots.each{|s,val| + if val == :new + new << s + @slots[s] = true + end + } + @r.cluster("addslots",*new) + @dirty = false + end + + def info + slots = @slots.map{|k,v| k}.reduce{|a,b| + a = [(a..a)] if !a.is_a?(Array) + if b == (a[-1].last)+1 + a[-1] = (a[-1].first)..b + a + else + a << (b..b) + end + }.map{|x| + (x.first == x.last) ? x.first.to_s : "#{x.first}-#{x.last}" + }.join(",") + "#{self.to_s.ljust(25)} slots:#{slots}" + end + + def is_dirty? + @dirty + end + def r @r end end class RedisTrib + def initialize + @nodes = [] + end + def check_arity(req_args, num_args) if ((req_args > 0 and num_args != req_args) || (req_args < 0 and num_args < req_args.abs)) @@ -72,7 +119,52 @@ class RedisTrib node.connect node.assert_cluster node.assert_empty + @nodes << node } + puts "Performing hash slots allocation on #{@nodes.length} nodes..." + alloc_slots + show_nodes + yes_or_die "Can I set the above configuration?" + flush_nodes_config + puts "** Nodes configuration updated" + puts "Sending CLUSTER MEET messages to join the cluster" + join_cluster + end + + def alloc_slots + slots_per_node = ClusterHashSlots/@nodes.length + i = 0 + @nodes.each{|n| + first = i*slots_per_node + last = first+slots_per_node-1 + last = ClusterHashSlots-1 if i == @nodes.length-1 + n.add_slots first..last + i += 1 + } + end + + def flush_nodes_config + @nodes.each{|n| + n.flush_node_config + } + end + + def show_nodes + @nodes.each{|n| + puts n.info + } + end + + def join_cluster + end + + def yes_or_die(msg) + print "#{msg} (type 'yes' to accept): " + STDOUT.flush + if !(STDIN.gets.chomp.downcase == "yes") + puts "Aborting..." + exit 1 + end end end