summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2016-01-26 12:32:53 +0100
committerantirez <antirez@gmail.com>2016-01-26 14:22:32 +0100
commit025f936cc45bdf7432dc38faf4a3c93b300c99a8 (patch)
treed4ad246ecd6eb33832a416d65425a71065c826cc
parent5d9a53359132aac5037df6536f83cb255ae0eafb (diff)
downloadredis-025f936cc45bdf7432dc38faf4a3c93b300c99a8.tar.gz
Better address udpate strategy when processing gossip sections.
The change covers the case where: 1. There is a node we can't reach (in fail or pfail state). 2. We see a different address for this node, in the gossip section sent to us by a node that, instead, is able to talk with the node we cannot talk to. In this case it's a good bet to switch to the address reported by this node, since there was an address switch and it is able to talk with the node and we are not. However previosuly this was done in a dangerous way, by initiating an handshake. The handshake, using the MEET packet, forces the receiver to join our cluster, and this is not a good idea. If the node in question really just switched address, but is the same node, it already knows about us, so we just need to perform an address update and a reconnection. So with this commit instead we just update the address of the node, release the node link if any, and attempt to reconnect in the next clusterCron() cycle. The commit also improves debugging messages printed by Cluster during address or ID switches.
-rw-r--r--src/cluster.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/cluster.c b/src/cluster.c
index 5917db890..f71783005 100644
--- a/src/cluster.c
+++ b/src/cluster.c
@@ -531,6 +531,7 @@ void clusterReset(int hard) {
sdsfree(oldname);
getRandomHexChars(myself->name, REDIS_CLUSTER_NAMELEN);
clusterAddNode(myself);
+ serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s", myself->name);
}
/* Make sure to persist the new config and update the state. */
@@ -1330,14 +1331,27 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) {
}
/* If we already know this node, but it is not reachable, and
+<<<<<<< HEAD
* we see a different address in the gossip section, start an
* handshake with the (possibly) new address: this will result
* into a node address update if the handshake will be
* successful. */
if (node->flags & (REDIS_NODE_FAIL|REDIS_NODE_PFAIL) &&
+=======
+ * we see a different address in the gossip section of a node that
+ * can talk with this other node, update the address, disconnect
+ * the old link if any, so that we'll attempt to connect with the
+ * new address. */
+ if (node->flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL) &&
+ !(flags & CLUSTER_NODE_NOADDR) &&
+ !(flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) &&
+>>>>>>> bd998b7... Better address udpate strategy when processing gossip sections.
(strcasecmp(node->ip,g->ip) || node->port != ntohs(g->port)))
{
- clusterStartHandshake(g->ip,ntohs(g->port));
+ if (node->link) freeClusterLink(node->link);
+ memcpy(node->ip,g->ip,NET_IP_STR_LEN);
+ node->port = g->port;
+ node->flags &= ~CLUSTER_NODE_NOADDR;
}
} else {
/* If it's not in NOADDR state and we don't have it, we
@@ -1715,8 +1729,11 @@ int clusterProcessPacket(clusterLink *link) {
/* If the reply has a non matching node ID we
* disconnect this node and set it as not having an associated
* address. */
- redisLog(REDIS_DEBUG,"PONG contains mismatching sender ID");
- link->node->flags |= REDIS_NODE_NOADDR;
+ redisLog(REDIS_WARNING,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d",
+ link->node->name,
+ (int)(mstime()-(link->node->ctime)),
+ link->node->flags);
+ link->node->flags |= CLUSTER_NODE_NOADDR;
link->node->ip[0] = '\0';
link->node->port = 0;
freeClusterLink(link);