summaryrefslogtreecommitdiff
path: root/src/redis-trib.rb
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2016-01-13 17:30:53 +0100
committerantirez <antirez@gmail.com>2016-01-13 17:30:53 +0100
commitf984cef2171f18158ffbfba34f988f559f855bba (patch)
tree479e2ce27019b1f7ee459abbc016cde03378dd15 /src/redis-trib.rb
parent152e9f67f885eea48da815412740ccd3029bf46d (diff)
downloadredis-f984cef2171f18158ffbfba34f988f559f855bba.tar.gz
Cluster: fix rebalancing to always empty nodes.
Because of rounding error even with weight=0 sometimes a node was left with an assigned slot. Close #3001.
Diffstat (limited to 'src/redis-trib.rb')
-rwxr-xr-xsrc/redis-trib.rb27
1 files changed, 24 insertions, 3 deletions
diff --git a/src/redis-trib.rb b/src/redis-trib.rb
index 125e5a4a1..63d2acec1 100755
--- a/src/redis-trib.rb
+++ b/src/redis-trib.rb
@@ -1044,7 +1044,6 @@ class RedisTrib
over_threshold = true
end
end
- puts "#{n} balance is #{n.info[:balance]} slots" if $verbose
threshold_reached = true if over_threshold
end
}
@@ -1053,15 +1052,37 @@ class RedisTrib
return
end
- # Sort nodes by their slots balance.
+ # Only consider nodes we want to change
sn = @nodes.select{|n|
n.has_flag?("master") && n.info[:w]
- }.sort{|a,b|
+ }
+
+ # Because of rounding, it is possible that the balance of all nodes
+ # summed does not give 0. Make sure that nodes that have to provide
+ # slots are always matched by nodes receiving slots.
+ total_balance = sn.map{|x| x.info[:balance]}.reduce{|a,b| a+b}
+ while total_balance > 0
+ sn.each{|n|
+ if n.info[:balance] < 0 && total_balance > 0
+ n.info[:balance] -= 1
+ total_balance -= 1
+ end
+ }
+ end
+
+ # Sort nodes by their slots balance.
+ sn = sn.sort{|a,b|
a.info[:balance] <=> b.info[:balance]
}
xputs ">>> Rebalancing across #{nodes_involved} nodes. Total weight = #{total_weight}"
+ if $verbose
+ sn.each{|n|
+ puts "#{n} balance is #{n.info[:balance]} slots"
+ }
+ end
+
# Now we have at the start of the 'sn' array nodes that should get
# slots, at the end nodes that must give slots.
# We take two indexes, one at the start, and one at the end,