redis集群实现(三)集群删除节点
来源:互联网 发布:淘宝联盟链接转换工具 编辑:程序博客网 时间:2024/06/05 11:38
redis集群里的节点支持动态删除,但是一般情况下不会这么做,只有在节点软硬件升级的时候才会主动让节点下线。删除节点的方式就是redis-cli客户端连接到服务器,然后执行cluster forget node-id就可以了,如果是删除一个从节点的话,集群仍然是可用状态,如果是删除一个主节点的话,集群的槽位不足,就会变成不可用状态。
下边看下我在自己的虚拟机运行的例子
127.0.0.1:7000> cluster infocluster_state:okcluster_slots_assigned:16384cluster_slots_ok:16384cluster_slots_pfail:0cluster_slots_fail:0cluster_known_nodes:6cluster_size:3cluster_current_epoch:8cluster_my_epoch:7cluster_stats_messages_sent:2058cluster_stats_messages_received:1596127.0.0.1:7000> cluster nodes930daea84150b5fabd32a95592781b27ceab1b71 192.168.39.153:7001 master - 0 1479044139420 2 connected 5461-109228a6707d5b9269b6260315b47f300c1ab599733b7 192.168.39.153:7005 slave bdb62bb6ffce71588961f513c74b0d5a1a7145ea 0 1479044141441 6 connectedbdb62bb6ffce71588961f513c74b0d5a1a7145ea 192.168.39.153:7002 master - 0 1479044139925 3 connected 10923-1638381c884ebfc919ad293f02d797aff1033025ac27e 192.168.39.153:7004 slave 930daea84150b5fabd32a95592781b27ceab1b71 0 1479044140937 2 connected099cfc6fbb785449a8bf5369a53d21a9e127fa42 192.168.39.153:7000 myself,slave a8081e97862d9cf76c72d364f9a173187376f215 0 0 1 connecteda8081e97862d9cf76c72d364f9a173187376f215 192.168.39.153:7003 master - 0 1479044140430 7 connected 0-5460
从上边的运行结果可以看出,集群有六个节点,分别是192.168.39.153:7000、192.168.39.153:7001、192.168.39.153:7002、192.168.39.153:7003、192.168.39.153:7004、192.168.39.153:7005。对应的node-id是099cfc6fbb785449a8bf5369a53d21a9e127fa42、930daea84150b5fabd32a95592781b27ceab1b71、bdb62bb6ffce71588961f513c74b0d5a1a7145ea、a8081e97862d9cf76c72d364f9a173187376f215、81c884ebfc919ad293f02d797aff1033025ac27e、8a6707d5b9269b6260315b47f300c1ab599733b7。
然后我们删除从节点192.168.39.153:7004
127.0.0.1:7000> cluster forget 81c884ebfc919ad293f02d797aff1033025ac27eOK127.0.0.1:7000> cluster infocluster_state:okcluster_slots_assigned:16384cluster_slots_ok:16384cluster_slots_pfail:0cluster_slots_fail:0cluster_known_nodes:5cluster_size:3cluster_current_epoch:8cluster_my_epoch:7cluster_stats_messages_sent:2403cluster_stats_messages_received:1941
可以看到,删除了节点后,cluster_known_nodes显示的值就是5,如果我们输入cluster nodes会发现原先的192.168.39.153:7004节点就找不到了,因为他已经从每一个节点的记录中删除了。同事我们也看到cluster_state:ok,说明集群状态仍然是可用的。
那我们尝试着删除主节点192.168.39.153:7001看看。
127.0.0.1:7000> cluster forget 930daea84150b5fabd32a95592781b27ceab1b71OK127.0.0.1:7000> cluster infocluster_state:failcluster_slots_assigned:10922cluster_slots_ok:10922cluster_slots_pfail:0cluster_slots_fail:0cluster_known_nodes:5cluster_size:2cluster_current_epoch:8cluster_my_epoch:7cluster_stats_messages_sent:2627cluster_stats_messages_received:2165
删除了192.168.39.153:7001后集群状态就是cluster_state:fail,说明集群此时是不可用的。
我们看看redis源代码,看看forget删除节点是怎么实现的,在redis/cluster.c文件里,客户端传入的forget参数会进入clusterCommand函数
————————————————————————————————— } else if (!strcasecmp(c->argv[1]->ptr,"forget") && c->argc == 3) { // argv[2]是NODE-ID,查找 NODE-ID 对应的节点 clusterNode *n = clusterLookupNode(c->argv[2]->ptr); // node-id对应的节点不在集群中,返回错误 if (!n) { addReplyErrorFormat(c,"Unknown node %s", (char*)c->argv[2]->ptr); return;//不能删除客户端连接到的服务器自己,也不能删除自己的master } else if (n == myself) { addReplyError(c,"I tried hard but I can't forget myself..."); return; } else if (nodeIsSlave(myself) && myself->slaveof == n) { addReplyError(c,"Can't forget my master!"); return; } // 将节点添加到黑名单 clusterBlacklistAddNode(n); // 从集群中删除这个node clusterDelNode(n);//删除后的下一个服务器周期检查会执行更新状态,保存当前集群配置的操作 clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE| CLUSTER_TODO_SAVE_CONFIG); addReply(c,shared.ok); }—————————————————————————————————
我们继续看clusterBlacklistAddNode函数是如何把node加入到黑名单的
// 把黑名单中的过期节点删除,把当前node加入到黑名单里void clusterBlacklistAddNode(clusterNode *node) { dictEntry *de; sds id = sdsnewlen(node->name,REDIS_CLUSTER_NAMELEN); // 查找过期的节点并删除 clusterBlacklistCleanup(); // 把node-id节点添加到黑名单里 if (dictAdd(server.cluster->nodes_black_list,id,NULL) == DICT_OK) { id = sdsdup(id); } // 设置node的过期时间 de = dictFind(server.cluster->nodes_black_list,id); dictSetUnsignedIntegerVal(de,time(NULL)+REDIS_CLUSTER_BLACKLIST_TTL); sdsfree(id);}
下边是删除节点的关键函数,这个函数首先将所有由这个节点负责的槽位都标记成未分配,然后移除这个节点发送的下线报告,最后释放本节点对这个节点的保存,如果此节点是从节点的话,把此节点的父节点的从节点指针中删除这个节点。
void clusterDelNode(clusterNode *delnode) { int j; dictIterator *di; dictEntry *de; //删除所有向这个节点迁移和被迁移的槽,最后标记为未分配 for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) { // 取消从此节点迁移槽 if (server.cluster->importing_slots_from[j] == delnode) server.cluster->importing_slots_from[j] = NULL; // 取消向此节点迁移槽 if (server.cluster->migrating_slots_to[j] == delnode) server.cluster->migrating_slots_to[j] = NULL; // 将所有这个节点负责的槽设置为未分配 if (server.cluster->slots[j] == delnode) clusterDelSlot(j); } // 移除此节点发送的下线报告 di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); if (node == delnode) continue; clusterNodeDelFailureReport(node,delnode); } dictReleaseIterator(di); // 将节点从它的主节点的从节点列表中移除 if (nodeIsSlave(delnode) && delnode->slaveof) clusterNodeRemoveSlave(delnode->slaveof,delnode); // 释放节点 freeClusterNode(delnode);}
这样,在本地服务器看来,这个节点就被删除了。集群中的节点会周期性的交换信息,一小段时间以后,整个集群就都知道这个节点的被删除。
- redis集群实现(三)集群删除节点
- redis集群实现(三)集群删除节点
- redis集群删除节点
- redis集群删除节点
- hadoop2.6.0删除集群节点(三)
- redis-cluster集群添加节点、删除节点
- redis集群实现(二)集群添加节点
- redis集群实现(二)集群添加节点
- redis集群动态增加或者删除节点
- redis集群动态增加或者删除节点
- redis的集群,添加和删除节点
- redis集群动态增加或者删除节点
- redis集群动态增加或者删除节点
- redis linux-集群新增删除节点流程
- redis集群——删除节点
- redis集群——删除节点
- redis集群动态增加或者删除节点
- Redis集群动态添加和删除节点
- Codeforces Round #378 (Div. 2) C. Epidemic in Monstropolis 贪心+构造
- Swift 3.0 UIAlertController的使用
- 欢迎使用CSDN-markdown编辑器
- Java8 Lambda表达式教程
- 反射的简单应用2
- redis集群实现(三)集群删除节点
- 对USB同步传输feedback的一点理解
- [C++ Primer Plus]预备知识
- android动画基础(一) View动画和属性动画
- CISSP复习笔记-第3章 访问控制
- 《OpenCV》Part2 OpenCV3.1.0调用摄像头显示视频并拍照
- js原型对象与原型链
- 关于初学面向对象
- 关于SpringMVC中的国际化