From 6c0047c4304fc5cd84029996587d6ea1416d0578 Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 30 Sep 2011 18:41:25 +0200 Subject: [PATCH] redis-trib: better slots allocation strategy for resharding --- src/redis-trib.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/redis-trib.rb b/src/redis-trib.rb index 083f9740..3717f54e 100755 --- a/src/redis-trib.rb +++ b/src/redis-trib.rb @@ -287,10 +287,22 @@ class RedisTrib # instance. def compute_reshard_table(sources,numslots) moved = [] - sources.each{|s| + # Sort from bigger to smaller instance, for two reasons: + # 1) If we take less slots than instanes it is better to start getting from + # the biggest instances. + # 2) We take one slot more from the first instance in the case of not perfect + # divisibility. Like we have 3 nodes and need to get 10 slots, we take + # 4 from the first, and 3 from the rest. So the biggest is always the first. + sources = sources.sort{|a,b| b.slots.length <=> a.slots.length} + sources.each_with_index{|s,i| # Every node will provide a number of slots proportional to the # slots it has assigned. - n = (numslots.to_f/4096*s.slots.length).ceil + n = (numslots.to_f/4096*s.slots.length) + if i == 0 + n = n.ceil + else + n = n.floor + end s.slots.keys.sort[(0...n)].each{|slot| if moved.length < numslots moved << {:source => s, :slot => slot}