Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
beb5058e
Commit
beb5058e
authored
Jan 11, 2016
by
antirez
Browse files
Cluster: implement redis-trib fix for uncovered slots.
parent
8ef716d1
Changes
1
Show whitespace changes
Inline
Side-by-side
src/redis-trib.rb
View file @
beb5058e
...
@@ -425,6 +425,7 @@ class RedisTrib
...
@@ -425,6 +425,7 @@ class RedisTrib
def nodes_with_keys_in_slot(slot)
def nodes_with_keys_in_slot(slot)
nodes = []
nodes = []
@nodes.each{|n|
@nodes.each{|n|
next if n.has_flag?("slave")
nodes << n if n.r.cluster("getkeysinslot",slot,1).length > 0
nodes << n if n.r.cluster("getkeysinslot",slot,1).length > 0
}
}
nodes
nodes
...
@@ -443,7 +444,7 @@ class RedisTrib
...
@@ -443,7 +444,7 @@ class RedisTrib
not_covered.each{|slot|
not_covered.each{|slot|
nodes = nodes_with_keys_in_slot(slot)
nodes = nodes_with_keys_in_slot(slot)
slots[slot] = nodes
slots[slot] = nodes
xputs
"Slot
#{
slot
}
has keys in
#{
nodes
.
length
}
nodes:
#{
nodes
.
join
}
"
xputs "Slot #{slot} has keys in #{nodes.length} nodes: #{nodes.join
(", ")
}"
}
}
none = slots.select {|k,v| v.length == 0}
none = slots.select {|k,v| v.length == 0}
...
@@ -479,14 +480,20 @@ class RedisTrib
...
@@ -479,14 +480,20 @@ class RedisTrib
xputs multi.keys.join(",")
xputs multi.keys.join(",")
yes_or_die "Fix these slots by moving keys into a single node?"
yes_or_die "Fix these slots by moving keys into a single node?"
multi.each{|slot,nodes|
multi.each{|slot,nodes|
xputs
">>> Covering slot
#{
slot
}
moving keys to
#{
nodes
[
0
]
}
"
target = get_node_with_most_keys_in_slot(nodes,slot)
# TODO
xputs ">>> Covering slot #{slot} moving keys to #{target}"
# 1) Set all nodes as "MIGRATING" for this slot, so that we
# can access keys in the hash slot using ASKING.
target.r.cluster('addslots',slot)
# 2) Move everything to node[0]
target.r.cluster('setslot',slot,'stable')
# 3) Clear MIGRATING from nodes, and ADDSLOTS the slot to
nodes.each{|src|
# node[0].
next if src == target
raise
"TODO: Work in progress"
# Set the source node in 'importing' state (even if we will
# actually migrate keys away) in order to avoid receiving
# redirections for MIGRATE.
src.r.cluster('setslot',slot,'importing',target.info[:name])
move_slot(src,target,slot,:dots=>true,:fix=>true,:cold=>true)
src.r.cluster('setslot',slot,'stable')
}
}
}
end
end
end
end
...
@@ -501,6 +508,22 @@ class RedisTrib
...
@@ -501,6 +508,22 @@ class RedisTrib
nil
nil
end
end
# Return the node, among 'nodes' with the greatest number of keys
# in the specified slot.
def get_node_with_most_keys_in_slot(nodes,slot)
best = nil
best_numkeys = 0
@nodes.each{|n|
next if n.has_flag?("slave")
numkeys = n.r.cluster("countkeysinslot",slot)
if numkeys > best_numkeys || best == nil
best = n
best_numkeys = numkeys
end
}
return best
end
# Slot 'slot' was found to be in importing or migrating state in one or
# 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
# more nodes. This function fixes this condition by migrating keys where
# it seems more sensible.
# it seems more sensible.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment