10.4.1 伸缩原理
之前搭建的集群槽和数据与节点的对应关系:
如果希望加入1个节点实现集群扩容时, 需要通过相关命令把一部分槽和数据迁移给新节点:
理解集群的水平伸缩的上层原理: 集群伸缩 = 槽和数据在节点之间的移动
10.4.2 扩容集群
Redis 集群扩容操作可分为如下步骤:
- 准备新节点
- 加入集群
- 迁移槽和数据
1. 准备新节点
新节点建议跟集群内的节点配置保持一致,便于管理统一。准备好配置后启动两个节点命令如下:
redis-server conf/redis-6385.conf
redis-server conf/redis-6386.conf
启动后的新节点作为孤儿节点运行, 并没有其他节点与之通信:
2. 加入集群
采用 cluster meet 命令加入到现有集群中。在集群内任意节点执行 cluster meet 命令让6385和6386节点加入进来:
127.0.0.1:6379> cluster meet 127.0.0.1 6385
127.0.0.1:6379> cluster meet 127.0.0.1 6386
对于新节点的后续操作我们一般有两种选择:
- 为它迁移槽和数据实现扩容
- 作为其他主节点的从节点负责故障转移
3. 迁移槽和数据
(1) 槽迁移计划
确定原有节点的哪些槽需要迁移到新节点。迁移计划需要确保每个节点负责相似数量的槽, 从而保证各节点的数据均匀。
槽迁移计划确定后开始逐个把槽内数据从源节点迁移到目标节点:
target 和 source 写反了.
(2) 迁移数据
数据迁移过程是逐个槽进行的:
流程说明:
- 对目标节点发送 cluster setslot {slot} importing {sourceNodeId} 命令, 让目标节点准备导入槽的数据
- 对源节点发送 cluster setslot {slot} migrating {targetNodeId} 命令, 让源节点准备迁出槽的数据
- 源节点循环执行 cluster getkeysinslot {slot} {count} 命令, 获取 count 个属于槽 {slot} 的键
- 在源节点上执行 migrate {targetIp} {targetPort} “” 0 {timeout} keys {keys…} 命令, 把获取的键通过流水线 (pipeline) 机制批量迁移到目标节点, 批量迁移版本的 migrate 命令在 Redis3.0.6 以上版本提供, 之前的 migrate 命令只能单个键迁移。对于大量 key 的场景, 批量键迁移将极大降低节点之间网络 IO 次数
- 重复执行步骤3)和步骤4)直到槽下所有的键值数据迁移到目标节点
- 向集群内所有主节点发送 cluster setslot{slot}node {targetNodeId} 命令, 通知槽分配给目标节点。为了保证槽节点映射变更及时传播, 需要遍历发送给所有主节点更新被迁移的槽指向新节点
(3) 添加从节点
这时需要把节点6386作为6385的从节点,从而保证整个集群的高可用。
使用 cluster replicate {masterNodeId} 命令为主节点添加对应从节点, 注意在集群模式下 slaveof 添加从节点操作不再支持:
127.0.0.1:6386>cluster replicate 1a205dd8b2819a00dd1e8b6be40a8e2abe77b756
10.4.3 收缩集群
安全下线节点流程:
1. 下线迁移槽
6381是主节点,负责槽 (12288-16383),6384是它的从节点, 如图10-26所示。下线6381之前需要把负责的槽迁移到其他节点:
直接使用 redis-trib.rb reshard 命令完成槽迁移.
2. 忘记节点
Redis 提供了 cluster forget {downNodeId} 命令实现该功能: