下线redis集群节点必须严格按迁槽、del-node、关进程三步执行,缺一不可;del-node报错“target node is not empty”是因为槽未清空,需验证cluster slots返回空数组且cluster nodes中该节点状态为fail或消失。

不能直接 kill 进程或停容器 —— 下线主从节点必须先迁槽、再 del-node、最后手动关进程,三步缺一不可。
为什么 del-node 会报 ERR Target node is not empty
这是最常卡住的一步。错误不是因为节点还在运行,而是因为它的槽(slot)还没清空。Redis 集群要求每个 slot 必须被且仅被一个主节点负责,del-node 命令只检查目标节点是否还持有任何 slot,只要 CLUSTER SLOTS 返回非空,就直接拒绝。
- 常见误操作:执行完
redis-cli --cluster reshard就以为迁移完成,其实只是发起请求,真正迁移需等待数据同步 + 状态切换 + 客户端重定向生效 - 验证是否真正清空:连上待下线节点执行
CLUSTER SLOTS,返回必须是空数组[];再连任意其他节点执行CLUSTER NODES,确认该节点状态为fail或已消失 - 残留 key 是隐形风险:即使 slot 已迁出,旧节点仍可能有未同步的写入(如客户端没收到 MOVED 重定向),必须手动清理:
FLUSHALL ASYNC(严禁用同步版)
迁移槽时必须用 node ID,不能填 host:port
redis-cli --cluster reshard 的 --cluster-to 参数只接受 40 位 node ID,填 127.0.0.1:7001 或域名会导致迁移“假成功”:槽在元数据中既不归属源节点也不归属目标节点,进入悬空状态。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 查目标 node ID:连任意集群节点执行
CLUSTER NODES,找 role=master 且你打算接收槽的那行,开头那串十六进制字符就是 ID(如66e1af455d385246e66ac73c8acdc7aebc4f67d9) - 批量迁移更可靠:避免交互式流程输错,用非交互参数指定,例如:
redis-cli --cluster reshard 127.0.0.1:7000 --cluster-from <old-id> --cluster-to <new-id> --cluster-slots 1365 --cluster-yes</new-id></old-id> - 槽数分配要均等:若待下线主节点负责 4096 个 slot,剩余 3 个主节点,则应分别迁入 1365、1365、1366 个(不能简单除尽,需向上取整补差)
主从节点下线顺序和 cluster forget 的实际作用
先下线从节点,再下线主节点。这不是可选项,而是防止故障转移干扰的关键步骤 —— 如果主节点先被 del-node,其从节点可能触发自动晋升,导致短暂全量复制和写服务中断。
-
del-node本质是批量执行CLUSTER FORGET:它会让所有现存节点调用cluster forget <node-id></node-id>,把目标节点加入禁用列表(有效期 60 秒),停止 Gossip 通信 - 不要手动对每个节点执行
CLUSTER FORGET:操作繁琐易漏,且禁用列表过期后节点会重新“发现”已下线节点,造成状态混乱 -
del-node成功后,必须手动在旧节点机器上执行redis-cli -p <port> shutdown</port>或杀进程,否则它仍监听端口,可能被误加入集群
最容易被忽略的是 key 清理和客户端连接池刷新:slot 迁出 ≠ 数据清空,FLUSHALL ASYNC 必须做;而客户端缓存的节点拓扑不会自动更新,必须重启应用或强制刷新连接池,否则仍有请求打到已下线节点 IP 上。










