mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
redis-trib: initial support to fix "open" slots.
Open slots are slots found in importing or migrating slot when a cluster check is performed.
This commit is contained in:
parent
1a6df1049d
commit
ed47f77977
@ -57,6 +57,10 @@ class ClusterNode
|
||||
@info[:slots]
|
||||
end
|
||||
|
||||
def has_flag?(flag)
|
||||
@info[:flags].index(flag)
|
||||
end
|
||||
|
||||
def to_s
|
||||
"#{@info[:host]}:#{@info[:port]}"
|
||||
end
|
||||
@ -197,7 +201,7 @@ class ClusterNode
|
||||
x.count == 1 ? x.first.to_s : "#{x.first}-#{x.last}"
|
||||
}.join(",")
|
||||
|
||||
"[#{@info[:cluster_state].upcase}] #{self.info[:name]} #{self.to_s} slots:#{slots} (#{self.slots.length} slots)"
|
||||
"[#{@info[:cluster_state].upcase} #{(self.info[:flags]-["myself"]).join(",")}] #{self.info[:name]} #{self.to_s} slots:#{slots} (#{self.slots.length} slots)"
|
||||
end
|
||||
|
||||
# Return a single string representing nodes and associated slots.
|
||||
@ -257,6 +261,7 @@ class RedisTrib
|
||||
puts "Performing Cluster Check (using node #{@nodes[0]})"
|
||||
show_nodes
|
||||
check_config_consistency
|
||||
check_open_slots
|
||||
check_slots_coverage
|
||||
end
|
||||
|
||||
@ -282,6 +287,26 @@ class RedisTrib
|
||||
end
|
||||
end
|
||||
|
||||
def check_open_slots
|
||||
open_slots = []
|
||||
@nodes.each{|n|
|
||||
if n.info[:migrating].size > 0
|
||||
puts "[WARNING] Node #{n} has slots in migrating state."
|
||||
open_slots += n.info[:migrating].keys
|
||||
elsif n.info[:importing].size > 0
|
||||
puts "[WARNING] Node #{n} has slots in importing state."
|
||||
open_slots += n.info[:importing].keys
|
||||
end
|
||||
}
|
||||
open_slots.uniq!
|
||||
if open_slots.length
|
||||
puts "[WARNING] The following slots are open: #{open_slots.join(",")}"
|
||||
end
|
||||
if @fix
|
||||
open_slots.each{|slot| fix_open_slot slot}
|
||||
end
|
||||
end
|
||||
|
||||
def nodes_with_keys_in_slot(slot)
|
||||
nodes = []
|
||||
@nodes.each{|n|
|
||||
@ -351,6 +376,36 @@ class RedisTrib
|
||||
end
|
||||
end
|
||||
|
||||
# Slot 'slot' was found to be in importing or migrating state in one or
|
||||
# more nodes. This function fixes this condition by migrating keys where
|
||||
# it seems more sensible.
|
||||
def fix_open_slot(slot)
|
||||
migrating = []
|
||||
importing = []
|
||||
@nodes.each{|n|
|
||||
next if n.has_flag? "slave"
|
||||
if n.info[:migrating][slot]
|
||||
migrating << n
|
||||
elsif n.info[:importing][slot]
|
||||
importing << n
|
||||
elsif n.r.cluster("countkeysinslot",slot) > 0
|
||||
puts "Found keys about slot #{slot} in node #{n}!"
|
||||
end
|
||||
}
|
||||
puts "Fixing open slot 0:"
|
||||
puts "Set as migrating in: #{migrating.join(",")}"
|
||||
puts "Set as importing in: #{importing.join(",")}"
|
||||
|
||||
# Case 1: The slot is in migrating state in one slot, and in
|
||||
# importing state in 1 slot. That's trivial to address.
|
||||
if migrating.length == 1 && importing.length == 1
|
||||
puts "Moving slot zero to #{importing[1]}"
|
||||
move_slot(migrating[0],importing[0],0,:verbose=>true)
|
||||
else
|
||||
puts "Sorry, Redis-trib can't fix this slot yet (work in progress)"
|
||||
end
|
||||
end
|
||||
|
||||
# Check if all the nodes agree about the cluster configuration
|
||||
def check_config_consistency
|
||||
signatures=[]
|
||||
@ -472,7 +527,7 @@ class RedisTrib
|
||||
# and the slot as migrating in the target host. Note that the order of
|
||||
# the operations is important, as otherwise a client may be redirected
|
||||
# to the target node that does not yet know it is importing this slot.
|
||||
print "Moving slot #{slot} from #{source.info_string}: "; STDOUT.flush
|
||||
print "Moving slot #{slot} from #{source} to #{target}: "; STDOUT.flush
|
||||
target.r.cluster("setslot",slot,"importing",source.info[:name])
|
||||
source.r.cluster("setslot",slot,"migrating",target.info[:name])
|
||||
# Migrate all the keys from source to target using the MIGRATE command
|
||||
|
Loading…
Reference in New Issue
Block a user