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