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

Optimize the performance of clusterSendPing by improving speed of checking for duplicate items in gossip.
This commit is contained in:
judeng 2022-06-21 12:02:22 +08:00 committed by GitHub
parent 99a425d0f3
commit ff6419658b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 6 additions and 14 deletions

View File

@ -964,6 +964,7 @@ clusterNode *createClusterNode(char *nodename, int flags) {
node->numslaves = 0;
node->slaves = NULL;
node->slaveof = NULL;
node->last_in_ping_gossip = 0;
node->ping_sent = node->pong_received = 0;
node->data_received = 0;
node->fail_time = 0;
@ -2847,18 +2848,6 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) {
* 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'
* to the info of the specified node 'n'. */
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
* gossip information. */
void clusterSendPing(clusterLink *link, int type) {
static unsigned long long cluster_pings_sent = 0;
cluster_pings_sent++;
unsigned char *buf;
clusterMsg *hdr;
int gossipcount = 0; /* Number of gossip sections added so far. */
@ -2967,10 +2958,11 @@ void clusterSendPing(clusterLink *link, int type) {
}
/* 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 */
clusterSetGossipEntry(hdr,gossipcount,this);
this->last_in_ping_gossip = cluster_pings_sent;
freshnodes--;
gossipcount++;
}
@ -2987,7 +2979,6 @@ void clusterSendPing(clusterLink *link, int type) {
if (node->flags & CLUSTER_NODE_NOADDR) continue;
if (!(node->flags & CLUSTER_NODE_PFAIL)) continue;
clusterSetGossipEntry(hdr,gossipcount,node);
freshnodes--;
gossipcount++;
/* We take the count of the slots we allocated, since the
* PFAIL stats may not match perfectly with the current number

View File

@ -127,6 +127,7 @@ typedef struct clusterNode {
may be NULL even if the node is a slave
if we don't have the master node in our
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 pong_received; /* Unix time we received the pong */
mstime_t data_received; /* Unix time we received any data */