1 /* Redis Cluster implementation. 2 * 3 * Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * * Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * * Neither the name of Redis nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without 16 * specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "redis.h" 32 #include "endianconv.h" 33 34 #include <arpa/inet.h> 35 #include <fcntl.h> 36 #include <unistd.h> 37 #include <sys/socket.h> 38 39 void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask); 40 void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask); 41 void clusterSendPing(clusterLink *link, int type); 42 void clusterSendFail(char *nodename); 43 void clusterSendFailoverAuthIfNeeded(clusterNode *sender); 44 void clusterUpdateState(void); 45 int clusterNodeGetSlotBit(clusterNode *n, int slot); 46 sds clusterGenNodesDescription(void); 47 clusterNode *clusterLookupNode(char *name); 48 int clusterNodeAddSlave(clusterNode *master, clusterNode *slave); 49 int clusterAddSlot(clusterNode *n, int slot); 50 int clusterDelSlot(int slot); 51 int clusterDelNodeSlots(clusterNode *node); 52 int clusterNodeSetSlotBit(clusterNode *n, int slot); 53 void clusterSetMaster(clusterNode *n); 54 int bitmapTestBit(unsigned char *bitmap, int pos); 55 56 /* ----------------------------------------------------------------------------- 57 * Initialization 58 * -------------------------------------------------------------------------- */ 59 60 int clusterLoadConfig(char *filename) { 61 FILE *fp = fopen(filename,"r"); 62 char *line; 63 int maxline, j; 64 65 if (fp == NULL) return REDIS_ERR; 66 67 /* Parse the file. Note that single liens of the cluster config file can 68 * be really long as they include all the hash slots of the node. 69 * This means in the worst possible case, half of the Redis slots will be 70 * present in a single line, possibly in importing or migrating state, so 71 * together with the node ID of the sender/receiver. 72 * 73 * To simplify we allocate 1024+REDIS_CLUSTER_SLOTS*128 bytes per line. */ 74 maxline = 1024+REDIS_CLUSTER_SLOTS*128; 75 line = zmalloc(maxline); 76 while(fgets(line,maxline,fp) != NULL) { 77 int argc; 78 sds *argv = sdssplitargs(line,&argc); 79 if (argv == NULL) goto fmterr; 80 81 clusterNode *n, *master; 82 char *p, *s; 83 84 /* Create this node if it does not exist */ 85 n = clusterLookupNode(argv[0]); 86 if (!n) { 87 n = createClusterNode(argv[0],0); 88 clusterAddNode(n); 89 } 90 /* Address and port */ 91 if ((p = strchr(argv[1],':')) == NULL) goto fmterr; 92 *p = '\0'; 93 memcpy(n->ip,argv[1],strlen(argv[1])+1); 94 n->port = atoi(p+1); 95 96 /* Parse flags */ 97 p = s = argv[2]; 98 while(p) { 99 p = strchr(s,','); 100 if (p) *p = '\0'; 101 if (!strcasecmp(s,"myself")) { 102 redisAssert(server.cluster->myself == NULL); 103 server.cluster->myself = n; 104 n->flags |= REDIS_NODE_MYSELF; 105 } else if (!strcasecmp(s,"master")) { 106 n->flags |= REDIS_NODE_MASTER; 107 } else if (!strcasecmp(s,"slave")) { 108 n->flags |= REDIS_NODE_SLAVE; 109 } else if (!strcasecmp(s,"fail?")) { 110 n->flags |= REDIS_NODE_PFAIL; 111 } else if (!strcasecmp(s,"fail")) { 112 n->flags |= REDIS_NODE_FAIL; 113 n->fail_time = time(NULL); 114 } else if (!strcasecmp(s,"handshake")) { 115 n->flags |= REDIS_NODE_HANDSHAKE; 116 } else if (!strcasecmp(s,"noaddr")) { 117 n->flags |= REDIS_NODE_NOADDR; 118 } else if (!strcasecmp(s,"promoted")) { 119 n->flags |= REDIS_NODE_PROMOTED; 120 } else if (!strcasecmp(s,"noflags")) { 121 /* nothing to do */ 122 } else { 123 redisPanic("Unknown flag in redis cluster config file"); 124 } 125 if (p) s = p+1; 126 } 127 128 /* Get master if any. Set the master and populate master's 129 * slave list. */ 130 if (argv[3][0] != '-') { 131 master = clusterLookupNode(argv[3]); 132 if (!master) { 133 master = createClusterNode(argv[3],0); 134 clusterAddNode(master); 135 } 136 n->slaveof = master; 137 clusterNodeAddSlave(master,n); 138 } 139 140 /* Set ping sent / pong received timestamps */ 141 if (atoi(argv[4])) n->ping_sent = time(NULL); 142 if (atoi(argv[5])) n->pong_received = time(NULL); 143 144 /* Populate hash slots served by this instance. */ 145 for (j = 7; j < argc; j++) { 146 int start, stop; 147 148 if (argv[j][0] == '[') { 149 /* Here we handle migrating / importing slots */ 150 int slot; 151 char direction; 152 clusterNode *cn; 153 154 p = strchr(argv[j],'-'); 155 redisAssert(p != NULL); 156 *p = '\0'; 157 direction = p[1]; /* Either '>' or '<' */ 158 slot = atoi(argv[j]+1); 159 p += 3; 160 cn = clusterLookupNode(p); 161 if (!cn) { 162 cn = createClusterNode(p,0); 163 clusterAddNode(cn); 164 } 165 if (direction == '>') { 166 server.cluster->migrating_slots_to[slot] = cn; 167 } else { 168 server.cluster->importing_slots_from[slot] = cn; 169 } 170 continue; 171 } else if ((p = strchr(argv[j],'-')) != NULL) { 172 *p = '\0'; 173 start = atoi(argv[j]); 174 stop = atoi(p+1); 175 } else { 176 start = stop = atoi(argv[j]); 177 } 178 while(start <= stop) clusterAddSlot(n, start++); 179 } 180 181 sdsfreesplitres(argv,argc); 182 } 183 zfree(line); 184 fclose(fp); 185 186 /* Config sanity check */ 187 redisAssert(server.cluster->myself != NULL); 188 redisLog(REDIS_NOTICE,"Node configuration loaded, I'm %.40s", 189 server.cluster->myself->name); 190 clusterUpdateState(); 191 return REDIS_OK; 192 193 fmterr: 194 redisLog(REDIS_WARNING,"Unrecoverable error: corrupted cluster config file."); 195 fclose(fp); 196 exit(1); 197 } 198 199 /* Cluster node configuration is exactly the same as CLUSTER NODES output. 200 * 201 * This function writes the node config and returns 0, on error -1 202 * is returned. */ 203 int clusterSaveConfig(void) { 204 sds ci = clusterGenNodesDescription(); 205 int fd; 206 207 if ((fd = open(server.cluster_configfile,O_WRONLY|O_CREAT|O_TRUNC,0644)) 208 == -1) goto err; 209 if (write(fd,ci,sdslen(ci)) != (ssize_t)sdslen(ci)) goto err; 210 close(fd); 211 sdsfree(ci); 212 return 0; 213 214 err: 215 sdsfree(ci); 216 return -1; 217 } 218 219 void clusterSaveConfigOrDie(void) { 220 if (clusterSaveConfig() == -1) { 221 redisLog(REDIS_WARNING,"Fatal: can't update cluster config file."); 222 exit(1); 223 } 224 } 225 226 void clusterInit(void) { 227 int saveconf = 0; 228 229 server.cluster = zmalloc(sizeof(clusterState)); 230 server.cluster->myself = NULL; 231 server.cluster->state = REDIS_CLUSTER_FAIL; 232 server.cluster->size = 1; 233 server.cluster->nodes = dictCreate(&clusterNodesDictType,NULL); 234 server.cluster->failover_auth_time = 0; 235 server.cluster->failover_auth_count = 0; 236 memset(server.cluster->migrating_slots_to,0, 237 sizeof(server.cluster->migrating_slots_to)); 238 memset(server.cluster->importing_slots_from,0, 239 sizeof(server.cluster->importing_slots_from)); 240 memset(server.cluster->slots,0, 241 sizeof(server.cluster->slots)); 242 if (clusterLoadConfig(server.cluster_configfile) == REDIS_ERR) { 243 /* No configuration found. We will just use the random name provided 244 * by the createClusterNode() function. */ 245 server.cluster->myself = 246 createClusterNode(NULL,REDIS_NODE_MYSELF|REDIS_NODE_MASTER); 247 redisLog(REDIS_NOTICE,"No cluster configuration found, I'm %.40s", 248 server.cluster->myself->name); 249 clusterAddNode(server.cluster->myself); 250 saveconf = 1; 251 } 252 if (saveconf) clusterSaveConfigOrDie(); 253 /* We need a listening TCP port for our cluster messaging needs */ 254 server.cfd = anetTcpServer(server.neterr, 255 server.port+REDIS_CLUSTER_PORT_INCR, server.bindaddr); 256 if (server.cfd == -1) { 257 redisLog(REDIS_WARNING, "Opening cluster TCP port: %s", server.neterr); 258 exit(1); 259 } 260 if (aeCreateFileEvent(server.el, server.cfd, AE_READABLE, 261 clusterAcceptHandler, NULL) == AE_ERR) redisPanic("Unrecoverable error creating Redis Cluster file event."); 262 server.cluster->slots_to_keys = zslCreate(); 263 } 264 265 /* ----------------------------------------------------------------------------- 266 * CLUSTER communication link 267 * -------------------------------------------------------------------------- */ 268 269 clusterLink *createClusterLink(clusterNode *node) { 270 clusterLink *link = zmalloc(sizeof(*link)); 271 link->ctime = time(NULL); 272 link->sndbuf = sdsempty(); 273 link->rcvbuf = sdsempty(); 274 link->node = node; 275 link->fd = -1; 276 return link; 277 } 278 279 /* Free a cluster link, but does not free the associated node of course. 280 * This function will just make sure that the original node associated 281 * with this link will have the 'link' field set to NULL. */ 282 void freeClusterLink(clusterLink *link) { 283 if (link->fd != -1) { 284 aeDeleteFileEvent(server.el, link->fd, AE_WRITABLE); 285 aeDeleteFileEvent(server.el, link->fd, AE_READABLE); 286 } 287 sdsfree(link->sndbuf); 288 sdsfree(link->rcvbuf); 289 if (link->node) 290 link->node->link = NULL; 291 close(link->fd); 292 zfree(link); 293 } 294 295 void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) { 296 int cport, cfd; 297 char cip[128]; 298 clusterLink *link; 299 REDIS_NOTUSED(el); 300 REDIS_NOTUSED(mask); 301 REDIS_NOTUSED(privdata); 302 303 cfd = anetTcpAccept(server.neterr, fd, cip, &cport); 304 if (cfd == AE_ERR) { 305 redisLog(REDIS_VERBOSE,"Accepting cluster node: %s", server.neterr); 306 return; 307 } 308 redisLog(REDIS_VERBOSE,"Accepted cluster node %s:%d", cip, cport); 309 /* We need to create a temporary node in order to read the incoming 310 * packet in a valid contest. This node will be released once we 311 * read the packet and reply. */ 312 link = createClusterLink(NULL); 313 link->fd = cfd; 314 aeCreateFileEvent(server.el,cfd,AE_READABLE,clusterReadHandler,link); 315 } 316 317 /* ----------------------------------------------------------------------------- 318 * Key space handling 319 * -------------------------------------------------------------------------- */ 320 321 /* We have 16384 hash slots. The hash slot of a given key is obtained 322 * as the least significant 14 bits of the crc16 of the key. */ 323 unsigned int keyHashSlot(char *key, int keylen) { 324 return crc16(key,keylen) & 0x3FFF; 325 } 326 327 /* ----------------------------------------------------------------------------- 328 * CLUSTER node API 329 * -------------------------------------------------------------------------- */ 330 331 /* Create a new cluster node, with the specified flags. 332 * If "nodename" is NULL this is considered a first handshake and a random 333 * node name is assigned to this node (it will be fixed later when we'll 334 * receive the first pong). 335 * 336 * The node is created and returned to the user, but it is not automatically 337 * added to the nodes hash table. */ 338 clusterNode *createClusterNode(char *nodename, int flags) { 339 clusterNode *node = zmalloc(sizeof(*node)); 340 341 if (nodename) 342 memcpy(node->name, nodename, REDIS_CLUSTER_NAMELEN); 343 else 344 getRandomHexChars(node->name, REDIS_CLUSTER_NAMELEN); 345 node->flags = flags; 346 memset(node->slots,0,sizeof(node->slots)); 347 node->numslots = 0; 348 node->numslaves = 0; 349 node->slaves = NULL; 350 node->slaveof = NULL; 351 node->ping_sent = node->pong_received = 0; 352 node->fail_time = 0; 353 node->link = NULL; 354 memset(node->ip,0,sizeof(node->ip)); 355 node->port = 0; 356 node->fail_reports = listCreate(); 357 listSetFreeMethod(node->fail_reports,zfree); 358 return node; 359 } 360 361 /* This function is called every time we get a failure report from a node. 362 * The side effect is to populate the fail_reports list (or to update 363 * the timestamp of an existing report). 364 * 365 * 'failing' is the node that is in failure state according to the 366 * 'sender' node. 367 * 368 * The function returns 0 if it just updates a timestamp of an existing 369 * failure report from the same sender. 1 is returned if a new failure 370 * report is created. */ 371 int clusterNodeAddFailureReport(clusterNode *failing, clusterNode *sender) { 372 list *l = failing->fail_reports; 373 listNode *ln; 374 listIter li; 375 clusterNodeFailReport *fr; 376 377 /* If a failure report from the same sender already exists, just update 378 * the timestamp. */ 379 listRewind(l,&li); 380 while ((ln = listNext(&li)) != NULL) { 381 fr = ln->value; 382 if (fr->node == sender) { 383 fr->time = time(NULL); 384 return 0; 385 } 386 } 387 388 /* Otherwise create a new report. */ 389 fr = zmalloc(sizeof(*fr)); 390 fr->node = sender; 391 fr->time = time(NULL); 392 listAddNodeTail(l,fr); 393 return 1; 394 } 395 396 /* Remove failure reports that are too old, where too old means reasonably 397 * older than the global node timeout. Note that anyway for a node to be 398 * flagged as FAIL we need to have a local PFAIL state that is at least 399 * older than the global node timeout, so we don't just trust the number 400 * of failure reports from other nodes. */ 401 void clusterNodeCleanupFailureReports(clusterNode *node) { 402 list *l = node->fail_reports; 403 listNode *ln; 404 listIter li; 405 clusterNodeFailReport *fr; 406 time_t maxtime = server.cluster_node_timeout * 407 REDIS_CLUSTER_FAIL_REPORT_VALIDITY_MULT; 408 time_t now = time(NULL); 409 410 listRewind(l,&li); 411 while ((ln = listNext(&li)) != NULL) { 412 fr = ln->value; 413 if (now - fr->time > maxtime) listDelNode(l,ln); 414 } 415 } 416 417 /* Remove the failing report for 'node' if it was previously considered 418 * failing by 'sender'. This function is called when a node informs us via 419 * gossip that a node is OK from its point of view (no FAIL or PFAIL flags). 420 * 421 * Note that this function is called relatively often as it gets called even 422 * when there are no nodes failing, and is O(N), however when the cluster is 423 * fine the failure reports list is empty so the function runs in constant 424 * time. 425 * 426 * The function returns 1 if the failure report was found and removed. 427 * Otherwise 0 is returned. */ 428 int clusterNodeDelFailureReport(clusterNode *node, clusterNode *sender) { 429 list *l = node->fail_reports; 430 listNode *ln; 431 listIter li; 432 clusterNodeFailReport *fr; 433 434 /* Search for a failure report from this sender. */ 435 listRewind(l,&li); 436 while ((ln = listNext(&li)) != NULL) { 437 fr = ln->value; 438 if (fr->node == sender) break; 439 } 440 if (!ln) return 0; /* No failure report from this sender. */ 441 442 /* Remove the failure report. */ 443 listDelNode(l,ln); 444 clusterNodeCleanupFailureReports(node); 445 return 1; 446 } 447 448 /* Return the number of external nodes that believe 'node' is failing, 449 * not including this node, that may have a PFAIL or FAIL state for this 450 * node as well. */ 451 int clusterNodeFailureReportsCount(clusterNode *node) { 452 clusterNodeCleanupFailureReports(node); 453 return listLength(node->fail_reports); 454 } 455 456 int clusterNodeRemoveSlave(clusterNode *master, clusterNode *slave) { 457 int j; 458 459 for (j = 0; j < master->numslaves; j++) { 460 if (master->slaves[j] == slave) { 461 memmove(master->slaves+j,master->slaves+(j+1), 462 (master->numslaves-1)-j); 463 master->numslaves--; 464 return REDIS_OK; 465 } 466 } 467 return REDIS_ERR; 468 } 469 470 int clusterNodeAddSlave(clusterNode *master, clusterNode *slave) { 471 int j; 472 473 /* If it's already a slave, don't add it again. */ 474 for (j = 0; j < master->numslaves; j++) 475 if (master->slaves[j] == slave) return REDIS_ERR; 476 master->slaves = zrealloc(master->slaves, 477 sizeof(clusterNode*)*(master->numslaves+1)); 478 master->slaves[master->numslaves] = slave; 479 master->numslaves++; 480 return REDIS_OK; 481 } 482 483 void clusterNodeResetSlaves(clusterNode *n) { 484 zfree(n->slaves); 485 n->numslaves = 0; 486 } 487 488 void freeClusterNode(clusterNode *n) { 489 sds nodename; 490 491 nodename = sdsnewlen(n->name, REDIS_CLUSTER_NAMELEN); 492 redisAssert(dictDelete(server.cluster->nodes,nodename) == DICT_OK); 493 sdsfree(nodename); 494 if (n->slaveof) clusterNodeRemoveSlave(n->slaveof, n); 495 if (n->link) freeClusterLink(n->link); 496 listRelease(n->fail_reports); 497 zfree(n); 498 } 499 500 /* Add a node to the nodes hash table */ 501 int clusterAddNode(clusterNode *node) { 502 int retval; 503 504 retval = dictAdd(server.cluster->nodes, 505 sdsnewlen(node->name,REDIS_CLUSTER_NAMELEN), node); 506 return (retval == DICT_OK) ? REDIS_OK : REDIS_ERR; 507 } 508 509 /* Remove a node from the cluster: 510 * 1) Mark all the nodes handled by it as unassigned. 511 * 2) Remove all the failure reports sent by this node. 512 * 3) Free the node, that will in turn remove it from the hash table 513 * and from the list of slaves of its master, if it is a slave node. 514 */ 515 void clusterDelNode(clusterNode *delnode) { 516 int j; 517 dictIterator *di; 518 dictEntry *de; 519 520 /* 1) Mark slots as unassigned. */ 521 for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) { 522 if (server.cluster->importing_slots_from[j] == delnode) 523 server.cluster->importing_slots_from[j] = NULL; 524 if (server.cluster->migrating_slots_to[j] == delnode) 525 server.cluster->migrating_slots_to[j] = NULL; 526 if (server.cluster->slots[j] == delnode) 527 clusterDelSlot(j); 528 } 529 530 /* 2) Remove failure reports. */ 531 di = dictGetIterator(server.cluster->nodes); 532 while((de = dictNext(di)) != NULL) { 533 clusterNode *node = dictGetVal(de); 534 535 if (node == delnode) continue; 536 clusterNodeDelFailureReport(node,delnode); 537 } 538 dictReleaseIterator(di); 539 540 /* 3) Free the node, unlinking it from the cluster. */ 541 freeClusterNode(delnode); 542 } 543 544 /* Node lookup by name */ 545 clusterNode *clusterLookupNode(char *name) { 546 sds s = sdsnewlen(name, REDIS_CLUSTER_NAMELEN); 547 struct dictEntry *de; 548 549 de = dictFind(server.cluster->nodes,s); 550 sdsfree(s); 551 if (de == NULL) return NULL; 552 return dictGetVal(de); 553 } 554 555 /* This is only used after the handshake. When we connect a given IP/PORT 556 * as a result of CLUSTER MEET we don't have the node name yet, so we 557 * pick a random one, and will fix it when we receive the PONG request using 558 * this function. */ 559 void clusterRenameNode(clusterNode *node, char *newname) { 560 int retval; 561 sds s = sdsnewlen(node->name, REDIS_CLUSTER_NAMELEN); 562 563 redisLog(REDIS_DEBUG,"Renaming node %.40s into %.40s", 564 node->name, newname); 565 retval = dictDelete(server.cluster->nodes, s); 566 sdsfree(s); 567 redisAssert(retval == DICT_OK); 568 memcpy(node->name, newname, REDIS_CLUSTER_NAMELEN); 569 clusterAddNode(node); 570 } 571 572 /* ----------------------------------------------------------------------------- 573 * CLUSTER messages exchange - PING/PONG and gossip 574 * -------------------------------------------------------------------------- */ 575 576 /* This function checks if a given node should be marked as FAIL. 577 * It happens if the following conditions are met: 578 * 579 * 1) We are a master node. Only master nodes can mark a node as failing. 580 * 2) We received enough failure reports from other nodes via gossip. 581 * Enough means that the majority of the masters believe the node is 582 * down. 583 * 3) We believe this node is in PFAIL state. 584 * 585 * If a failure is detected we also inform the whole cluster about this 586 * event trying to force every other node to set the FAIL flag for the node. 587 */ 588 void markNodeAsFailingIfNeeded(clusterNode *node) { 589 int failures; 590 int needed_quorum = (server.cluster->size / 2) + 1; 591 592 if (!(server.cluster->myself->flags & REDIS_NODE_MASTER)) return; 593 if (!(node->flags & REDIS_NODE_PFAIL)) return; /* We can reach it. */ 594 if (node->flags & REDIS_NODE_FAIL) return; /* Already FAILing. */ 595 596 failures = 1 + clusterNodeFailureReportsCount(node); /* +1 is for myself. */ 597 if (failures < needed_quorum) return; 598 599 redisLog(REDIS_NOTICE, 600 "Marking node %.40s as failing (quorum reached).", node->name); 601 602 /* Mark the node as failing. */ 603 node->flags &= ~REDIS_NODE_PFAIL; 604 node->flags |= REDIS_NODE_FAIL; 605 node->fail_time = time(NULL); 606 607 /* Broadcast the failing node name to everybody */ 608 clusterSendFail(node->name); 609 clusterUpdateState(); 610 clusterSaveConfigOrDie(); 611 } 612 613 /* This function is called only if a node is marked as FAIL, but we are able 614 * to reach it again. It checks if there are the conditions to undo the FAIL 615 * state. */ 616 void clearNodeFailureIfNeeded(clusterNode *node) { 617 int changes = 0; 618 time_t now = time(NULL); 619 620 redisAssert(node->flags & REDIS_NODE_FAIL); 621 622 /* For slaves we always clear the FAIL flag if we can contact the 623 * node again. */ 624 if (node->flags & REDIS_NODE_SLAVE) { 625 redisLog(REDIS_NOTICE, 626 "Clear FAIL state for node %.40s: slave is already reachable.", 627 node->name); 628 node->flags &= ~REDIS_NODE_FAIL; 629 changes++; 630 } 631 632 /* If it is a master and... 633 * 1) The FAIL state is old enough. We use our node timeout multiplicator 634 * plus some additional fixed time. The additional time is useful when 635 * the node timeout is extremely short and the reaction time of 636 * the cluster may be longer, so wait at least a few seconds always. 637 * 2) It is yet serving slots from our point of view (not failed over). 638 * Apparently no one is going to fix these slots, clear the FAIL flag. */ 639 if (node->flags & REDIS_NODE_MASTER && 640 node->numslots > 0 && 641 (now - node->fail_time) > 642 (server.cluster_node_timeout * REDIS_CLUSTER_FAIL_UNDO_TIME_MULT + 643 REDIS_CLUSTER_FAIL_UNDO_TIME_ADD)) 644 { 645 redisLog(REDIS_NOTICE, 646 "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.", 647 node->name); 648 node->flags &= ~REDIS_NODE_FAIL; 649 changes++; 650 } 651 652 /* Update state and save config. */ 653 if (changes) { 654 clusterUpdateState(); 655 clusterSaveConfigOrDie(); 656 } 657 } 658 659 /* Process the gossip section of PING or PONG packets. 660 * Note that this function assumes that the packet is already sanity-checked 661 * by the caller, not in the content of the gossip section, but in the 662 * length. */ 663 void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { 664 uint16_t count = ntohs(hdr->count); 665 clusterMsgDataGossip *g = (clusterMsgDataGossip*) hdr->data.ping.gossip; 666 clusterNode *sender = link->node ? link->node : clusterLookupNode(hdr->sender); 667 668 while(count--) { 669 sds ci = sdsempty(); 670 uint16_t flags = ntohs(g->flags); 671 clusterNode *node; 672 673 if (flags == 0) ci = sdscat(ci,"noflags,"); 674 if (flags & REDIS_NODE_MYSELF) ci = sdscat(ci,"myself,"); 675 if (flags & REDIS_NODE_MASTER) ci = sdscat(ci,"master,"); 676 if (flags & REDIS_NODE_SLAVE) ci = sdscat(ci,"slave,"); 677 if (flags & REDIS_NODE_PFAIL) ci = sdscat(ci,"fail?,"); 678 if (flags & REDIS_NODE_FAIL) ci = sdscat(ci,"fail,"); 679 if (flags & REDIS_NODE_HANDSHAKE) ci = sdscat(ci,"handshake,"); 680 if (flags & REDIS_NODE_NOADDR) ci = sdscat(ci,"noaddr,"); 681 if (flags & REDIS_NODE_PROMOTED) ci = sdscat(ci,"promoted,"); 682 if (ci[sdslen(ci)-1] == ',') ci[sdslen(ci)-1] = ' '; 683 684 redisLog(REDIS_DEBUG,"GOSSIP %.40s %s:%d %s", 685 g->nodename, 686 g->ip, 687 ntohs(g->port), 688 ci); 689 sdsfree(ci); 690 691 /* Update our state accordingly to the gossip sections */ 692 node = clusterLookupNode(g->nodename); 693 if (node != NULL) { 694 /* We already know this node. Let's start updating the last 695 * time PONG figure if it is newer than our figure. 696 * Note that it's not a problem if we have a PING already 697 * in progress against this node. */ 698 if (node->pong_received < (signed) ntohl(g->pong_received)) { 699 redisLog(REDIS_DEBUG,"Node pong_received updated by gossip"); 700 node->pong_received = ntohl(g->pong_received); 701 } 702 /* Handle failure reports, only when the sender is a master. */ 703 if (sender && sender->flags & REDIS_NODE_MASTER && 704 node != server.cluster->myself) 705 { 706 if (flags & (REDIS_NODE_FAIL|REDIS_NODE_PFAIL)) { 707 if (clusterNodeAddFailureReport(node,sender)) { 708 redisLog(REDIS_NOTICE, 709 "Node %.40s reported node %.40s as not reachable.", 710 sender->name, node->name); 711 } 712 markNodeAsFailingIfNeeded(node); 713 } else { 714 if (clusterNodeDelFailureReport(node,sender)) { 715 redisLog(REDIS_NOTICE, 716 "Node %.40s reported node %.40s is back online.", 717 sender->name, node->name); 718 } 719 } 720 } 721 } else { 722 /* If it's not in NOADDR state and we don't have it, we 723 * start an handshake process against this IP/PORT pairs. 724 * 725 * Note that we require that the sender of this gossip message 726 * is a well known node in our cluster, otherwise we risk 727 * joining another cluster. */ 728 if (sender && !(flags & REDIS_NODE_NOADDR)) { 729 clusterNode *newnode; 730 731 redisLog(REDIS_DEBUG,"Adding the new node"); 732 newnode = createClusterNode(NULL,REDIS_NODE_HANDSHAKE); 733 memcpy(newnode->ip,g->ip,sizeof(g->ip)); 734 newnode->port = ntohs(g->port); 735 clusterAddNode(newnode); 736 } 737 } 738 739 /* Next node */ 740 g++; 741 } 742 } 743 744 /* IP -> string conversion. 'buf' is supposed to at least be 16 bytes. */ 745 void nodeIp2String(char *buf, clusterLink *link) { 746 struct sockaddr_in sa; 747 socklen_t salen = sizeof(sa); 748 749 if (getpeername(link->fd, (struct sockaddr*) &sa, &salen) == -1) 750 redisPanic("getpeername() failed."); 751 strncpy(buf,inet_ntoa(sa.sin_addr),sizeof(link->node->ip)); 752 } 753 754 755 /* Update the node address to the IP address that can be extracted 756 * from link->fd, and at the specified port. */ 757 void nodeUpdateAddress(clusterNode *node, clusterLink *link, int port) { 758 /* TODO */ 759 } 760 761 /* When this function is called, there is a packet to process starting 762 * at node->rcvbuf. Releasing the buffer is up to the caller, so this 763 * function should just handle the higher level stuff of processing the 764 * packet, modifying the cluster state if needed. 765 * 766 * The function returns 1 if the link is still valid after the packet 767 * was processed, otherwise 0 if the link was freed since the packet 768 * processing lead to some inconsistency error (for instance a PONG 769 * received from the wrong sender ID). */ 770 int clusterProcessPacket(clusterLink *link) { 771 clusterMsg *hdr = (clusterMsg*) link->rcvbuf; 772 uint32_t totlen = ntohl(hdr->totlen); 773 uint16_t type = ntohs(hdr->type); 774 uint16_t flags = ntohs(hdr->flags); 775 clusterNode *sender; 776 777 redisLog(REDIS_DEBUG,"--- Processing packet of type %d, %lu bytes", 778 type, (unsigned long) totlen); 779 780 /* Perform sanity checks */ 781 if (totlen < 8) return 1; 782 if (totlen > sdslen(link->rcvbuf)) return 1; 783 if (type == CLUSTERMSG_TYPE_PING || type == CLUSTERMSG_TYPE_PONG || 784 type == CLUSTERMSG_TYPE_MEET) 785 { 786 uint16_t count = ntohs(hdr->count); 787 uint32_t explen; /* expected length of this packet */ 788 789 explen = sizeof(clusterMsg)-sizeof(union clusterMsgData); 790 explen += (sizeof(clusterMsgDataGossip)*count); 791 if (totlen != explen) return 1; 792 } else if (type == CLUSTERMSG_TYPE_FAIL) { 793 uint32_t explen = sizeof(clusterMsg)-sizeof(union clusterMsgData); 794 795 explen += sizeof(clusterMsgDataFail); 796 if (totlen != explen) return 1; 797 } else if (type == CLUSTERMSG_TYPE_PUBLISH) { 798 uint32_t explen = sizeof(clusterMsg)-sizeof(union clusterMsgData); 799 800 explen += sizeof(clusterMsgDataPublish) + 801 ntohl(hdr->data.publish.msg.channel_len) + 802 ntohl(hdr->data.publish.msg.message_len); 803 if (totlen != explen) return 1; 804 } else if (type == CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST || 805 type == CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK) { 806 uint32_t explen = sizeof(clusterMsg)-sizeof(union clusterMsgData); 807 808 if (totlen != explen) return 1; 809 } 810 811 /* Process packets by type. */ 812 sender = clusterLookupNode(hdr->sender); 813 814 if (type == CLUSTERMSG_TYPE_PING || type == CLUSTERMSG_TYPE_MEET) { 815 int update_config = 0; 816 redisLog(REDIS_DEBUG,"Ping packet received: %p", (void*)link->node); 817 818 /* Add this node if it is new for us and the msg type is MEET. 819 * In this stage we don't try to add the node with the right 820 * flags, slaveof pointer, and so forth, as this details will be 821 * resolved when we'll receive PONGs from the server. */ 822 if (!sender && type == CLUSTERMSG_TYPE_MEET) { 823 clusterNode *node; 824 825 node = createClusterNode(NULL,REDIS_NODE_HANDSHAKE); 826 nodeIp2String(node->ip,link); 827 node->port = ntohs(hdr->port); 828 clusterAddNode(node); 829 update_config = 1; 830 } 831 832 /* Get info from the gossip section */ 833 clusterProcessGossipSection(hdr,link); 834 835 /* Anyway reply with a PONG */ 836 clusterSendPing(link,CLUSTERMSG_TYPE_PONG); 837 838 /* Update config if needed */ 839 if (update_config) clusterSaveConfigOrDie(); 840 } 841 842 /* PING or PONG: process config information. */ 843 if (type == CLUSTERMSG_TYPE_PING || type == CLUSTERMSG_TYPE_PONG) { 844 int update_state = 0; 845 int update_config = 0; 846 847 redisLog(REDIS_DEBUG,"%s packet received: %p", 848 type == CLUSTERMSG_TYPE_PING ? "ping" : "pong", 849 (void*)link->node); 850 if (link->node) { 851 if (link->node->flags & REDIS_NODE_HANDSHAKE) { 852 /* If we already have this node, try to change the 853 * IP/port of the node with the new one. */ 854 if (sender) { 855 redisLog(REDIS_WARNING, 856 "Handshake error: we already know node %.40s, updating the address if needed.", sender->name); 857 nodeUpdateAddress(sender,link,ntohs(hdr->port)); 858 freeClusterNode(link->node); /* will free the link too */ 859 return 0; 860 } 861 862 /* First thing to do is replacing the random name with the 863 * right node name if this was an handshake stage. */ 864 clusterRenameNode(link->node, hdr->sender); 865 redisLog(REDIS_DEBUG,"Handshake with node %.40s completed.", 866 link->node->name); 867 link->node->flags &= ~REDIS_NODE_HANDSHAKE; 868 link->node->flags |= flags&(REDIS_NODE_MASTER|REDIS_NODE_SLAVE); 869 update_config = 1; 870 } else if (memcmp(link->node->name,hdr->sender, 871 REDIS_CLUSTER_NAMELEN) != 0) 872 { 873 /* If the reply has a non matching node ID we 874 * disconnect this node and set it as not having an associated 875 * address. */ 876 redisLog(REDIS_DEBUG,"PONG contains mismatching sender ID"); 877 link->node->flags |= REDIS_NODE_NOADDR; 878 link->node->ip[0] = '\0'; 879 link->node->port = 0; 880 freeClusterLink(link); 881 update_config = 1; 882 /* FIXME: remove this node if we already have it. 883 * 884 * If we already have it but the IP is different, use 885 * the new one if the old node is in FAIL, PFAIL, or NOADDR 886 * status... */ 887 return 0; 888 } 889 } 890 891 /* Update our info about the node */ 892 if (link->node && type == CLUSTERMSG_TYPE_PONG) { 893 link->node->pong_received = time(NULL); 894 link->node->ping_sent = 0; 895 896 /* The PFAIL condition can be reversed without external 897 * help if it is not transitive (that is, if it does not 898 * turn into a FAIL state). 899 * 900 * The FAIL condition is also reversible under specific 901 * conditions detected by clearNodeFailureIfNeeded(). */ 902 if (link->node->flags & REDIS_NODE_PFAIL) { 903 link->node->flags &= ~REDIS_NODE_PFAIL; 904 update_state = 1; 905 } else if (link->node->flags & REDIS_NODE_FAIL) { 906 clearNodeFailureIfNeeded(link->node); 907 } 908 } 909 910 /* Update master/slave state */ 911 if (sender) { 912 if (!memcmp(hdr->slaveof,REDIS_NODE_NULL_NAME, 913 sizeof(hdr->slaveof))) 914 { 915 /* Node is a master. */ 916 if (sender->flags & REDIS_NODE_SLAVE) { 917 /* Slave turned into master! */ 918 clusterNode *oldmaster = sender->slaveof; 919 920 /* Reconfigure node as master. */ 921 if (sender->slaveof) 922 clusterNodeRemoveSlave(sender->slaveof,sender); 923 sender->flags &= ~REDIS_NODE_SLAVE; 924 sender->flags |= REDIS_NODE_MASTER; 925 sender->slaveof = NULL; 926 927 /* If this node used to be our slave, and now has the 928 * PROMOTED flag set. We'll turn ourself into a slave 929 * of the new master. */ 930 if (flags & REDIS_NODE_PROMOTED && 931 oldmaster == server.cluster->myself) 932 { 933 redisLog(REDIS_WARNING,"One of my slaves took my place. Reconfiguring myself as a replica of %.40s", sender->name); 934 clusterDelNodeSlots(server.cluster->myself); 935 clusterSetMaster(sender); 936 } 937 938 /* If we are a slave, and this node used to be a slave 939 * of our master, and now has the PROMOTED flag set, we 940 * need to switch our replication setup over it. */ 941 if (flags & REDIS_NODE_PROMOTED && 942 server.cluster->myself->flags & REDIS_NODE_SLAVE && 943 server.cluster->myself->slaveof == oldmaster) 944 { 945 redisLog(REDIS_WARNING,"One of the slaves failed over my master. Reconfiguring myself as a replica of %.40s", sender->name); 946 clusterDelNodeSlots(server.cluster->myself); 947 clusterSetMaster(sender); 948 } 949 950 /* Update config and state. */ 951 update_state = 1; 952 update_config = 1; 953 } 954 } else { 955 /* Node is a slave. */ 956 clusterNode *master = clusterLookupNode(hdr->slaveof); 957 958 if (sender->flags & REDIS_NODE_MASTER) { 959 /* Master turned into a slave! Reconfigure the node. */ 960 clusterDelNodeSlots(sender); 961 sender->flags &= ~REDIS_NODE_MASTER; 962 sender->flags |= REDIS_NODE_SLAVE; 963 964 /* Remove the list of slaves from the node. */ 965 if (sender->numslaves) clusterNodeResetSlaves(sender); 966 967 /* Update config and state. */ 968 update_state = 1; 969 update_config = 1; 970 } 971 972 /* Master node changed for this slave? */ 973 if (sender->slaveof != master) { 974 if (sender->slaveof) 975 clusterNodeRemoveSlave(sender->slaveof,sender); 976 clusterNodeAddSlave(master,sender); 977 sender->slaveof = master; 978 } 979 } 980 } 981 982 /* Update our info about served slots. 983 * Note: this MUST happen after we update the master/slave state 984 * so that REDIS_NODE_MASTER flag will be set. */ 985 if (sender && sender->flags & REDIS_NODE_MASTER) { 986 int changes, j; 987 988 changes = 989 memcmp(sender->slots,hdr->myslots,sizeof(hdr->myslots)) != 0; 990 if (changes) { 991 for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) { 992 if (bitmapTestBit(hdr->myslots,j)) { 993 /* If this slot was not served, or served by a node 994 * in FAIL state, update the table with the new node 995 * claiming to serve the slot. */ 996 if (server.cluster->slots[j] == sender) continue; 997 if (server.cluster->slots[j] == NULL || 998 server.cluster->slots[j]->flags & REDIS_NODE_FAIL) 999 { 1000 clusterDelSlot(j); 1001 clusterAddSlot(sender,j); 1002 update_state = update_config = 1; 1003 } 1004 } else { 1005 /* This node claims to no longer handling the slot, 1006 * however we don't change our config as this is likely 1007 * happening because a resharding is in progress, and 1008 * it already knows where to redirect clients. */ 1009 } 1010 } 1011 } 1012 } 1013 1014 /* Get info from the gossip section */ 1015 clusterProcessGossipSection(hdr,link); 1016 1017 /* Update the cluster state if needed */ 1018 if (update_state) clusterUpdateState(); 1019 if (update_config) clusterSaveConfigOrDie(); 1020 } else if (type == CLUSTERMSG_TYPE_FAIL && sender) { 1021 clusterNode *failing; 1022 1023 failing = clusterLookupNode(hdr->data.fail.about.nodename); 1024 if (failing && !(failing->flags & (REDIS_NODE_FAIL|REDIS_NODE_MYSELF))) 1025 { 1026 redisLog(REDIS_NOTICE, 1027 "FAIL message received from %.40s about %.40s", 1028 hdr->sender, hdr->data.fail.about.nodename); 1029 failing->flags |= REDIS_NODE_FAIL; 1030 failing->fail_time = time(NULL); 1031 failing->flags &= ~REDIS_NODE_PFAIL; 1032 clusterUpdateState(); 1033 clusterSaveConfigOrDie(); 1034 } 1035 } else if (type == CLUSTERMSG_TYPE_PUBLISH) { 1036 robj *channel, *message; 1037 uint32_t channel_len, message_len; 1038 1039 /* Don't bother creating useless objects if there are no Pub/Sub subscribers. */ 1040 if (dictSize(server.pubsub_channels) || listLength(server.pubsub_patterns)) { 1041 channel_len = ntohl(hdr->data.publish.msg.channel_len); 1042 message_len = ntohl(hdr->data.publish.msg.message_len); 1043 channel = createStringObject( 1044 (char*)hdr->data.publish.msg.bulk_data,channel_len); 1045 message = createStringObject( 1046 (char*)hdr->data.publish.msg.bulk_data+channel_len, message_len); 1047 pubsubPublishMessage(channel,message); 1048 decrRefCount(channel); 1049 decrRefCount(message); 1050 } 1051 } else if (type == CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST) { 1052 if (!sender) return 0; /* We don't know that node. */ 1053 /* If we are not a master, ignore that message at all. */ 1054 if (!(server.cluster->myself->flags & REDIS_NODE_MASTER)) return 0; 1055 clusterSendFailoverAuthIfNeeded(sender); 1056 } else if (type == CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK) { 1057 if (!sender) return 0; /* We don't know that node. */ 1058 /* If this is a master, increment the number of acknowledges 1059 * we received so far. */ 1060 if (sender->flags & REDIS_NODE_MASTER) 1061 server.cluster->failover_auth_count++; 1062 } else { 1063 redisLog(REDIS_WARNING,"Received unknown packet type: %d", type); 1064 } 1065 return 1; 1066 } 1067 1068 /* This function is called when we detect the link with this node is lost. 1069 We set the node as no longer connected. The Cluster Cron will detect 1070 this connection and will try to get it connected again. 1071 1072 Instead if the node is a temporary node used to accept a query, we 1073 completely free the node on error. */ 1074 void handleLinkIOError(clusterLink *link) { 1075 freeClusterLink(link); 1076 } 1077 1078 /* Send data. This is handled using a trivial send buffer that gets 1079 * consumed by write(). We don't try to optimize this for speed too much 1080 * as this is a very low traffic channel. */ 1081 void clusterWriteHandler(aeEventLoop *el, int fd, void *privdata, int mask) { 1082 clusterLink *link = (clusterLink*) privdata; 1083 ssize_t nwritten; 1084 REDIS_NOTUSED(el); 1085 REDIS_NOTUSED(mask); 1086 1087 nwritten = write(fd, link->sndbuf, sdslen(link->sndbuf)); 1088 if (nwritten <= 0) { 1089 redisLog(REDIS_DEBUG,"I/O error writing to node link: %s", 1090 strerror(errno)); 1091 handleLinkIOError(link); 1092 return; 1093 } 1094 link->sndbuf = sdsrange(link->sndbuf,nwritten,-1); 1095 if (sdslen(link->sndbuf) == 0) 1096 aeDeleteFileEvent(server.el, link->fd, AE_WRITABLE); 1097 } 1098 1099 /* Read data. Try to read the first field of the header first to check the 1100 * full length of the packet. When a whole packet is in memory this function 1101 * will call the function to process the packet. And so forth. */ 1102 void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask) { 1103 char buf[4096]; 1104 ssize_t nread; 1105 clusterMsg *hdr; 1106 clusterLink *link = (clusterLink*) privdata; 1107 int readlen, rcvbuflen; 1108 REDIS_NOTUSED(el); 1109 REDIS_NOTUSED(mask); 1110 1111 again: 1112 rcvbuflen = sdslen(link->rcvbuf); 1113 if (rcvbuflen < 4) { 1114 /* First, obtain the first four bytes to get the full message 1115 * length. */ 1116 readlen = 4 - rcvbuflen; 1117 } else { 1118 /* Finally read the full message. */ 1119 hdr = (clusterMsg*) link->rcvbuf; 1120 if (rcvbuflen == 4) { 1121 /* Perform some sanity check on the message length. */ 1122 if (ntohl(hdr->totlen) < CLUSTERMSG_MIN_LEN) { 1123 redisLog(REDIS_WARNING, 1124 "Bad message length received from Cluster bus."); 1125 handleLinkIOError(link); 1126 return; 1127 } 1128 } 1129 readlen = ntohl(hdr->totlen) - rcvbuflen; 1130 } 1131 1132 nread = read(fd,buf,readlen); 1133 if (nread == -1 && errno == EAGAIN) return; /* No more data ready. */ 1134 1135 if (nread <= 0) { 1136 /* I/O error... */ 1137 redisLog(REDIS_DEBUG,"I/O error reading from node link: %s", 1138 (nread == 0) ? "connection closed" : strerror(errno)); 1139 handleLinkIOError(link); 1140 return; 1141 } else { 1142 /* Read data and recast the pointer to the new buffer. */ 1143 link->rcvbuf = sdscatlen(link->rcvbuf,buf,nread); 1144 hdr = (clusterMsg*) link->rcvbuf; 1145 rcvbuflen += nread; 1146 } 1147 1148 /* Total length obtained? read the payload now instead of burning 1149 * cycles waiting for a new event to fire. */ 1150 if (rcvbuflen == 4) goto again; 1151 1152 /* Whole packet in memory? We can process it. */ 1153 if (rcvbuflen == ntohl(hdr->totlen)) { 1154 if (clusterProcessPacket(link)) { 1155 sdsfree(link->rcvbuf); 1156 link->rcvbuf = sdsempty(); 1157 rcvbuflen = 0; /* Useless line of code currently... defensive. */ 1158 } 1159 } 1160 } 1161 1162 /* Put stuff into the send buffer. */ 1163 void clusterSendMessage(clusterLink *link, unsigned char *msg, size_t msglen) { 1164 if (sdslen(link->sndbuf) == 0 && msglen != 0) 1165 aeCreateFileEvent(server.el,link->fd,AE_WRITABLE, 1166 clusterWriteHandler,link); 1167 1168 link->sndbuf = sdscatlen(link->sndbuf, msg, msglen); 1169 } 1170 1171 /* Send a message to all the nodes that are part of the cluster having 1172 * a connected link. */ 1173 void clusterBroadcastMessage(void *buf, size_t len) { 1174 dictIterator *di; 1175 dictEntry *de; 1176 1177 di = dictGetIterator(server.cluster->nodes); 1178 while((de = dictNext(di)) != NULL) { 1179 clusterNode *node = dictGetVal(de); 1180 1181 if (!node->link) continue; 1182 if (node->flags & (REDIS_NODE_MYSELF|REDIS_NODE_HANDSHAKE)) 1183 continue; 1184 clusterSendMessage(node->link,buf,len); 1185 } 1186 dictReleaseIterator(di); 1187 } 1188 1189 /* Build the message header */ 1190 void clusterBuildMessageHdr(clusterMsg *hdr, int type) { 1191 int totlen = 0; 1192 1193 memset(hdr,0,sizeof(*hdr)); 1194 hdr->type = htons(type); 1195 memcpy(hdr->sender,server.cluster->myself->name,REDIS_CLUSTER_NAMELEN); 1196 memcpy(hdr->myslots,server.cluster->myself->slots, 1197 sizeof(hdr->myslots)); 1198 memset(hdr->slaveof,0,REDIS_CLUSTER_NAMELEN); 1199 if (server.cluster->myself->slaveof != NULL) { 1200 memcpy(hdr->slaveof,server.cluster->myself->slaveof->name, 1201 REDIS_CLUSTER_NAMELEN); 1202 } 1203 hdr->port = htons(server.port); 1204 hdr->flags = htons(server.cluster->myself->flags); 1205 hdr->state = server.cluster->state; 1206 1207 if (type == CLUSTERMSG_TYPE_FAIL) { 1208 totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData); 1209 totlen += sizeof(clusterMsgDataFail); 1210 } 1211 hdr->totlen = htonl(totlen); 1212 /* For PING, PONG, and MEET, fixing the totlen field is up to the caller */ 1213 } 1214 1215 /* Send a PING or PONG packet to the specified node, making sure to add enough 1216 * gossip informations. */ 1217 void clusterSendPing(clusterLink *link, int type) { 1218 unsigned char buf[4096]; 1219 clusterMsg *hdr = (clusterMsg*) buf; 1220 int gossipcount = 0, totlen; 1221 /* freshnodes is the number of nodes we can still use to populate the 1222 * gossip section of the ping packet. Basically we start with the nodes 1223 * we have in memory minus two (ourself and the node we are sending the 1224 * message to). Every time we add a node we decrement the counter, so when 1225 * it will drop to <= zero we know there is no more gossip info we can 1226 * send. */ 1227 int freshnodes = dictSize(server.cluster->nodes)-2; 1228 1229 if (link->node && type == CLUSTERMSG_TYPE_PING) 1230 link->node->ping_sent = time(NULL); 1231 clusterBuildMessageHdr(hdr,type); 1232 1233 /* Populate the gossip fields */ 1234 while(freshnodes > 0 && gossipcount < 3) { 1235 struct dictEntry *de = dictGetRandomKey(server.cluster->nodes); 1236 clusterNode *this = dictGetVal(de); 1237 clusterMsgDataGossip *gossip; 1238 int j; 1239 1240 /* In the gossip section don't include: 1241 * 1) Myself. 1242 * 2) Nodes in HANDSHAKE state. 1243 * 3) Nodes with the NOADDR flag set. 1244 * 4) Disconnected nodes if they don't have configured slots. 1245 */ 1246 if (this == server.cluster->myself || 1247 this->flags & (REDIS_NODE_HANDSHAKE|REDIS_NODE_NOADDR) || 1248 (this->link == NULL && this->numslots == 0)) 1249 { 1250 freshnodes--; /* otherwise we may loop forever. */ 1251 continue; 1252 } 1253 1254 /* Check if we already added this node */ 1255 for (j = 0; j < gossipcount; j++) { 1256 if (memcmp(hdr->data.ping.gossip[j].nodename,this->name, 1257 REDIS_CLUSTER_NAMELEN) == 0) break; 1258 } 1259 if (j != gossipcount) continue; 1260 1261 /* Add it */ 1262 freshnodes--; 1263 gossip = &(hdr->data.ping.gossip[gossipcount]); 1264 memcpy(gossip->nodename,this->name,REDIS_CLUSTER_NAMELEN); 1265 gossip->ping_sent = htonl(this->ping_sent); 1266 gossip->pong_received = htonl(this->pong_received); 1267 memcpy(gossip->ip,this->ip,sizeof(this->ip)); 1268 gossip->port = htons(this->port); 1269 gossip->flags = htons(this->flags); 1270 gossipcount++; 1271 } 1272 totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData); 1273 totlen += (sizeof(clusterMsgDataGossip)*gossipcount); 1274 hdr->count = htons(gossipcount); 1275 hdr->totlen = htonl(totlen); 1276 clusterSendMessage(link,buf,totlen); 1277 } 1278 1279 /* Send a PONG packet to every connected node that's not in handshake state. 1280 * 1281 * In Redis Cluster pings are not just used for failure detection, but also 1282 * to carry important configuration informations. So broadcasting a pong is 1283 * useful when something changes in the configuration and we want to make 1284 * the cluster aware ASAP (for instance after a slave promotion). */ 1285 void clusterBroadcastPong(void) { 1286 dictIterator *di; 1287 dictEntry *de; 1288 1289 di = dictGetIterator(server.cluster->nodes); 1290 while((de = dictNext(di)) != NULL) { 1291 clusterNode *node = dictGetVal(de); 1292 1293 if (node->flags & (REDIS_NODE_MYSELF|REDIS_NODE_HANDSHAKE)) continue; 1294 clusterSendPing(node->link,CLUSTERMSG_TYPE_PONG); 1295 } 1296 dictReleaseIterator(di); 1297 } 1298 1299 /* Send a PUBLISH message. 1300 * 1301 * If link is NULL, then the message is broadcasted to the whole cluster. */ 1302 void clusterSendPublish(clusterLink *link, robj *channel, robj *message) { 1303 unsigned char buf[4096], *payload; 1304 clusterMsg *hdr = (clusterMsg*) buf; 1305 uint32_t totlen; 1306 uint32_t channel_len, message_len; 1307 1308 channel = getDecodedObject(channel); 1309 message = getDecodedObject(message); 1310 channel_len = sdslen(channel->ptr); 1311 message_len = sdslen(message->ptr); 1312 1313 clusterBuildMessageHdr(hdr,CLUSTERMSG_TYPE_PUBLISH); 1314 totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData); 1315 totlen += sizeof(clusterMsgDataPublish) + channel_len + message_len; 1316 1317 hdr->data.publish.msg.channel_len = htonl(channel_len); 1318 hdr->data.publish.msg.message_len = htonl(message_len); 1319 hdr->totlen = htonl(totlen); 1320 1321 /* Try to use the local buffer if possible */ 1322 if (totlen < sizeof(buf)) { 1323 payload = buf; 1324 } else { 1325 payload = zmalloc(totlen); 1326 hdr = (clusterMsg*) payload; 1327 memcpy(payload,hdr,sizeof(*hdr)); 1328 } 1329 memcpy(hdr->data.publish.msg.bulk_data,channel->ptr,sdslen(channel->ptr)); 1330 memcpy(hdr->data.publish.msg.bulk_data+sdslen(channel->ptr), 1331 message->ptr,sdslen(message->ptr)); 1332 1333 if (link) 1334 clusterSendMessage(link,payload,totlen); 1335 else 1336 clusterBroadcastMessage(payload,totlen); 1337 1338 decrRefCount(channel); 1339 decrRefCount(message); 1340 if (payload != buf) zfree(payload); 1341 } 1342 1343 /* Send a FAIL message to all the nodes we are able to contact. 1344 * The FAIL message is sent when we detect that a node is failing 1345 * (REDIS_NODE_PFAIL) and we also receive a gossip confirmation of this: 1346 * we switch the node state to REDIS_NODE_FAIL and ask all the other 1347 * nodes to do the same ASAP. */ 1348 void clusterSendFail(char *nodename) { 1349 unsigned char buf[4096]; 1350 clusterMsg *hdr = (clusterMsg*) buf; 1351 1352 clusterBuildMessageHdr(hdr,CLUSTERMSG_TYPE_FAIL); 1353 memcpy(hdr->data.fail.about.nodename,nodename,REDIS_CLUSTER_NAMELEN); 1354 clusterBroadcastMessage(buf,ntohl(hdr->totlen)); 1355 } 1356 1357 /* ----------------------------------------------------------------------------- 1358 * CLUSTER Pub/Sub support 1359 * 1360 * For now we do very little, just propagating PUBLISH messages across the whole 1361 * cluster. In the future we'll try to get smarter and avoiding propagating those 1362 * messages to hosts without receives for a given channel. 1363 * -------------------------------------------------------------------------- */ 1364 void clusterPropagatePublish(robj *channel, robj *message) { 1365 clusterSendPublish(NULL, channel, message); 1366 } 1367 1368 /* ----------------------------------------------------------------------------- 1369 * SLAVE node specific functions 1370 * -------------------------------------------------------------------------- */ 1371 1372 /* This function sends a FAILOVE_AUTH_REQUEST message to every node in order to 1373 * see if there is the quorum for this slave instance to failover its failing 1374 * master. 1375 * 1376 * Note that we send the failover request to everybody, master and slave nodes, 1377 * but only the masters are supposed to reply to our query. */ 1378 void clusterRequestFailoverAuth(void) { 1379 unsigned char buf[4096]; 1380 clusterMsg *hdr = (clusterMsg*) buf; 1381 uint32_t totlen; 1382 1383 clusterBuildMessageHdr(hdr,CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST); 1384 totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData); 1385 hdr->totlen = htonl(totlen); 1386 clusterBroadcastMessage(buf,totlen); 1387 } 1388 1389 /* Send a FAILOVER_AUTH_ACK message to the specified node. */ 1390 void clusterSendFailoverAuth(clusterNode *node) { 1391 unsigned char buf[4096]; 1392 clusterMsg *hdr = (clusterMsg*) buf; 1393 uint32_t totlen; 1394 1395 if (!node->link) return; 1396 clusterBuildMessageHdr(hdr,CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK); 1397 totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData); 1398 hdr->totlen = htonl(totlen); 1399 clusterSendMessage(node->link,buf,totlen); 1400 } 1401 1402 /* If we believe 'node' is the "first slave" of it's master, reply with 1403 * a FAILOVER_AUTH_GRANTED packet. 1404 * 1405 * To be a first slave the sender must: 1406 * 1) Be a slave. 1407 * 2) Its master should be in FAIL state. 1408 * 3) Ordering all the slaves IDs for its master by run-id, it should be the 1409 * first (the smallest) among the ones not in FAIL / PFAIL state. 1410 */ 1411 void clusterSendFailoverAuthIfNeeded(clusterNode *node) { 1412 char first[REDIS_CLUSTER_NAMELEN]; 1413 clusterNode *master = node->slaveof; 1414 int j; 1415 1416 /* Node is a slave? Its master is down? */ 1417 if (!(node->flags & REDIS_NODE_SLAVE) || 1418 master == NULL || 1419 !(master->flags & REDIS_NODE_FAIL)) return; 1420 1421 /* Iterate all the master slaves to check what's the first one. */ 1422 memset(first,0xff,sizeof(first)); 1423 for (j = 0; j < master->numslaves; j++) { 1424 clusterNode *slave = master->slaves[j]; 1425 1426 if (slave->flags & (REDIS_NODE_FAIL|REDIS_NODE_PFAIL)) continue; 1427 if (memcmp(slave->name,first,sizeof(first)) < 0) { 1428 memcpy(first,slave->name,sizeof(first)); 1429 } 1430 } 1431 1432 /* Is 'node' the first slave? */ 1433 if (memcmp(node->name,first,sizeof(first)) != 0) return; 1434 1435 /* We can send the packet. */ 1436 clusterSendFailoverAuth(node); 1437 } 1438 1439 /* This function is called if we are a slave node and our master serving 1440 * a non-zero amount of hash slots is in FAIL state. 1441 * 1442 * The gaol of this function is: 1443 * 1) To check if we are able to perform a failover, is our data updated? 1444 * 2) Ask reachable masters the authorization to perform the failover. 1445 * 3) Check if there is the majority of masters agreeing we should failover. 1446 * 4) Perform the failover informing all the other nodes. 1447 */ 1448 void clusterHandleSlaveFailover(void) { 1449 time_t data_age = server.unixtime - server.repl_down_since; 1450 time_t auth_age = server.unixtime - server.cluster->failover_auth_time; 1451 int needed_quorum = (server.cluster->size / 2) + 1; 1452 int j; 1453 1454 /* Check if our data is recent enough. For now we just use a fixed 1455 * constant of ten times the node timeout since the cluster should 1456 * react much faster to a master down. */ 1457 if (data_age > 1458 server.cluster_node_timeout * REDIS_CLUSTER_SLAVE_VALIDITY_MULT) 1459 return; 1460 1461 /* TODO: check if we are the first slave as well? Or just rely on the 1462 * master authorization? */ 1463 1464 /* Ask masters if we are authorized to perform the failover. If there 1465 * is a pending auth request that's too old, reset it. */ 1466 if (server.cluster->failover_auth_time == 0 || 1467 auth_age > 1468 server.cluster_node_timeout * REDIS_CLUSTER_FAILOVER_AUTH_RETRY_MULT) 1469 { 1470 redisLog(REDIS_WARNING,"Asking masters if I can failover..."); 1471 server.cluster->failover_auth_time = time(NULL); 1472 server.cluster->failover_auth_count = 0; 1473 clusterRequestFailoverAuth(); 1474 return; /* Wait for replies. */ 1475 } 1476 1477 /* Check if we reached the quorum. */ 1478 if (server.cluster->failover_auth_count >= needed_quorum) { 1479 clusterNode *oldmaster = server.cluster->myself->slaveof; 1480 1481 redisLog(REDIS_WARNING, 1482 "Masters quorum reached: failing over my (failing) master."); 1483 /* We have the quorum, perform all the steps to correctly promote 1484 * this slave to a master. 1485 * 1486 * 1) Turn this node into a master. */ 1487 clusterNodeRemoveSlave(server.cluster->myself->slaveof, 1488 server.cluster->myself); 1489 server.cluster->myself->flags &= ~REDIS_NODE_SLAVE; 1490 server.cluster->myself->flags |= REDIS_NODE_MASTER; 1491 server.cluster->myself->flags |= REDIS_NODE_PROMOTED; 1492 server.cluster->myself->slaveof = NULL; 1493 replicationUnsetMaster(); 1494 1495 /* 2) Claim all the slots assigned to our master. */ 1496 for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) { 1497 if (clusterNodeGetSlotBit(oldmaster,j)) { 1498 clusterDelSlot(j); 1499 clusterAddSlot(server.cluster->myself,j); 1500 } 1501 } 1502 1503 /* 3) Pong all the other nodes so that they can update the state 1504 * accordingly and detect that we switched to master role. */ 1505 clusterBroadcastPong(); 1506 1507 /* 4) Update state and save config. */ 1508 clusterUpdateState(); 1509 clusterSaveConfigOrDie(); 1510 } 1511 } 1512 1513 /* ----------------------------------------------------------------------------- 1514 * CLUSTER cron job 1515 * -------------------------------------------------------------------------- */ 1516 1517 /* This is executed 1 time every second */ 1518 void clusterCron(void) { 1519 dictIterator *di; 1520 dictEntry *de; 1521 int j, update_state = 0; 1522 time_t min_pong = 0; 1523 clusterNode *min_pong_node = NULL; 1524 1525 /* Check if we have disconnected nodes and re-establish the connection. */ 1526 di = dictGetIterator(server.cluster->nodes); 1527 while((de = dictNext(di)) != NULL) { 1528 clusterNode *node = dictGetVal(de); 1529 1530 if (node->flags & (REDIS_NODE_MYSELF|REDIS_NODE_NOADDR)) continue; 1531 if (node->link == NULL) { 1532 int fd; 1533 time_t old_ping_sent; 1534 clusterLink *link; 1535 1536 fd = anetTcpNonBlockConnect(server.neterr, node->ip, 1537 node->port+REDIS_CLUSTER_PORT_INCR); 1538 if (fd == -1) continue; 1539 link = createClusterLink(node); 1540 link->fd = fd; 1541 node->link = link; 1542 aeCreateFileEvent(server.el,link->fd,AE_READABLE,clusterReadHandler,link); 1543 /* Queue a PING in the new connection ASAP: this is crucial 1544 * to avoid false positives in failure detection. 1545 * 1546 * If the node is flagged as MEET, we send a MEET message instead 1547 * of a PING one, to force the receiver to add us in its node 1548 * table. */ 1549 old_ping_sent = node->ping_sent; 1550 clusterSendPing(link, node->flags & REDIS_NODE_MEET ? 1551 CLUSTERMSG_TYPE_MEET : CLUSTERMSG_TYPE_PING); 1552 if (old_ping_sent) { 1553 /* If there was an active ping before the link was 1554 * disconnected, we want to restore the ping time, otherwise 1555 * replaced by the clusterSendPing() call. */ 1556 node->ping_sent = old_ping_sent; 1557 } 1558 /* We can clear the flag after the first packet is sent. 1559 * If we'll never receive a PONG, we'll never send new packets 1560 * to this node. Instead after the PONG is received and we 1561 * are no longer in meet/handshake status, we want to send 1562 * normal PING packets. */ 1563 node->flags &= ~REDIS_NODE_MEET; 1564 1565 redisLog(REDIS_DEBUG,"Connecting with Node %.40s at %s:%d", node->name, node->ip, node->port+REDIS_CLUSTER_PORT_INCR); 1566 } 1567 } 1568 dictReleaseIterator(di); 1569 1570 /* Ping some random node. Check a few random nodes and ping the one with 1571 * the oldest pong_received time */ 1572 for (j = 0; j < 5; j++) { 1573 de = dictGetRandomKey(server.cluster->nodes); 1574 clusterNode *this = dictGetVal(de); 1575 1576 /* Don't ping nodes disconnected or with a ping currently active. */ 1577 if (this->link == NULL || this->ping_sent != 0) continue; 1578 if (this->flags & (REDIS_NODE_MYSELF|REDIS_NODE_HANDSHAKE)) continue; 1579 if (min_pong_node == NULL || min_pong > this->pong_received) { 1580 min_pong_node = this; 1581 min_pong = this->pong_received; 1582 } 1583 } 1584 if (min_pong_node) { 1585 redisLog(REDIS_DEBUG,"Pinging node %.40s", min_pong_node->name); 1586 clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); 1587 } 1588 1589 /* Iterate nodes to check if we need to flag something as failing */ 1590 di = dictGetIterator(server.cluster->nodes); 1591 while((de = dictNext(di)) != NULL) { 1592 clusterNode *node = dictGetVal(de); 1593 time_t now = time(NULL); 1594 int delay; 1595 1596 if (node->flags & 1597 (REDIS_NODE_MYSELF|REDIS_NODE_NOADDR|REDIS_NODE_HANDSHAKE)) 1598 continue; 1599 1600 /* If we are waiting for the PONG more than half the cluster 1601 * timeout, reconnect the link: maybe there is a connection 1602 * issue even if the node is alive. */ 1603 if (node->link && /* is connected */ 1604 time(NULL) - node->link->ctime > 1605 server.cluster_node_timeout && /* was not already reconnected */ 1606 node->ping_sent && /* we already sent a ping */ 1607 node->pong_received < node->ping_sent && /* still waiting pong */ 1608 /* and we are waiting for the pong more than timeout/2 */ 1609 now - node->ping_sent > server.cluster_node_timeout/2) 1610 { 1611 /* Disconnect the link, it will be reconnected automatically. */ 1612 freeClusterLink(node->link); 1613 } 1614 1615 /* If we have currently no active ping in this instance, and the 1616 * received PONG is older than half the cluster timeout, send 1617 * a new ping now, to ensure all the nodes are pinged without 1618 * a too big delay. */ 1619 if (node->link && 1620 node->ping_sent == 0 && 1621 (now - node->pong_received) > server.cluster_node_timeout/2) 1622 { 1623 clusterSendPing(node->link, CLUSTERMSG_TYPE_PING); 1624 continue; 1625 } 1626 1627 /* Check only if we have an active ping for this instance. */ 1628 if (node->ping_sent == 0) continue; 1629 1630 /* Compute the delay of the PONG. Note that if we already received 1631 * the PONG, then node->ping_sent is zero, so can't reach this 1632 * code at all. */ 1633 delay = now - node->ping_sent; 1634 1635 if (delay > server.cluster_node_timeout) { 1636 /* Timeout reached. Set the node as possibly failing if it is 1637 * not already in this state. */ 1638 if (!(node->flags & (REDIS_NODE_PFAIL|REDIS_NODE_FAIL))) { 1639 redisLog(REDIS_DEBUG,"*** NODE %.40s possibly failing", 1640 node->name); 1641 node->flags |= REDIS_NODE_PFAIL; 1642 update_state = 1; 1643 } 1644 } 1645 } 1646 dictReleaseIterator(di); 1647 1648 /* If we are a slave node but the replication is still turned off, 1649 * enable it if we know the address of our master and it appears to 1650 * be up. */ 1651 if (server.cluster->myself->flags & REDIS_NODE_SLAVE && 1652 server.masterhost == NULL && 1653 server.cluster->myself->slaveof && 1654 !(server.cluster->myself->slaveof->flags & REDIS_NODE_NOADDR)) 1655 { 1656 replicationSetMaster(server.cluster->myself->slaveof->ip, 1657 server.cluster->myself->slaveof->port); 1658 } 1659 1660 /* If we are a slave and our master is down, but is serving slots, 1661 * call the function that handles the failover. 1662 * This function is called with a small delay in order to let the 1663 * FAIL message to propagate after failure detection, this is not 1664 * strictly required but makes 99.99% of failovers mechanically 1665 * simpler. */ 1666 if (server.cluster->myself->flags & REDIS_NODE_SLAVE && 1667 server.cluster->myself->slaveof && 1668 server.cluster->myself->slaveof->flags & REDIS_NODE_FAIL && 1669 (server.unixtime - server.cluster->myself->slaveof->fail_time) > 1670 REDIS_CLUSTER_FAILOVER_DELAY && 1671 server.cluster->myself->slaveof->numslots != 0) 1672 { 1673 clusterHandleSlaveFailover(); 1674 } 1675 1676 if (update_state) clusterUpdateState(); 1677 } 1678 1679 /* ----------------------------------------------------------------------------- 1680 * Slots management 1681 * -------------------------------------------------------------------------- */ 1682 1683 /* Test bit 'pos' in a generic bitmap. Return 1 if the bit is zet, 1684 * otherwise 0. */ 1685 int bitmapTestBit(unsigned char *bitmap, int pos) { 1686 off_t byte = pos/8; 1687 int bit = pos&7; 1688 return (bitmap[byte] & (1<<bit)) != 0; 1689 } 1690 1691 /* Set the bit at position 'pos' in a bitmap. */ 1692 void bitmapSetBit(unsigned char *bitmap, int pos) { 1693 off_t byte = pos/8; 1694 int bit = pos&7; 1695 bitmap[byte] |= 1<<bit; 1696 } 1697 1698 /* Clear the bit at position 'pos' in a bitmap. */ 1699 void bitmapClearBit(unsigned char *bitmap, int pos) { 1700 off_t byte = pos/8; 1701 int bit = pos&7; 1702 bitmap[byte] &= ~(1<<bit); 1703 } 1704 1705 /* Set the slot bit and return the old value. */ 1706 int clusterNodeSetSlotBit(clusterNode *n, int slot) { 1707 int old = bitmapTestBit(n->slots,slot); 1708 bitmapSetBit(n->slots,slot); 1709 if (!old) n->numslots++; 1710 return old; 1711 } 1712 1713 /* Clear the slot bit and return the old value. */ 1714 int clusterNodeClearSlotBit(clusterNode *n, int slot) { 1715 int old = bitmapTestBit(n->slots,slot); 1716 bitmapClearBit(n->slots,slot); 1717 if (old) n->numslots--; 1718 return old; 1719 } 1720 1721 /* Return the slot bit from the cluster node structure. */ 1722 int clusterNodeGetSlotBit(clusterNode *n, int slot) { 1723 return bitmapTestBit(n->slots,slot); 1724 } 1725 1726 /* Add the specified slot to the list of slots that node 'n' will 1727 * serve. Return REDIS_OK if the operation ended with success. 1728 * If the slot is already assigned to another instance this is considered 1729 * an error and REDIS_ERR is returned. */ 1730 int clusterAddSlot(clusterNode *n, int slot) { 1731 if (server.cluster->slots[slot]) return REDIS_ERR; 1732 clusterNodeSetSlotBit(n,slot); 1733 server.cluster->slots[slot] = n; 1734 return REDIS_OK; 1735 } 1736 1737 /* Delete the specified slot marking it as unassigned. 1738 * Returns REDIS_OK if the slot was assigned, otherwise if the slot was 1739 * already unassigned REDIS_ERR is returned. */ 1740 int clusterDelSlot(int slot) { 1741 clusterNode *n = server.cluster->slots[slot]; 1742 1743 if (!n) return REDIS_ERR; 1744 redisAssert(clusterNodeClearSlotBit(n,slot) == 1); 1745 server.cluster->slots[slot] = NULL; 1746 return REDIS_OK; 1747 } 1748 1749 /* Delete all the slots associated with the specified node. 1750 * The number of deleted slots is returned. */ 1751 int clusterDelNodeSlots(clusterNode *node) { 1752 int deleted = 0, j; 1753 1754 for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) { 1755 if (clusterNodeGetSlotBit(node,j)) clusterDelSlot(j); 1756 deleted++; 1757 } 1758 return deleted; 1759 } 1760 1761 /* ----------------------------------------------------------------------------- 1762 * Cluster state evaluation function 1763 * -------------------------------------------------------------------------- */ 1764 void clusterUpdateState(void) { 1765 int j, initial_state = server.cluster->state; 1766 int unreachable_masters = 0; 1767 1768 /* Start assuming the state is OK. We'll turn it into FAIL if there 1769 * are the right conditions. */ 1770 server.cluster->state = REDIS_CLUSTER_OK; 1771 1772 /* Check if all the slots are covered. */ 1773 for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) { 1774 if (server.cluster->slots[j] == NULL || 1775 server.cluster->slots[j]->flags & (REDIS_NODE_FAIL)) 1776 { 1777 server.cluster->state = REDIS_CLUSTER_FAIL; 1778 break; 1779 } 1780 } 1781 1782 /* Compute the cluster size, that is the number of master nodes 1783 * serving at least a single slot. 1784 * 1785 * At the same time count the number of unreachable masters with 1786 * at least one node. */ 1787 { 1788 dictIterator *di; 1789 dictEntry *de; 1790 1791 server.cluster->size = 0; 1792 di = dictGetIterator(server.cluster->nodes); 1793 while((de = dictNext(di)) != NULL) { 1794 clusterNode *node = dictGetVal(de); 1795 1796 if (node->flags & REDIS_NODE_MASTER && node->numslots) { 1797 server.cluster->size++; 1798 if (node->flags & (REDIS_NODE_FAIL|REDIS_NODE_PFAIL)) 1799 unreachable_masters++; 1800 } 1801 } 1802 dictReleaseIterator(di); 1803 } 1804 1805 /* If we can't reach at least half the masters, change the cluster state 1806 * as FAIL, as we are not even able to mark nodes as FAIL in this side 1807 * of the netsplit because of lack of majority. */ 1808 { 1809 int needed_quorum = (server.cluster->size / 2) + 1; 1810 1811 if (unreachable_masters >= needed_quorum) 1812 server.cluster->state = REDIS_CLUSTER_FAIL; 1813 } 1814 1815 /* Log a state change */ 1816 if (initial_state != server.cluster->state) 1817 redisLog(REDIS_WARNING,"Cluster state changed: %s", 1818 server.cluster->state == REDIS_CLUSTER_OK ? "ok" : "fail"); 1819 } 1820 1821 /* This function is called after the node startup in order to verify that data 1822 * loaded from disk is in agreement with the cluster configuration: 1823 * 1824 * 1) If we find keys about hash slots we have no responsibility for, the 1825 * following happens: 1826 * A) If no other node is in charge according to the current cluster 1827 * configuration, we add these slots to our node. 1828 * B) If according to our config other nodes are already in charge for 1829 * this lots, we set the slots as IMPORTING from our point of view 1830 * in order to justify we have those slots, and in order to make 1831 * redis-trib aware of the issue, so that it can try to fix it. 1832 * 2) If we find data in a DB different than DB0 we return REDIS_ERR to 1833 * signal the caller it should quit the server with an error message 1834 * or take other actions. 1835 * 1836 * The function always returns REDIS_OK even if it will try to correct 1837 * the error described in "1". However if data is found in DB different 1838 * from DB0, REDIS_ERR is returned. 1839 * 1840 * The function also uses the logging facility in order to warn the user 1841 * about desynchronizations between the data we have in memory and the 1842 * cluster configuration. */ 1843 int verifyClusterConfigWithData(void) { 1844 int j; 1845 int update_config = 0; 1846 1847 /* If this node is a slave, don't perform the check at all as we 1848 * completely depend on the replication stream. */ 1849 if (server.cluster->myself->flags & REDIS_NODE_SLAVE) return REDIS_OK; 1850 1851 /* Make sure we only have keys in DB0. */ 1852 for (j = 1; j < server.dbnum; j++) { 1853 if (dictSize(server.db[j].dict)) return REDIS_ERR; 1854 } 1855 1856 /* Check that all the slots we see populated memory have a corresponding 1857 * entry in the cluster table. Otherwise fix the table. */ 1858 for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) { 1859 if (!countKeysInSlot(j)) continue; /* No keys in this slot. */ 1860 /* Check if we are assigned to this slot or if we are importing it. 1861 * In both cases check the next slot as the configuration makes 1862 * sense. */ 1863 if (server.cluster->slots[j] == server.cluster->myself || 1864 server.cluster->importing_slots_from[j] != NULL) continue; 1865 1866 /* If we are here data and cluster config don't agree, and we have 1867 * slot 'j' populated even if we are not importing it, nor we are 1868 * assigned to this slot. Fix this condition. */ 1869 1870 update_config++; 1871 /* Case A: slot is unassigned. Take responsability for it. */ 1872 if (server.cluster->slots[j] == NULL) { 1873 redisLog(REDIS_WARNING, "I've keys about slot %d that is " 1874 "unassigned. Taking responsability " 1875 "for it.",j); 1876 clusterAddSlot(server.cluster->myself,j); 1877 } else { 1878 redisLog(REDIS_WARNING, "I've keys about slot %d that is " 1879 "already assigned to a different node. " 1880 "Setting it in importing state.",j); 1881 server.cluster->importing_slots_from[j] = server.cluster->slots[j]; 1882 } 1883 } 1884 if (update_config) clusterSaveConfigOrDie(); 1885 return REDIS_OK; 1886 } 1887 1888 /* ----------------------------------------------------------------------------- 1889 * SLAVE nodes handling 1890 * -------------------------------------------------------------------------- */ 1891 1892 /* Set the specified node 'n' as master. Setup the node as a slave if 1893 * needed. */ 1894 void clusterSetMaster(clusterNode *n) { 1895 clusterNode *myself = server.cluster->myself; 1896 1897 redisAssert(n != myself); 1898 redisAssert(myself->numslots == 0); 1899 1900 if (myself->flags & REDIS_NODE_MASTER) { 1901 myself->flags &= ~REDIS_NODE_MASTER; 1902 myself->flags |= REDIS_NODE_SLAVE; 1903 } 1904 /* Clear the promoted flag anyway if we are a slave, to ensure it will 1905 * be set only when the node turns into a master because of fail over. */ 1906 myself->flags &= ~REDIS_NODE_PROMOTED; 1907 myself->slaveof = n; 1908 replicationSetMaster(n->ip, n->port); 1909 } 1910 1911 /* ----------------------------------------------------------------------------- 1912 * CLUSTER command 1913 * -------------------------------------------------------------------------- */ 1914 1915 sds clusterGenNodesDescription(void) { 1916 sds ci = sdsempty(); 1917 dictIterator *di; 1918 dictEntry *de; 1919 int j, start; 1920 1921 di = dictGetIterator(server.cluster->nodes); 1922 while((de = dictNext(di)) != NULL) { 1923 clusterNode *node = dictGetVal(de); 1924 1925 /* Node coordinates */ 1926 ci = sdscatprintf(ci,"%.40s %s:%d ", 1927 node->name, 1928 node->ip, 1929 node->port); 1930 1931 /* Flags */ 1932 if (node->flags == 0) ci = sdscat(ci,"noflags,"); 1933 if (node->flags & REDIS_NODE_MYSELF) ci = sdscat(ci,"myself,"); 1934 if (node->flags & REDIS_NODE_MASTER) ci = sdscat(ci,"master,"); 1935 if (node->flags & REDIS_NODE_SLAVE) ci = sdscat(ci,"slave,"); 1936 if (node->flags & REDIS_NODE_PFAIL) ci = sdscat(ci,"fail?,"); 1937 if (node->flags & REDIS_NODE_FAIL) ci = sdscat(ci,"fail,"); 1938 if (node->flags & REDIS_NODE_HANDSHAKE) ci =sdscat(ci,"handshake,"); 1939 if (node->flags & REDIS_NODE_NOADDR) ci = sdscat(ci,"noaddr,"); 1940 if (node->flags & REDIS_NODE_PROMOTED) ci = sdscat(ci,"promoted,"); 1941 if (ci[sdslen(ci)-1] == ',') ci[sdslen(ci)-1] = ' '; 1942 1943 /* Slave of... or just "-" */ 1944 if (node->slaveof) 1945 ci = sdscatprintf(ci,"%.40s ",node->slaveof->name); 1946 else 1947 ci = sdscatprintf(ci,"- "); 1948 1949 /* Latency from the POV of this node, link status */ 1950 ci = sdscatprintf(ci,"%ld %ld %s", 1951 (long) node->ping_sent, 1952 (long) node->pong_received, 1953 (node->link || node->flags & REDIS_NODE_MYSELF) ? 1954 "connected" : "disconnected"); 1955 1956 /* Slots served by this instance */ 1957 start = -1; 1958 for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) { 1959 int bit; 1960 1961 if ((bit = clusterNodeGetSlotBit(node,j)) != 0) { 1962 if (start == -1) start = j; 1963 } 1964 if (start != -1 && (!bit || j == REDIS_CLUSTER_SLOTS-1)) { 1965 if (j == REDIS_CLUSTER_SLOTS-1) j++; 1966 1967 if (start == j-1) { 1968 ci = sdscatprintf(ci," %d",start); 1969 } else { 1970 ci = sdscatprintf(ci," %d-%d",start,j-1); 1971 } 1972 start = -1; 1973 } 1974 } 1975 1976 /* Just for MYSELF node we also dump info about slots that 1977 * we are migrating to other instances or importing from other 1978 * instances. */ 1979 if (node->flags & REDIS_NODE_MYSELF) { 1980 for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) { 1981 if (server.cluster->migrating_slots_to[j]) { 1982 ci = sdscatprintf(ci," [%d->-%.40s]",j, 1983 server.cluster->migrating_slots_to[j]->name); 1984 } else if (server.cluster->importing_slots_from[j]) { 1985 ci = sdscatprintf(ci," [%d-<-%.40s]",j, 1986 server.cluster->importing_slots_from[j]->name); 1987 } 1988 } 1989 } 1990 ci = sdscatlen(ci,"\n",1); 1991 } 1992 dictReleaseIterator(di); 1993 return ci; 1994 } 1995 1996 int getSlotOrReply(redisClient *c, robj *o) { 1997 long long slot; 1998 1999 if (getLongLongFromObject(o,&slot) != REDIS_OK || 2000 slot < 0 || slot > REDIS_CLUSTER_SLOTS) 2001 { 2002 addReplyError(c,"Invalid or out of range slot"); 2003 return -1; 2004 } 2005 return (int) slot; 2006 } 2007 2008 void clusterCommand(redisClient *c) { 2009 if (server.cluster_enabled == 0) { 2010 addReplyError(c,"This instance has cluster support disabled"); 2011 return; 2012 } 2013 2014 if (!strcasecmp(c->argv[1]->ptr,"meet") && c->argc == 4) { 2015 /* CLUSTER MEET <ip> <port> */ 2016 clusterNode *n; 2017 struct sockaddr_in sa; 2018 long port; 2019 2020 /* Perform sanity checks on IP/port */ 2021 if (inet_aton(c->argv[2]->ptr,&sa.sin_addr) == 0) { 2022 addReplyError(c,"Invalid IP address in MEET"); 2023 return; 2024 } 2025 if (getLongFromObjectOrReply(c, c->argv[3], &port, NULL) != REDIS_OK || 2026 port < 0 || port > (65535-REDIS_CLUSTER_PORT_INCR)) 2027 { 2028 addReplyError(c,"Invalid TCP port specified"); 2029 return; 2030 } 2031 2032 /* Finally add the node to the cluster with a random name, this 2033 * will get fixed in the first handshake (ping/pong). */ 2034 n = createClusterNode(NULL,REDIS_NODE_HANDSHAKE|REDIS_NODE_MEET); 2035 strncpy(n->ip,inet_ntoa(sa.sin_addr),sizeof(n->ip)); 2036 n->port = port; 2037 clusterAddNode(n); 2038 addReply(c,shared.ok); 2039 } else if (!strcasecmp(c->argv[1]->ptr,"nodes") && c->argc == 2) { 2040 /* CLUSTER NODES */ 2041 robj *o; 2042 sds ci = clusterGenNodesDescription(); 2043 2044 o = createObject(REDIS_STRING,ci); 2045 addReplyBulk(c,o); 2046 decrRefCount(o); 2047 } else if (!strcasecmp(c->argv[1]->ptr,"flushslots") && c->argc == 2) { 2048 /* CLUSTER FLUSHSLOTS */ 2049 if (dictSize(server.db[0].dict) != 0) { 2050 addReplyError(c,"DB must be empty to perform CLUSTER FLUSHSLOTS."); 2051 return; 2052 } 2053 clusterDelNodeSlots(server.cluster->myself); 2054 clusterUpdateState(); 2055 clusterSaveConfigOrDie(); 2056 addReply(c,shared.ok); 2057 } else if ((!strcasecmp(c->argv[1]->ptr,"addslots") || 2058 !strcasecmp(c->argv[1]->ptr,"delslots")) && c->argc >= 3) 2059 { 2060 /* CLUSTER ADDSLOTS <slot> [slot] ... */ 2061 /* CLUSTER DELSLOTS <slot> [slot] ... */ 2062 int j, slot; 2063 unsigned char *slots = zmalloc(REDIS_CLUSTER_SLOTS); 2064 int del = !strcasecmp(c->argv[1]->ptr,"delslots"); 2065 2066 memset(slots,0,REDIS_CLUSTER_SLOTS); 2067 /* Check that all the arguments are parsable and that all the 2068 * slots are not already busy. */ 2069 for (j = 2; j < c->argc; j++) { 2070 if ((slot = getSlotOrReply(c,c->argv[j])) == -1) { 2071 zfree(slots); 2072 return; 2073 } 2074 if (del && server.cluster->slots[slot] == NULL) { 2075 addReplyErrorFormat(c,"Slot %d is already unassigned", slot); 2076 zfree(slots); 2077 return; 2078 } else if (!del && server.cluster->slots[slot]) { 2079 addReplyErrorFormat(c,"Slot %d is already busy", slot); 2080 zfree(slots); 2081 return; 2082 } 2083 if (slots[slot]++ == 1) { 2084 addReplyErrorFormat(c,"Slot %d specified multiple times", 2085 (int)slot); 2086 zfree(slots); 2087 return; 2088 } 2089 } 2090 for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) { 2091 if (slots[j]) { 2092 int retval; 2093 2094 /* If this slot was set as importing we can clear this 2095 * state as now we are the real owner of the slot. */ 2096 if (server.cluster->importing_slots_from[j]) 2097 server.cluster->importing_slots_from[j] = NULL; 2098 2099 retval = del ? clusterDelSlot(j) : 2100 clusterAddSlot(server.cluster->myself,j); 2101 redisAssertWithInfo(c,NULL,retval == REDIS_OK); 2102 } 2103 } 2104 zfree(slots); 2105 clusterUpdateState(); 2106 clusterSaveConfigOrDie(); 2107 addReply(c,shared.ok); 2108 } else if (!strcasecmp(c->argv[1]->ptr,"setslot") && c->argc >= 4) { 2109 /* SETSLOT 10 MIGRATING <node ID> */ 2110 /* SETSLOT 10 IMPORTING <node ID> */ 2111 /* SETSLOT 10 STABLE */ 2112 /* SETSLOT 10 NODE <node ID> */ 2113 int slot; 2114 clusterNode *n; 2115 2116 if ((slot = getSlotOrReply(c,c->argv[2])) == -1) return; 2117 2118 if (!strcasecmp(c->argv[3]->ptr,"migrating") && c->argc == 5) { 2119 if (server.cluster->slots[slot] != server.cluster->myself) { 2120 addReplyErrorFormat(c,"I'm not the owner of hash slot %u",slot); 2121 return; 2122 } 2123 if ((n = clusterLookupNode(c->argv[4]->ptr)) == NULL) { 2124 addReplyErrorFormat(c,"I don't know about node %s", 2125 (char*)c->argv[4]->ptr); 2126 return; 2127 } 2128 server.cluster->migrating_slots_to[slot] = n; 2129 } else if (!strcasecmp(c->argv[3]->ptr,"importing") && c->argc == 5) { 2130 if (server.cluster->slots[slot] == server.cluster->myself) { 2131 addReplyErrorFormat(c, 2132 "I'm already the owner of hash slot %u",slot); 2133 return; 2134 } 2135 if ((n = clusterLookupNode(c->argv[4]->ptr)) == NULL) { 2136 addReplyErrorFormat(c,"I don't know about node %s", 2137 (char*)c->argv[3]->ptr); 2138 return; 2139 } 2140 server.cluster->importing_slots_from[slot] = n; 2141 } else if (!strcasecmp(c->argv[3]->ptr,"stable") && c->argc == 4) { 2142 /* CLUSTER SETSLOT <SLOT> STABLE */ 2143 server.cluster->importing_slots_from[slot] = NULL; 2144 server.cluster->migrating_slots_to[slot] = NULL; 2145 } else if (!strcasecmp(c->argv[3]->ptr,"node") && c->argc == 5) { 2146 /* CLUSTER SETSLOT <SLOT> NODE <NODE ID> */ 2147 clusterNode *n = clusterLookupNode(c->argv[4]->ptr); 2148 2149 if (!n) { 2150 addReplyErrorFormat(c,"Unknown node %s", 2151 (char*)c->argv[4]->ptr); 2152 return; 2153 } 2154 /* If this hash slot was served by 'myself' before to switch 2155 * make sure there are no longer local keys for this hash slot. */ 2156 if (server.cluster->slots[slot] == server.cluster->myself && 2157 n != server.cluster->myself) 2158 { 2159 if (countKeysInSlot(slot) != 0) { 2160 addReplyErrorFormat(c, "Can't assign hashslot %d to a different node while I still hold keys for this hash slot.", slot); 2161 return; 2162 } 2163 } 2164 /* If this node was the slot owner and the slot was marked as 2165 * migrating, assigning the slot to another node will clear 2166 * the migratig status. */ 2167 if (server.cluster->slots[slot] == server.cluster->myself && 2168 server.cluster->migrating_slots_to[slot]) 2169 server.cluster->migrating_slots_to[slot] = NULL; 2170 2171 /* If this node was importing this slot, assigning the slot to 2172 * itself also clears the importing status. */ 2173 if (n == server.cluster->myself && 2174 server.cluster->importing_slots_from[slot]) 2175 server.cluster->importing_slots_from[slot] = NULL; 2176 clusterDelSlot(slot); 2177 clusterAddSlot(n,slot); 2178 } else { 2179 addReplyError(c,"Invalid CLUSTER SETSLOT action or number of arguments"); 2180 return; 2181 } 2182 clusterUpdateState(); 2183 clusterSaveConfigOrDie(); 2184 addReply(c,shared.ok); 2185 } else if (!strcasecmp(c->argv[1]->ptr,"info") && c->argc == 2) { 2186 /* CLUSTER INFO */ 2187 char *statestr[] = {"ok","fail","needhelp"}; 2188 int slots_assigned = 0, slots_ok = 0, slots_pfail = 0, slots_fail = 0; 2189 int j; 2190 2191 for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) { 2192 clusterNode *n = server.cluster->slots[j]; 2193 2194 if (n == NULL) continue; 2195 slots_assigned++; 2196 if (n->flags & REDIS_NODE_FAIL) { 2197 slots_fail++; 2198 } else if (n->flags & REDIS_NODE_PFAIL) { 2199 slots_pfail++; 2200 } else { 2201 slots_ok++; 2202 } 2203 } 2204 2205 sds info = sdscatprintf(sdsempty(), 2206 "cluster_state:%s\r\n" 2207 "cluster_slots_assigned:%d\r\n" 2208 "cluster_slots_ok:%d\r\n" 2209 "cluster_slots_pfail:%d\r\n" 2210 "cluster_slots_fail:%d\r\n" 2211 "cluster_known_nodes:%lu\r\n" 2212 "cluster_size:%d\r\n" 2213 , statestr[server.cluster->state], 2214 slots_assigned, 2215 slots_ok, 2216 slots_pfail, 2217 slots_fail, 2218 dictSize(server.cluster->nodes), 2219 server.cluster->size 2220 ); 2221 addReplySds(c,sdscatprintf(sdsempty(),"$%lu\r\n", 2222 (unsigned long)sdslen(info))); 2223 addReplySds(c,info); 2224 addReply(c,shared.crlf); 2225 } else if (!strcasecmp(c->argv[1]->ptr,"keyslot") && c->argc == 3) { 2226 /* CLUSTER KEYSLOT <key> */ 2227 sds key = c->argv[2]->ptr; 2228 2229 addReplyLongLong(c,keyHashSlot(key,sdslen(key))); 2230 } else if (!strcasecmp(c->argv[1]->ptr,"countkeysinslot") && c->argc == 3) { 2231 /* CLUSTER COUNTKEYSINSLOT <slot> */ 2232 long long slot; 2233 2234 if (getLongLongFromObjectOrReply(c,c->argv[2],&slot,NULL) != REDIS_OK) 2235 return; 2236 if (slot < 0 || slot >= REDIS_CLUSTER_SLOTS) { 2237 addReplyError(c,"Invalid slot"); 2238 return; 2239 } 2240 addReplyLongLong(c,countKeysInSlot(slot)); 2241 } else if (!strcasecmp(c->argv[1]->ptr,"getkeysinslot") && c->argc == 4) { 2242 /* CLUSTER GETKEYSINSLOT <slot> <count> */ 2243 long long maxkeys, slot; 2244 unsigned int numkeys, j; 2245 robj **keys; 2246 2247 if (getLongLongFromObjectOrReply(c,c->argv[2],&slot,NULL) != REDIS_OK) 2248 return; 2249 if (getLongLongFromObjectOrReply(c,c->argv[3],&maxkeys,NULL) != REDIS_OK) 2250 return; 2251 if (slot < 0 || slot >= REDIS_CLUSTER_SLOTS || maxkeys < 0) { 2252 addReplyError(c,"Invalid slot or number of keys"); 2253 return; 2254 } 2255 2256 keys = zmalloc(sizeof(robj*)*maxkeys); 2257 numkeys = getKeysInSlot(slot, keys, maxkeys); 2258 addReplyMultiBulkLen(c,numkeys); 2259 for (j = 0; j < numkeys; j++) addReplyBulk(c,keys[j]); 2260 zfree(keys); 2261 } else if (!strcasecmp(c->argv[1]->ptr,"forget") && c->argc == 3) { 2262 /* CLUSTER FORGET <NODE ID> */ 2263 clusterNode *n = clusterLookupNode(c->argv[2]->ptr); 2264 2265 if (!n) { 2266 addReplyErrorFormat(c,"Unknown node %s", (char*)c->argv[2]->ptr); 2267 return; 2268 } 2269 clusterDelNode(n); 2270 clusterUpdateState(); 2271 clusterSaveConfigOrDie(); 2272 addReply(c,shared.ok); 2273 } else if (!strcasecmp(c->argv[1]->ptr,"replicate") && c->argc == 3) { 2274 /* CLUSTER REPLICATE <NODE ID> */ 2275 clusterNode *n = clusterLookupNode(c->argv[2]->ptr); 2276 2277 /* Lookup the specified node in our table. */ 2278 if (!n) { 2279 addReplyErrorFormat(c,"Unknown node %s", (char*)c->argv[2]->ptr); 2280 return; 2281 } 2282 2283 /* I can't replicate myself. */ 2284 if (n == server.cluster->myself) { 2285 addReplyError(c,"Can't replicate myself"); 2286 return; 2287 } 2288 2289 /* Can't replicate a slave. */ 2290 if (n->slaveof != NULL) { 2291 addReplyError(c,"I can only replicate a master, not a slave."); 2292 return; 2293 } 2294 2295 /* We should have no assigned slots to accept to replicate some 2296 * other node. */ 2297 if (server.cluster->myself->numslots != 0 || 2298 dictSize(server.db[0].dict) != 0) 2299 { 2300 addReplyError(c,"To set a master the node must be empty and without assigned slots."); 2301 return; 2302 } 2303 2304 /* Set the master. */ 2305 clusterSetMaster(n); 2306 clusterUpdateState(); 2307 clusterSaveConfigOrDie(); 2308 addReply(c,shared.ok); 2309 } else { 2310 addReplyError(c,"Wrong CLUSTER subcommand or number of arguments"); 2311 } 2312 } 2313 2314 /* ----------------------------------------------------------------------------- 2315 * DUMP, RESTORE and MIGRATE commands 2316 * -------------------------------------------------------------------------- */ 2317 2318 /* Generates a DUMP-format representation of the object 'o', adding it to the 2319 * io stream pointed by 'rio'. This function can't fail. */ 2320 void createDumpPayload(rio *payload, robj *o) { 2321 unsigned char buf[2]; 2322 uint64_t crc; 2323 2324 /* Serialize the object in a RDB-like format. It consist of an object type 2325 * byte followed by the serialized object. This is understood by RESTORE. */ 2326 rioInitWithBuffer(payload,sdsempty()); 2327 redisAssert(rdbSaveObjectType(payload,o)); 2328 redisAssert(rdbSaveObject(payload,o)); 2329 2330 /* Write the footer, this is how it looks like: 2331 * ----------------+---------------------+---------------+ 2332 * ... RDB payload | 2 bytes RDB version | 8 bytes CRC64 | 2333 * ----------------+---------------------+---------------+ 2334 * RDB version and CRC are both in little endian. 2335 */ 2336 2337 /* RDB version */ 2338 buf[0] = REDIS_RDB_VERSION & 0xff; 2339 buf[1] = (REDIS_RDB_VERSION >> 8) & 0xff; 2340 payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr,buf,2); 2341 2342 /* CRC64 */ 2343 crc = crc64(0,(unsigned char*)payload->io.buffer.ptr, 2344 sdslen(payload->io.buffer.ptr)); 2345 memrev64ifbe(&crc); 2346 payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr,&crc,8); 2347 } 2348 2349 /* Verify that the RDB version of the dump payload matches the one of this Redis 2350 * instance and that the checksum is ok. 2351 * If the DUMP payload looks valid REDIS_OK is returned, otherwise REDIS_ERR 2352 * is returned. */ 2353 int verifyDumpPayload(unsigned char *p, size_t len) { 2354 unsigned char *footer; 2355 uint16_t rdbver; 2356 uint64_t crc; 2357 2358 /* At least 2 bytes of RDB version and 8 of CRC64 should be present. */ 2359 if (len < 10) return REDIS_ERR; 2360 footer = p+(len-10); 2361 2362 /* Verify RDB version */ 2363 rdbver = (footer[1] << 8) | footer[0]; 2364 if (rdbver != REDIS_RDB_VERSION) return REDIS_ERR; 2365 2366 /* Verify CRC64 */ 2367 crc = crc64(0,p,len-8); 2368 memrev64ifbe(&crc); 2369 return (memcmp(&crc,footer+2,8) == 0) ? REDIS_OK : REDIS_ERR; 2370 } 2371 2372 /* DUMP keyname 2373 * DUMP is actually not used by Redis Cluster but it is the obvious 2374 * complement of RESTORE and can be useful for different applications. */ 2375 void dumpCommand(redisClient *c) { 2376 robj *o, *dumpobj; 2377 rio payload; 2378 2379 /* Check if the key is here. */ 2380 if ((o = lookupKeyRead(c->db,c->argv[1])) == NULL) { 2381 addReply(c,shared.nullbulk); 2382 return; 2383 } 2384 2385 /* Create the DUMP encoded representation. */ 2386 createDumpPayload(&payload,o); 2387 2388 /* Transfer to the client */ 2389 dumpobj = createObject(REDIS_STRING,payload.io.buffer.ptr); 2390 addReplyBulk(c,dumpobj); 2391 decrRefCount(dumpobj); 2392 return; 2393 } 2394 2395 /* RESTORE key ttl serialized-value [REPLACE] */ 2396 void restoreCommand(redisClient *c) { 2397 long ttl; 2398 rio payload; 2399 int j, type, replace = 0; 2400 robj *obj; 2401 2402 /* Parse additional options */ 2403 for (j = 4; j < c->argc; j++) { 2404 if (!strcasecmp(c->argv[j]->ptr,"replace")) { 2405 replace = 1; 2406 } else { 2407 addReply(c,shared.syntaxerr); 2408 return; 2409 } 2410 } 2411 2412 /* Make sure this key does not already exist here... */ 2413 if (!replace && lookupKeyWrite(c->db,c->argv[1]) != NULL) { 2414 addReplyError(c,"Target key name is busy."); 2415 return; 2416 } 2417 2418 /* Check if the TTL value makes sense */ 2419 if (getLongFromObjectOrReply(c,c->argv[2],&ttl,NULL) != REDIS_OK) { 2420 return; 2421 } else if (ttl < 0) { 2422 addReplyError(c,"Invalid TTL value, must be >= 0"); 2423 return; 2424 } 2425 2426 /* Verify RDB version and data checksum. */ 2427 if (verifyDumpPayload(c->argv[3]->ptr,sdslen(c->argv[3]->ptr)) == REDIS_ERR) { 2428 addReplyError(c,"DUMP payload version or checksum are wrong"); 2429 return; 2430 } 2431 2432 rioInitWithBuffer(&payload,c->argv[3]->ptr); 2433 if (((type = rdbLoadObjectType(&payload)) == -1) || 2434 ((obj = rdbLoadObject(type,&payload)) == NULL)) 2435 { 2436 addReplyError(c,"Bad data format"); 2437 return; 2438 } 2439 2440 /* Remove the old key if needed. */ 2441 if (replace) dbDelete(c->db,c->argv[1]); 2442 2443 /* Create the key and set the TTL if any */ 2444 dbAdd(c->db,c->argv[1],obj); 2445 if (ttl) setExpire(c->db,c->argv[1],mstime()+ttl); 2446 signalModifiedKey(c->db,c->argv[1]); 2447 addReply(c,shared.ok); 2448 server.dirty++; 2449 } 2450 2451 /* MIGRATE socket cache implementation. 2452 * 2453 * We take a map between host:ip and a TCP socket that we used to connect 2454 * to this instance in recent time. 2455 * This sockets are closed when the max number we cache is reached, and also 2456 * in serverCron() when they are around for more than a few seconds. */ 2457 #define MIGRATE_SOCKET_CACHE_ITEMS 64 /* max num of items in the cache. */ 2458 #define MIGRATE_SOCKET_CACHE_TTL 10 /* close cached socekts after 10 sec. */ 2459 2460 typedef struct migrateCachedSocket { 2461 int fd; 2462 time_t last_use_time; 2463 } migrateCachedSocket; 2464 2465 /* Return a TCP scoket connected with the target instance, possibly returning 2466 * a cached one. 2467 * 2468 * This function is responsible of sending errors to the client if a 2469 * connection can't be established. In this case -1 is returned. 2470 * Otherwise on success the socket is returned, and the caller should not 2471 * attempt to free it after usage. 2472 * 2473 * If the caller detects an error while using the socket, migrateCloseSocket() 2474 * should be called so that the connection will be craeted from scratch 2475 * the next time. */ 2476 int migrateGetSocket(redisClient *c, robj *host, robj *port, long timeout) { 2477 int fd; 2478 sds name = sdsempty(); 2479 migrateCachedSocket *cs; 2480 2481 /* Check if we have an already cached socket for this ip:port pair. */ 2482 name = sdscatlen(name,host->ptr,sdslen(host->ptr)); 2483 name = sdscatlen(name,":",1); 2484 name = sdscatlen(name,port->ptr,sdslen(port->ptr)); 2485 cs = dictFetchValue(server.migrate_cached_sockets,name); 2486 if (cs) { 2487 sdsfree(name); 2488 cs->last_use_time = server.unixtime; 2489 return cs->fd; 2490 } 2491 2492 /* No cached socket, create one. */ 2493 if (dictSize(server.migrate_cached_sockets) == MIGRATE_SOCKET_CACHE_ITEMS) { 2494 /* Too many items, drop one at random. */ 2495 dictEntry *de = dictGetRandomKey(server.migrate_cached_sockets); 2496 cs = dictGetVal(de); 2497 close(cs->fd); 2498 zfree(cs); 2499 dictDelete(server.migrate_cached_sockets,dictGetKey(de)); 2500 } 2501 2502 /* Create the socket */ 2503 fd = anetTcpNonBlockConnect(server.neterr,c->argv[1]->ptr, 2504 atoi(c->argv[2]->ptr)); 2505 if (fd == -1) { 2506 sdsfree(name); 2507 addReplyErrorFormat(c,"Can't connect to target node: %s", 2508 server.neterr); 2509 return -1; 2510 } 2511 anetEnableTcpNoDelay(server.neterr,fd); 2512 2513 /* Check if it connects within the specified timeout. */ 2514 if ((aeWait(fd,AE_WRITABLE,timeout) & AE_WRITABLE) == 0) { 2515 sdsfree(name); 2516 addReplySds(c,sdsnew("-IOERR error or timeout connecting to the client\r\n")); 2517 close(fd); 2518 return -1; 2519 } 2520 2521 /* Add to the cache and return it to the caller. */ 2522 cs = zmalloc(sizeof(*cs)); 2523 cs->fd = fd; 2524 cs->last_use_time = server.unixtime; 2525 dictAdd(server.migrate_cached_sockets,name,cs); 2526 return fd; 2527 } 2528 2529 /* Free a migrate cached connection. */ 2530 void migrateCloseSocket(robj *host, robj *port) { 2531 sds name = sdsempty(); 2532 migrateCachedSocket *cs; 2533 2534 name = sdscatlen(name,host->ptr,sdslen(host->ptr)); 2535 name = sdscatlen(name,":",1); 2536 name = sdscatlen(name,port->ptr,sdslen(port->ptr)); 2537 cs = dictFetchValue(server.migrate_cached_sockets,name); 2538 if (!cs) { 2539 sdsfree(name); 2540 return; 2541 } 2542 2543 close(cs->fd); 2544 zfree(cs); 2545 dictDelete(server.migrate_cached_sockets,name); 2546 sdsfree(name); 2547 } 2548 2549 void migrateCloseTimedoutSockets(void) { 2550 dictIterator *di = dictGetSafeIterator(server.migrate_cached_sockets); 2551 dictEntry *de; 2552 2553 while((de = dictNext(di)) != NULL) { 2554 migrateCachedSocket *cs = dictGetVal(de); 2555 2556 if ((server.unixtime - cs->last_use_time) > MIGRATE_SOCKET_CACHE_TTL) { 2557 close(cs->fd); 2558 zfree(cs); 2559 dictDelete(server.migrate_cached_sockets,dictGetKey(de)); 2560 } 2561 } 2562 dictReleaseIterator(di); 2563 } 2564 2565 /* MIGRATE host port key dbid timeout [COPY | REPLACE] */ 2566 void migrateCommand(redisClient *c) { 2567 int fd, copy, replace, j; 2568 long timeout; 2569 long dbid; 2570 long long ttl, expireat; 2571 robj *o; 2572 rio cmd, payload; 2573 int retry_num = 0; 2574 2575 try_again: 2576 /* Initialization */ 2577 copy = 0; 2578 replace = 0; 2579 ttl = 0; 2580 2581 /* Parse additional options */ 2582 for (j = 6; j < c->argc; j++) { 2583 if (!strcasecmp(c->argv[j]->ptr,"copy")) { 2584 copy = 1; 2585 } else if (!strcasecmp(c->argv[j]->ptr,"replace")) { 2586 replace = 1; 2587 } else { 2588 addReply(c,shared.syntaxerr); 2589 return; 2590 } 2591 } 2592 2593 /* Sanity check */ 2594 if (getLongFromObjectOrReply(c,c->argv[5],&timeout,NULL) != REDIS_OK) 2595 return; 2596 if (getLongFromObjectOrReply(c,c->argv[4],&dbid,NULL) != REDIS_OK) 2597 return; 2598 if (timeout <= 0) timeout = 1000; 2599 2600 /* Check if the key is here. If not we reply with success as there is 2601 * nothing to migrate (for instance the key expired in the meantime), but 2602 * we include such information in the reply string. */ 2603 if ((o = lookupKeyRead(c->db,c->argv[3])) == NULL) { 2604 addReplySds(c,sdsnew("+NOKEY\r\n")); 2605 return; 2606 } 2607 2608 /* Connect */ 2609 fd = migrateGetSocket(c,c->argv[1],c->argv[2],timeout); 2610 if (fd == -1) return; /* error sent to the client by migrateGetSocket() */ 2611 2612 /* Create RESTORE payload and generate the protocol to call the command. */ 2613 rioInitWithBuffer(&cmd,sdsempty()); 2614 redisAssertWithInfo(c,NULL,rioWriteBulkCount(&cmd,'*',2)); 2615 redisAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"SELECT",6)); 2616 redisAssertWithInfo(c,NULL,rioWriteBulkLongLong(&cmd,dbid)); 2617 2618 expireat = getExpire(c->db,c->argv[3]); 2619 if (expireat != -1) { 2620 ttl = expireat-mstime(); 2621 if (ttl < 1) ttl = 1; 2622 } 2623 redisAssertWithInfo(c,NULL,rioWriteBulkCount(&cmd,'*',replace ? 5 : 4)); 2624 if (server.cluster_enabled) 2625 redisAssertWithInfo(c,NULL, 2626 rioWriteBulkString(&cmd,"RESTORE-ASKING",14)); 2627 else 2628 redisAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"RESTORE",7)); 2629 redisAssertWithInfo(c,NULL,c->argv[3]->encoding == REDIS_ENCODING_RAW); 2630 redisAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,c->argv[3]->ptr,sdslen(c->argv[3]->ptr))); 2631 redisAssertWithInfo(c,NULL,rioWriteBulkLongLong(&cmd,ttl)); 2632 2633 /* Emit the payload argument, that is the serialized object using 2634 * the DUMP format. */ 2635 createDumpPayload(&payload,o); 2636 redisAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,payload.io.buffer.ptr, 2637 sdslen(payload.io.buffer.ptr))); 2638 sdsfree(payload.io.buffer.ptr); 2639 2640 /* Add the REPLACE option to the RESTORE command if it was specified 2641 * as a MIGRATE option. */ 2642 if (replace) 2643 redisAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"REPLACE",7)); 2644 2645 /* Transfer the query to the other node in 64K chunks. */ 2646 errno = 0; 2647 { 2648 sds buf = cmd.io.buffer.ptr; 2649 size_t pos = 0, towrite; 2650 int nwritten = 0; 2651 2652 while ((towrite = sdslen(buf)-pos) > 0) { 2653 towrite = (towrite > (64*1024) ? (64*1024) : towrite); 2654 nwritten = syncWrite(fd,buf+pos,towrite,timeout); 2655 if (nwritten != (signed)towrite) goto socket_wr_err; 2656 pos += nwritten; 2657 } 2658 } 2659 2660 /* Read back the reply. */ 2661 { 2662 char buf1[1024]; 2663 char buf2[1024]; 2664 2665 /* Read the two replies */ 2666 if (syncReadLine(fd, buf1, sizeof(buf1), timeout) <= 0) 2667 goto socket_rd_err; 2668 if (syncReadLine(fd, buf2, sizeof(buf2), timeout) <= 0) 2669 goto socket_rd_err; 2670 if (buf1[0] == '-' || buf2[0] == '-') { 2671 addReplyErrorFormat(c,"Target instance replied with error: %s", 2672 (buf1[0] == '-') ? buf1+1 : buf2+1); 2673 } else { 2674 robj *aux; 2675 2676 if (!copy) { 2677 /* No COPY option: remove the local key, signal the change. */ 2678 dbDelete(c->db,c->argv[3]); 2679 signalModifiedKey(c->db,c->argv[3]); 2680 } 2681 addReply(c,shared.ok); 2682 server.dirty++; 2683 2684 /* Translate MIGRATE as DEL for replication/AOF. */ 2685 aux = createStringObject("DEL",3); 2686 rewriteClientCommandVector(c,2,aux,c->argv[3]); 2687 decrRefCount(aux); 2688 } 2689 } 2690 2691 sdsfree(cmd.io.buffer.ptr); 2692 return; 2693 2694 socket_wr_err: 2695 sdsfree(cmd.io.buffer.ptr); 2696 migrateCloseSocket(c->argv[1],c->argv[2]); 2697 if (errno != ETIMEDOUT && retry_num++ == 0) goto try_again; 2698 addReplySds(c, 2699 sdsnew("-IOERR error or timeout writing to target instance\r\n")); 2700 return; 2701 2702 socket_rd_err: 2703 sdsfree(cmd.io.buffer.ptr); 2704 migrateCloseSocket(c->argv[1],c->argv[2]); 2705 if (errno != ETIMEDOUT && retry_num++ == 0) goto try_again; 2706 addReplySds(c, 2707 sdsnew("-IOERR error or timeout reading from target node\r\n")); 2708 return; 2709 } 2710 2711 /* The ASKING command is required after a -ASK redirection. 2712 * The client should issue ASKING before to actually send the command to 2713 * the target instance. See the Redis Cluster specification for more 2714 * information. */ 2715 void askingCommand(redisClient *c) { 2716 if (server.cluster_enabled == 0) { 2717 addReplyError(c,"This instance has cluster support disabled"); 2718 return; 2719 } 2720 c->flags |= REDIS_ASKING; 2721 addReply(c,shared.ok); 2722 } 2723 2724 /* ----------------------------------------------------------------------------- 2725 * Cluster functions related to serving / redirecting clients 2726 * -------------------------------------------------------------------------- */ 2727 2728 /* Return the pointer to the cluster node that is able to serve the command. 2729 * For the function to succeed the command should only target a single 2730 * key (or the same key multiple times). 2731 * 2732 * If the returned node should be used only for this request, the *ask 2733 * integer is set to '1', otherwise to '0'. This is used in order to 2734 * let the caller know if we should reply with -MOVED or with -ASK. 2735 * 2736 * If the command contains multiple keys, and as a consequence it is not 2737 * possible to handle the request in Redis Cluster, NULL is returned. */ 2738 clusterNode *getNodeByQuery(redisClient *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *ask) { 2739 clusterNode *n = NULL; 2740 robj *firstkey = NULL; 2741 multiState *ms, _ms; 2742 multiCmd mc; 2743 int i, slot = 0; 2744 2745 /* We handle all the cases as if they were EXEC commands, so we have 2746 * a common code path for everything */ 2747 if (cmd->proc == execCommand) { 2748 /* If REDIS_MULTI flag is not set EXEC is just going to return an 2749 * error. */ 2750 if (!(c->flags & REDIS_MULTI)) return server.cluster->myself; 2751 ms = &c->mstate; 2752 } else { 2753 /* In order to have a single codepath create a fake Multi State 2754 * structure if the client is not in MULTI/EXEC state, this way 2755 * we have a single codepath below. */ 2756 ms = &_ms; 2757 _ms.commands = &mc; 2758 _ms.count = 1; 2759 mc.argv = argv; 2760 mc.argc = argc; 2761 mc.cmd = cmd; 2762 } 2763 2764 /* Check that all the keys are the same key, and get the slot and 2765 * node for this key. */ 2766 for (i = 0; i < ms->count; i++) { 2767 struct redisCommand *mcmd; 2768 robj **margv; 2769 int margc, *keyindex, numkeys, j; 2770 2771 mcmd = ms->commands[i].cmd; 2772 margc = ms->commands[i].argc; 2773 margv = ms->commands[i].argv; 2774 2775 keyindex = getKeysFromCommand(mcmd,margv,margc,&numkeys, 2776 REDIS_GETKEYS_ALL); 2777 for (j = 0; j < numkeys; j++) { 2778 if (firstkey == NULL) { 2779 /* This is the first key we see. Check what is the slot 2780 * and node. */ 2781 firstkey = margv[keyindex[j]]; 2782 2783 slot = keyHashSlot((char*)firstkey->ptr, sdslen(firstkey->ptr)); 2784 n = server.cluster->slots[slot]; 2785 redisAssertWithInfo(c,firstkey,n != NULL); 2786 } else { 2787 /* If it is not the first key, make sure it is exactly 2788 * the same key as the first we saw. */ 2789 if (!equalStringObjects(firstkey,margv[keyindex[j]])) { 2790 getKeysFreeResult(keyindex); 2791 return NULL; 2792 } 2793 } 2794 } 2795 getKeysFreeResult(keyindex); 2796 } 2797 if (ask) *ask = 0; /* This is the default. Set to 1 if needed later. */ 2798 /* No key at all in command? then we can serve the request 2799 * without redirections. */ 2800 if (n == NULL) return server.cluster->myself; 2801 if (hashslot) *hashslot = slot; 2802 /* This request is about a slot we are migrating into another instance? 2803 * Then we need to check if we have the key. If we have it we can reply. 2804 * If instead is a new key, we pass the request to the node that is 2805 * receiving the slot. */ 2806 if (n == server.cluster->myself && 2807 server.cluster->migrating_slots_to[slot] != NULL) 2808 { 2809 if (lookupKeyRead(&server.db[0],firstkey) == NULL) { 2810 if (ask) *ask = 1; 2811 return server.cluster->migrating_slots_to[slot]; 2812 } 2813 } 2814 /* Handle the case in which we are receiving this hash slot from 2815 * another instance, so we'll accept the query even if in the table 2816 * it is assigned to a different node, but only if the client 2817 * issued an ASKING command before. */ 2818 if (server.cluster->importing_slots_from[slot] != NULL && 2819 (c->flags & REDIS_ASKING || cmd->flags & REDIS_CMD_ASKING)) { 2820 return server.cluster->myself; 2821 } 2822 /* It's not a -ASK case. Base case: just return the right node. */ 2823 return n; 2824 } 2825