mirror of
https://github.com/php-win-ext/phpredis.git
synced 2026-03-24 00:52:16 +01:00
Added support for remapping the cluster's keyspace on a failover
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 { \
|
||||
|
||||
Reference in New Issue
Block a user