CLUSTER BUMPEPOCH initial implementation fixed.

This commit is contained in:
antirez 2016-01-11 15:39:09 +01:00
parent e4eb6c7a5d
commit 02c40c9dc2
2 changed files with 25 additions and 14 deletions

View File

@ -4022,13 +4022,6 @@ void clusterCommand(client *c) {
}
clusterDelSlot(slot);
clusterAddSlot(n,slot);
} else if (!strcasecmp(c->argv[3]->ptr,"bumpepoch") && c->argc == 2) {
/* CLUSTER BUMPEPOCH */
int retval = clusterBumpConfigEpochWithoutConsensus();
sds reply = sdscatprintf(sdsempty(),"%s %llu\r\n",
(retval == C_OK) ? "BUMPED" : "STILL",
(unsigned long long) myself->configEpoch);
addReplySds(c,reply);
} else {
addReplyError(c,
"Invalid CLUSTER SETSLOT action or number of arguments");
@ -4036,6 +4029,13 @@ void clusterCommand(client *c) {
}
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_UPDATE_STATE);
addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"bumpepoch") && c->argc == 2) {
/* CLUSTER BUMPEPOCH */
int retval = clusterBumpConfigEpochWithoutConsensus();
sds reply = sdscatprintf(sdsempty(),"+%s %llu\r\n",
(retval == C_OK) ? "BUMPED" : "STILL",
(unsigned long long) myself->configEpoch);
addReplySds(c,reply);
} else if (!strcasecmp(c->argv[1]->ptr,"info") && c->argc == 2) {
/* CLUSTER INFO */
char *statestr[] = {"ok","fail","needhelp"};

View File

@ -499,13 +499,15 @@ class RedisTrib
end
# Return the owner of the specified slot
def get_slot_owner(slot)
def get_slot_owners(slot)
owners = []
@nodes.each{|n|
next if n.has_flag?("slave")
n.slots.each{|s,_|
return n if s == slot
owners << n if s == slot
}
}
nil
owners
end
# Return the node, among 'nodes' with the greatest number of keys
@ -532,7 +534,8 @@ class RedisTrib
# Try to obtain the current slot owner, according to the current
# nodes configuration.
owner = get_slot_owner(slot)
owners = get_slot_owners(slot)
owner = owners[0] if owners.length == 1
migrating = []
importing = []
@ -585,9 +588,17 @@ class RedisTrib
# Note that this case also covers multiple nodes having the slot
# in migrating state, since migrating is a valid state only for
# slot owners.
#
# TODO: Use CLUSTER BUMPEPOCH in order to make the
# winner able to claim the slot over all the other nodes.
if owners.length > 1
owner = get_node_with_most_keys_in_slot(owners,slot)
owners.each{|n|
next if n == owner
n.r.cluster('delslots',slot)
n.r.cluster('setslot',slot,'importing',owner.info[:name])
importing.delete(n) # Avoid duplciates
importing << n
}
owner.r.cluster('bumpepoch')
end
# Case 1: The slot is in migrating state in one slot, and in
# importing state in 1 slot. That's trivial to address.