10.4.1 伸缩原理

image.png

之前搭建的集群槽和数据与节点的对应关系:

image.png

如果希望加入1个节点实现集群扩容时, 需要通过相关命令把一部分槽和数据迁移给新节点:

image.png

理解集群的水平伸缩的上层原理: 集群伸缩 = 槽和数据在节点之间的移动

10.4.2 扩容集群

Redis 集群扩容操作可分为如下步骤:

  1. 准备新节点
  2. 加入集群
  3. 迁移槽和数据

1. 准备新节点

新节点建议跟集群内的节点配置保持一致,便于管理统一。准备好配置后启动两个节点命令如下:

  1. redis-server conf/redis-6385.conf
  2. redis-server conf/redis-6386.conf

启动后的新节点作为孤儿节点运行, 并没有其他节点与之通信:

image.png

2. 加入集群

采用 cluster meet 命令加入到现有集群中。在集群内任意节点执行 cluster meet 命令让6385和6386节点加入进来:

  1. 127.0.0.1:6379> cluster meet 127.0.0.1 6385
  2. 127.0.0.1:6379> cluster meet 127.0.0.1 6386

image.png

对于新节点的后续操作我们一般有两种选择:

  • 为它迁移槽和数据实现扩容
  • 作为其他主节点的从节点负责故障转移

3. 迁移槽和数据

(1) 槽迁移计划

确定原有节点的哪些槽需要迁移到新节点。迁移计划需要确保每个节点负责相似数量的槽, 从而保证各节点的数据均匀。

image.png

槽迁移计划确定后开始逐个把槽内数据从源节点迁移到目标节点:

image.png

target 和 source 写反了.

(2) 迁移数据

数据迁移过程是逐个槽进行的:

image.png

流程说明:

  1. 对目标节点发送 cluster setslot {slot} importing {sourceNodeId} 命令, 让目标节点准备导入槽的数据
  2. 对源节点发送 cluster setslot {slot} migrating {targetNodeId} 命令, 让源节点准备迁出槽的数据
  3. 源节点循环执行 cluster getkeysinslot {slot} {count} 命令, 获取 count 个属于槽 {slot} 的键
  4. 在源节点上执行 migrate {targetIp} {targetPort} “” 0 {timeout} keys {keys…} 命令, 把获取的键通过流水线 (pipeline) 机制批量迁移到目标节点, 批量迁移版本的 migrate 命令在 Redis3.0.6 以上版本提供, 之前的 migrate 命令只能单个键迁移。对于大量 key 的场景, 批量键迁移将极大降低节点之间网络 IO 次数
  5. 重复执行步骤3)和步骤4)直到槽下所有的键值数据迁移到目标节点
  6. 向集群内所有主节点发送 cluster setslot{slot}node {targetNodeId} 命令, 通知槽分配给目标节点。为了保证槽节点映射变更及时传播, 需要遍历发送给所有主节点更新被迁移的槽指向新节点

(3) 添加从节点

这时需要把节点6386作为6385的从节点,从而保证整个集群的高可用。

使用 cluster replicate {masterNodeId} 命令为主节点添加对应从节点, 注意在集群模式下 slaveof 添加从节点操作不再支持:

  1. 127.0.0.1:6386>cluster replicate 1a205dd8b2819a00dd1e8b6be40a8e2abe77b756

image.png

10.4.3 收缩集群

安全下线节点流程:

image.png

1. 下线迁移槽

6381是主节点,负责槽 (12288-16383),6384是它的从节点, 如图10-26所示。下线6381之前需要把负责的槽迁移到其他节点:

image.png

直接使用 redis-trib.rb reshard 命令完成槽迁移.

2. 忘记节点

Redis 提供了 cluster forget {downNodeId} 命令实现该功能:

image.png

image.png