*Redis CLUSTER SETSLOT 命令
CLUSTER SETSLOT 修改指定哈希槽的归属状态,是 Redis Cluster 槽迁移(resharding)和故障恢复的核心命令。
*语法
CLUSTER SETSLOT slot (IMPORTING node-id | MIGRATING node-id | NODE node-id | STABLE)
*参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slot | Integer | 是 | 哈希槽编号,范围 0 ~ 16383 |
| IMPORTING node-id | 子命令 | 条件 | 将槽标记为正在从指定节点迁入到当前节点 |
| MIGRATING node-id | 子命令 | 条件 | 将槽标记为正在从当前节点迁出到指定节点 |
| NODE node-id | 子命令 | 条件 | 将槽绑定到指定节点,完成迁移 |
| STABLE | 子命令 | 条件 | 清除槽的 IMPORTING/MIGRATING 状态,恢复稳定 |
*返回值
- OK:操作成功。
- Error:参数错误或节点不存在。
*时间复杂度
O(1)
*
*示例
*标记槽为迁出状态
> CLUSTER SETSLOT 5798 MIGRATING 67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1
OK
*标记槽为迁入状态
> CLUSTER SETSLOT 5798 IMPORTING 3c3a0c74aae0b56179ccb1a76b7850a3b1f1b26b
OK
*完成槽迁移,将槽归属转移
> CLUSTER SETSLOT 5798 NODE 67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1
OK
*取消迁移状态
> CLUSTER SETSLOT 5798 STABLE
OK
*常见错误
| 错误 | 原因 | 解决 |
|---|---|---|
| ERR Invalid slot | slot 超出 0~16383 范围 | 确保 slot 在有效范围内 |
| ERR Unknown node | 提供的 node-id 不存在 | 通过 CLUSTER NODES 确认正确的节点 ID |
| ERR Slot is already busy | 尝试将槽绑定到已有该槽的节点 | 检查槽的当前归属 |
| ERR wrong number of arguments | 缺少子命令或参数 | 补充完整的子命令 |
| ERR This instance has cluster support disabled | 未启用集群模式 | 在 redis.conf 中设置 cluster-enabled yes |
*最佳实践
- 标准迁移流程:
- 在目标节点执行:
CLUSTER SETSLOT <slot> IMPORTING <source-node-id> - 在源节点执行:
CLUSTER SETSLOT <slot> MIGRATING <target-node-id> - 使用 CLUSTER GETKEYSINSLOT 获取键名,用 MIGRATE 迁移数据
- 在源节点和目标节点都执行:
CLUSTER SETSLOT <slot> NODE <target-node-id>
- 在目标节点执行:
- MIGRATING 状态会触发
-ASK重定向:客户端访问该槽的键时,源节点返回 ASK 重定向到目标节点 - IMPORTING 状态配合 ASKING 命令使用:客户端发送 ASKING 后,目标节点才会接受该槽的写入请求
- 生产环境建议使用
redis-cli --cluster reshard工具进行自动化迁移,避免手动操作的复杂性和出错风险 - 取消迁移时,STABLE 子命令仅清除 IMPORTING/MIGRATING 标记,不迁移数据,数据仍留在原节点
*FAQ
Q1: IMPORTING 和 MIGRATING 必须同时设置吗? A: 标准迁移流程中两者都需要设置。如果只设置 MIGRATING 而不设置 IMPORTING,目标节点不会接受该槽的数据写入;如果迁移完成后没有执行 NODE 子命令,槽的所有权不会正式转移。
Q2: 可以批量迁移多个槽吗?
A: 可以,但需要逐个槽执行。生产环境推荐使用 redis-cli --cluster reshard 工具,它可以自动处理批量槽迁移和键迁移。
Q3: NODE 子命令需要在所有节点执行吗?
A: 在 Redis 3.0+ 中,只需在一个节点执行 CLUSTER SETSLOT <slot> NODE <node-id>,集群会通过 gossip 协议将槽分配信息传播到所有节点。但为确保一致性,建议在所有相关节点上执行。