八股:redis集群模式中的槽迁移
·
秋招在即,大家背八股的时候,心里会不会有些疑惑。集群模式中的槽,如果遇到节点挂掉?新增节点?的时候 会触发怎样的场景?

一、Redis 集群模式与槽的关系
- 槽的定义
-
- Redis 集群将整个 key 空间(2^32)划分成 16384 个 slot。
- 每一个 key 通过
CRC16(key) % 16384算出它属于哪个 slot。 - 这些 slot 分布在不同的节点上,由节点来管理。
- 为什么要有槽
-
- 槽是 逻辑分片的中间层,避免直接绑定 key 到节点。
- 好处是:增加/减少节点时,只需迁移 slot,不用一个个迁移 key。
二、槽迁移的典型场景
- 新增节点
-
- 集群本来有 N 个节点,槽分布均匀。
- 现在加了一个新节点,为了让它分担数据,就需要 把部分槽迁移到新节点。
- 节点宕机 / 下线
-
- 如果是从节点宕机,影响不大,可以通过重新同步。
- 如果是主节点宕机且没有可用从节点,会导致一部分槽不可用。
- 如果修复后恢复节点,可能需要重新迁移槽。
- 负载均衡
-
- 某些节点压力过大(存的数据多/访问频繁),需要迁移部分槽到负载较轻的节点上。

三、槽迁移的工作机制
- 槽的状态
-
stable:槽正常工作。migrating:槽正在从本节点迁移到其他节点。importing:槽正在被其他节点迁入。node:槽已属于该节点。
- 迁移的核心操作
-
- 标记槽迁移:源节点标记该槽为 migrating,目标节点标记该槽为 importing。
- 迁移 key:源节点逐个将槽中的 key 用
MIGRATE命令迁移到目标节点。
MIGRATE会把 key 及其 TTL 一并传输到目标节点,并从源节点删除。 - 更新槽分配:当该槽下所有 key 都迁移完成,整个集群会更新槽映射表,槽正式属于目标节点。
- 迁移过程中的访问
-
- 如果客户端在迁移过程中访问了槽的 key:
-
-
- 源节点会返回
ASK重定向,提示客户端去目标节点查询。 - 客户端收到
ASK后,会先向目标节点发送ASKING,再发送实际命令。
- 源节点会返回
-
-
- 因此迁移期间客户端仍然可以读写,只是有短暂的重定向。
四、槽迁移的详细步骤(以新增节点为例)
假设原来有 3 个节点(A、B、C),现在新增 D 节点:
- 使用
redis-cli --cluster reshard工具执行槽迁移: -
- 指定迁移的目标节点(D)。
- 指定要迁移多少槽(比如 5000 个)。
- 从源节点(A、B、C)平均取一些槽分配给 D。
- 工具会自动执行:
-
- 标记 A、B、C 中对应的槽为
migrating,D 中对应槽为importing。 - 循环迁移槽中的 key(逐个调用
MIGRATE)。 - 完成后,更新槽映射表,让 D 正式接管这些槽。
- 标记 A、B、C 中对应的槽为
- 客户端视角:
-
- 在迁移期间访问数据时,可能会收到
ASK重定向。 - 迁移完成后,D 节点接管槽,客户端路由表更新。
- 在迁移期间访问数据时,可能会收到
五、槽迁移中的异常情况

- 源节点宕机
-
- 如果源节点在迁移中宕机,部分 key 没迁完。
- 目标节点仍然处于
importing状态,这会导致某些 key 访问出错。 - 修复办法:手动重新迁移剩余的 key,或者使用
redis-cli --cluster fix工具修复槽分配。
- 目标节点宕机
-
- 如果目标节点宕机,迁移任务会中断。
- 源节点仍然在
migrating状态。 - 恢复后需要重新导入。
- 迁移失败/中断
-
- 可以通过
CLUSTER SETSLOT手动调整槽的状态。 - 比如:
CLUSTER SETSLOT <slot> NODE <node_id>强制指定槽属于某个节点。
- 可以通过
六、槽迁移工具
- redis-cli --cluster reshard
-
- 官方推荐,自动化操作。
- 手动迁移(更灵活但麻烦):
-
CLUSTER SETSLOT <slot> MIGRATING <target_id>CLUSTER SETSLOT <slot> IMPORTING <source_id>MIGRATE一个个迁移 key。CLUSTER SETSLOT <slot> NODE <target_id>完成分配。
更多推荐

所有评论(0)