Unverified Commit ff641965 authored by judeng's avatar judeng Committed by GitHub
Browse files

Optimize the performance of clusterSendPing for large clusters (#10624)

Optimize the performance of clusterSendPing by improving speed of checking for duplicate items in gossip.
parent 99a425d0
...@@ -964,6 +964,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { ...@@ -964,6 +964,7 @@ clusterNode *createClusterNode(char *nodename, int flags) {
node->numslaves = 0; node->numslaves = 0;
node->slaves = NULL; node->slaves = NULL;
node->slaveof = NULL; node->slaveof = NULL;
node->last_in_ping_gossip = 0;
node->ping_sent = node->pong_received = 0; node->ping_sent = node->pong_received = 0;
node->data_received = 0; node->data_received = 0;
node->fail_time = 0; node->fail_time = 0;
...@@ -2847,18 +2848,6 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) { ...@@ -2847,18 +2848,6 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) {
* totlen field is up to the caller. */ * totlen field is up to the caller. */
} }
/* Return non zero if the node is already present in the gossip section of the
* message pointed by 'hdr' and having 'count' gossip entries. Otherwise
* zero is returned. Helper for clusterSendPing(). */
int clusterNodeIsInGossipSection(clusterMsg *hdr, int count, clusterNode *n) {
int j;
for (j = 0; j < count; j++) {
if (memcmp(hdr->data.ping.gossip[j].nodename,n->name,
CLUSTER_NAMELEN) == 0) break;
}
return j != count;
}
/* Set the i-th entry of the gossip section in the message pointed by 'hdr' /* Set the i-th entry of the gossip section in the message pointed by 'hdr'
* to the info of the specified node 'n'. */ * to the info of the specified node 'n'. */
void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) { void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) {
...@@ -2878,6 +2867,8 @@ void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) { ...@@ -2878,6 +2867,8 @@ void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) {
/* Send a PING or PONG packet to the specified node, making sure to add enough /* Send a PING or PONG packet to the specified node, making sure to add enough
* gossip information. */ * gossip information. */
void clusterSendPing(clusterLink *link, int type) { void clusterSendPing(clusterLink *link, int type) {
static unsigned long long cluster_pings_sent = 0;
cluster_pings_sent++;
unsigned char *buf; unsigned char *buf;
clusterMsg *hdr; clusterMsg *hdr;
int gossipcount = 0; /* Number of gossip sections added so far. */ int gossipcount = 0; /* Number of gossip sections added so far. */
...@@ -2967,10 +2958,11 @@ void clusterSendPing(clusterLink *link, int type) { ...@@ -2967,10 +2958,11 @@ void clusterSendPing(clusterLink *link, int type) {
} }
/* Do not add a node we already have. */ /* Do not add a node we already have. */
if (clusterNodeIsInGossipSection(hdr,gossipcount,this)) continue; if (this->last_in_ping_gossip == cluster_pings_sent) continue;
/* Add it */ /* Add it */
clusterSetGossipEntry(hdr,gossipcount,this); clusterSetGossipEntry(hdr,gossipcount,this);
this->last_in_ping_gossip = cluster_pings_sent;
freshnodes--; freshnodes--;
gossipcount++; gossipcount++;
} }
...@@ -2987,7 +2979,6 @@ void clusterSendPing(clusterLink *link, int type) { ...@@ -2987,7 +2979,6 @@ void clusterSendPing(clusterLink *link, int type) {
if (node->flags & CLUSTER_NODE_NOADDR) continue; if (node->flags & CLUSTER_NODE_NOADDR) continue;
if (!(node->flags & CLUSTER_NODE_PFAIL)) continue; if (!(node->flags & CLUSTER_NODE_PFAIL)) continue;
clusterSetGossipEntry(hdr,gossipcount,node); clusterSetGossipEntry(hdr,gossipcount,node);
freshnodes--;
gossipcount++; gossipcount++;
/* We take the count of the slots we allocated, since the /* We take the count of the slots we allocated, since the
* PFAIL stats may not match perfectly with the current number * PFAIL stats may not match perfectly with the current number
......
...@@ -127,6 +127,7 @@ typedef struct clusterNode { ...@@ -127,6 +127,7 @@ typedef struct clusterNode {
may be NULL even if the node is a slave may be NULL even if the node is a slave
if we don't have the master node in our if we don't have the master node in our
tables. */ tables. */
unsigned long long last_in_ping_gossip; /* The number of the last carried in the ping gossip section */
mstime_t ping_sent; /* Unix time we sent latest ping */ mstime_t ping_sent; /* Unix time we sent latest ping */
mstime_t pong_received; /* Unix time we received the pong */ mstime_t pong_received; /* Unix time we received the pong */
mstime_t data_received; /* Unix time we received any data */ mstime_t data_received; /* Unix time we received any data */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment