Added support for remapping the cluster's keyspace on a failover

This commit is contained in:
Bar Shaul
2021-10-28 12:10:55 +03:00
committed by michael-grunder
parent 6be921004a
commit b1a52688e1
2 changed files with 23 additions and 7 deletions

View File

@@ -683,7 +683,7 @@ static int cluster_map_slots(redisCluster *c, clusterReply *r) {
clusterReply *r2, *r3;
unsigned short port;
char *host, key[1024];
zend_hash_clean(c->nodes);
for (i = 0; i < r->elements; i++) {
// Inner response
r2 = r->element[i];
@@ -1396,7 +1396,7 @@ static void cluster_update_slot(redisCluster *c) {
/* Do we already have the new slot mapped */
if (c->master[c->redir_slot]) {
/* No need to do anything if it's the same node */
if (!CLUSTER_REDIR_CMP(c)) {
if (!CLUSTER_REDIR_CMP(c, SLOT_SOCK(c,c->redir_slot))) {
return;
}
@@ -1407,6 +1407,22 @@ static void cluster_update_slot(redisCluster *c) {
/* Just point to this slot */
c->master[c->redir_slot] = node;
} else {
/* If the redirected node is a replica of the previous slot owner, a failover has taken place.
We must then remap the cluster's keyspace in order to update the cluster's topology. */
redisClusterNode *prev_master = SLOT(c,c->redir_slot);
redisClusterNode *slave;
ZEND_HASH_FOREACH_PTR(prev_master->slaves, slave) {
if (slave == NULL) {
continue;
}
if (!CLUSTER_REDIR_CMP(c, slave->sock)) {
// Detected a failover, the redirected node was a replica
// Remap the cluster's keyspace
cluster_map_keyspace(c);
return;
}
} ZEND_HASH_FOREACH_END();
/* Create our node */
node = cluster_node_create(c, c->redir_host, c->redir_host_len,
c->redir_port, c->redir_slot, 0);

View File

@@ -45,11 +45,11 @@
#define CMD_SOCK(c) (c->cmd_sock)
#define CMD_STREAM(c) (c->cmd_sock->stream)
/* Compare redirection slot information with what we have */
#define CLUSTER_REDIR_CMP(c) \
(SLOT_SOCK(c,c->redir_slot)->port != c->redir_port || \
ZSTR_LEN(SLOT_SOCK(c,c->redir_slot)->host) != c->redir_host_len || \
memcmp(ZSTR_VAL(SLOT_SOCK(c,c->redir_slot)->host),c->redir_host,c->redir_host_len))
/* Compare redirection slot information with the passed node */
#define CLUSTER_REDIR_CMP(c, sock) \
(sock->port != c->redir_port || \
ZSTR_LEN(sock->host) != c->redir_host_len || \
memcmp(ZSTR_VAL(sock->host),c->redir_host,c->redir_host_len))
/* Clear out our "last error" */
#define CLUSTER_CLEAR_ERROR(c) do { \