summaryrefslogtreecommitdiff
path: root/src/cluster.c
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2021-02-01 20:11:42 +0200
committerGitHub <noreply@github.com>2021-02-01 20:11:42 +0200
commit2dba1e391d3772a8da182d95bde050ffa9d01e4d (patch)
tree3664bcd3ede605643a18668624f41c846b5e43ab /src/cluster.c
parentec2d180739aa3877a45ec54438c68a7659be5159 (diff)
parent95338f9cc41fdfd050f122789187db75fda1fe3c (diff)
downloadredis-2dba1e391d3772a8da182d95bde050ffa9d01e4d.tar.gz
Merge 6.2 RC36.2-rc3
Diffstat (limited to 'src/cluster.c')
-rw-r--r--src/cluster.c94
1 files changed, 72 insertions, 22 deletions
diff --git a/src/cluster.c b/src/cluster.c
index 78c36e8d1..97a25b0b3 100644
--- a/src/cluster.c
+++ b/src/cluster.c
@@ -398,7 +398,7 @@ int clusterLockConfig(char *filename) {
/* To lock it, we need to open the file in a way it is created if
* it does not exist, otherwise there is a race condition with other
* processes. */
- int fd = open(filename,O_WRONLY|O_CREAT,0644);
+ int fd = open(filename,O_WRONLY|O_CREAT|O_CLOEXEC,0644);
if (fd == -1) {
serverLog(LL_WARNING,
"Can't open %s in order to acquire a lock: %s",
@@ -509,8 +509,7 @@ void clusterInit(void) {
serverLog(LL_WARNING, "Redis port number too high. "
"Cluster communication port is 10,000 port "
"numbers higher than your Redis port. "
- "Your Redis port number must be "
- "lower than 55535.");
+ "Your Redis port number must be 55535 or less.");
exit(1);
}
if (listenToPort(port+CLUSTER_PORT_INCR,
@@ -779,6 +778,7 @@ clusterNode *createClusterNode(char *nodename, int flags) {
node->configEpoch = 0;
node->flags = flags;
memset(node->slots,0,sizeof(node->slots));
+ node->slots_info = NULL;
node->numslots = 0;
node->numslaves = 0;
node->slaves = NULL;
@@ -4144,8 +4144,8 @@ sds clusterGenNodeDescription(clusterNode *node) {
sds ci;
/* Node coordinates */
- ci = sdscatprintf(sdsempty(),"%.40s %s:%d@%d ",
- node->name,
+ ci = sdscatlen(sdsempty(),node->name,CLUSTER_NAMELEN);
+ ci = sdscatfmt(ci," %s:%i@%i ",
node->ip,
node->port,
node->cport);
@@ -4154,40 +4154,46 @@ sds clusterGenNodeDescription(clusterNode *node) {
ci = representClusterNodeFlags(ci, node->flags);
/* Slave of... or just "-" */
+ ci = sdscatlen(ci," ",1);
if (node->slaveof)
- ci = sdscatprintf(ci," %.40s ",node->slaveof->name);
+ ci = sdscatlen(ci,node->slaveof->name,CLUSTER_NAMELEN);
else
- ci = sdscatlen(ci," - ",3);
+ ci = sdscatlen(ci,"-",1);
unsigned long long nodeEpoch = node->configEpoch;
if (nodeIsSlave(node) && node->slaveof) {
nodeEpoch = node->slaveof->configEpoch;
}
/* Latency from the POV of this node, config epoch, link status */
- ci = sdscatprintf(ci,"%lld %lld %llu %s",
+ ci = sdscatfmt(ci," %I %I %U %s",
(long long) node->ping_sent,
(long long) node->pong_received,
nodeEpoch,
(node->link || node->flags & CLUSTER_NODE_MYSELF) ?
"connected" : "disconnected");
- /* Slots served by this instance */
- start = -1;
- for (j = 0; j < CLUSTER_SLOTS; j++) {
- int bit;
+ /* Slots served by this instance. If we already have slots info,
+ * append it diretly, otherwise, generate slots only if it has. */
+ if (node->slots_info) {
+ ci = sdscatsds(ci, node->slots_info);
+ } else if (node->numslots > 0) {
+ start = -1;
+ for (j = 0; j < CLUSTER_SLOTS; j++) {
+ int bit;
- if ((bit = clusterNodeGetSlotBit(node,j)) != 0) {
- if (start == -1) start = j;
- }
- if (start != -1 && (!bit || j == CLUSTER_SLOTS-1)) {
- if (bit && j == CLUSTER_SLOTS-1) j++;
+ if ((bit = clusterNodeGetSlotBit(node,j)) != 0) {
+ if (start == -1) start = j;
+ }
+ if (start != -1 && (!bit || j == CLUSTER_SLOTS-1)) {
+ if (bit && j == CLUSTER_SLOTS-1) j++;
- if (start == j-1) {
- ci = sdscatprintf(ci," %d",start);
- } else {
- ci = sdscatprintf(ci," %d-%d",start,j-1);
+ if (start == j-1) {
+ ci = sdscatfmt(ci," %i",start);
+ } else {
+ ci = sdscatfmt(ci," %i-%i",start,j-1);
+ }
+ start = -1;
}
- start = -1;
}
}
@@ -4208,6 +4214,41 @@ sds clusterGenNodeDescription(clusterNode *node) {
return ci;
}
+/* Generate the slot topology for all nodes and store the string representation
+ * in the slots_info struct on the node. This is used to improve the efficiency
+ * of clusterGenNodesDescription() because it removes looping of the slot space
+ * for generating the slot info for each node individually. */
+void clusterGenNodesSlotsInfo(int filter) {
+ clusterNode *n = NULL;
+ int start = -1;
+
+ for (int i = 0; i <= CLUSTER_SLOTS; i++) {
+ /* Find start node and slot id. */
+ if (n == NULL) {
+ if (i == CLUSTER_SLOTS) break;
+ n = server.cluster->slots[i];
+ start = i;
+ continue;
+ }
+
+ /* Generate slots info when occur different node with start
+ * or end of slot. */
+ if (i == CLUSTER_SLOTS || n != server.cluster->slots[i]) {
+ if (!(n->flags & filter)) {
+ if (n->slots_info == NULL) n->slots_info = sdsempty();
+ if (start == i-1) {
+ n->slots_info = sdscatfmt(n->slots_info," %i",start);
+ } else {
+ n->slots_info = sdscatfmt(n->slots_info," %i-%i",start,i-1);
+ }
+ }
+ if (i == CLUSTER_SLOTS) break;
+ n = server.cluster->slots[i];
+ start = i;
+ }
+ }
+}
+
/* Generate a csv-alike representation of the nodes we are aware of,
* including the "myself" node, and return an SDS string containing the
* representation (it is up to the caller to free it).
@@ -4225,6 +4266,9 @@ sds clusterGenNodesDescription(int filter) {
dictIterator *di;
dictEntry *de;
+ /* Generate all nodes slots info firstly. */
+ clusterGenNodesSlotsInfo(filter);
+
di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de);
@@ -4234,6 +4278,12 @@ sds clusterGenNodesDescription(int filter) {
ci = sdscatsds(ci,ni);
sdsfree(ni);
ci = sdscatlen(ci,"\n",1);
+
+ /* Release slots info. */
+ if (node->slots_info) {
+ sdsfree(node->slots_info);
+ node->slots_info = NULL;
+ }
}
dictReleaseIterator(di);
return ci;