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