集群收缩原理
集群收缩就是让其中一些节点安全下线。
所谓的安全下线指的是让一个节点下线之前,把其负责的所有 slots 迁移到别的节点上,否则该节点下线后其负责的 slots 就没法继续提供服务了。
收缩流程如下:
需求
前面扩容完成后,集群中共有4个主节点和4个从节点。随机找一个设备下线,这里以下线 30003 节点为例。
下线 30003 节点,首先需要把其上负责 slots 的数据分别迁移到指定的节点上,然后通知所有集群中的节点删除 30003 集群节点,最后 30003 节点关闭下线。
迁移槽位时最好让每个节点为的槽位尽量保持平均,那么计算公式为: (待迁移节点槽位数 / 现有节点数)=要迁出的槽位数。
示例:
待迁移节点槽位数 = 4096;现有节点数 = 3;结果为:1365.3333。
由于不能被整除,所以每个节点的槽位分别为:1365、1365、1366。
迁移槽位
准备开始迁移槽位,操作命令如下:
redis-cli --cluster reshard 127.0.0.1:30007 --cluster-from b9f22886f74d62e36fe308af4eb7f95dc31367ad --cluster-to 6134319b42511239b4c514111efbad5d6141dab0 --cluster-slots 4096
语法:
redis-cli --cluster reshard 已存在节点ip:端口 --cluster-from 要迁出节点ID --cluster-to 接收槽节点ID --cluster-slots 迁出槽数量
稍等片刻,等全部槽迁移完成后,查看集群状态如下:
从图上可以看到 30003 上已经不再有槽位了,同时迁移的节点会合并到 30007 节点上。
下线节点
当槽位移动完成后分别对 30003 主从两个节实施安全下线,操作命令如下:
redis-cli --cluster del-node 127.0.0.1:30003 b9f22886f74d62e36fe308af4eb7f95dc31367ad
语法:
redis-cli --cluster del-node 已存在节点IP:端口 要删除的节点ID
下线完主节点后,重复以上操作下线其原从节点。
最后如图所示:
当集群中的所有其他节点收到下线命令(cluster forget <node id> )时,会删除自己保存的 node_id 对应的节点状态,至此就完成了集群的缩容。
总结
Redis 集群扩缩容最核心的地方还是数据的迁移,扩容和缩容的最大区别:
- 数据迁移的方向;
- 扩容添加新节点后,需要向整个集群广播 slot 被新的节点负责的信息。
集群收缩下线节点时,需要向集群广播让所有节点 forget 掉下线节点,同时在数据迁移过程中,我们需要解决的很重要的问题就是数据路由问题,Redis 通过 ASK 重定向和 moved 重定向解决了该问题。
集群收缩主要分为三步:
- 迁移槽和数据
- 下线节点
- 关闭节点