灯下哥谭 灯下哥谭
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

灯下哥谭

灯还亮着
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL

  • Redis

    • Redis 运维知识地图:从单机到 Cluster 排障
    • Redis 常用查询操作:五种数据类型速查 + 生产环境避坑
    • Redis 集群部署
    • Redis 大 key 分析:三条排查路径怎么选
    • Redis手动进行主从切换
    • Redis集群添加节点之后数据重新均匀分配
    • Redis槽位slot解读
    • Redis Cluster 新增节点 slot 迁移卡住:"open slots" 故障复盘
      • 1. 现象
      • 2. 定位:为什么会卡在"open slots"
        • 2.1 定位步骤详解
      • 3. 修复:手动把 slot 状态切回 stable
        • 3.1 修复操作步骤
        • 3.2 自动修复工具
        • 3.3 批量修复脚本
      • 4. 验证
      • 5. 原理:Redis Cluster slot 迁移机制
        • 5.1 迁移状态机
        • 5.2 迁移完整流程
        • 5.3 中断场景分析
      • 6. 坑
      • 7. 可复用要点
      • 8. 附录:常用命令速查
    • Redis集群的创建、剔除节点与新增节点操作过程
    • Redis配置文件解读
    • redis cluster压测
    • Redis 慢查询告警与抓包分析排障脚本
    • Redis 的可用内存过高时的自动驱逐 key 策略详解
  • 高性能KV

  • TiDB

  • Elasticsearch

  • 数据管道

  • 其他数据库

  • 数据库
  • Redis
灯下哥谭
2022-03-29
目录

Redis Cluster 新增节点 slot 迁移卡住:"open slots" 故障复盘

# 1. 现象

给 Redis Cluster 加节点、做 slot 迁移(redis-cli --cluster reshard)的过程中,如果中途被打断(网络抖动、手动 Ctrl-C、迁移脚本异常退出),再执行集群健康检查会报错:

版本说明

本文基于 Redis Cluster 5.x/6.x 的 redis-cli --cluster 工具链,slot 状态机在 7.x 上未发生变化,仍适用。

redis-cli --cluster check <PUBLIC_IP>:8001

>>> Check for open slots...
[WARNING] Node <INTERNAL_IP>:8001 has slots in importing state 11763.
[WARNING] The following slots are open: 11763.
1
2
3
4
5

集群此时能正常读写(大部分 slot 状态正常),但这个 11763 slot 处于一种"悬空"状态,--cluster check 会持续报警,如果不处理,后续再做别的 reshard 操作大概率会失败或报更多冲突。


# 2. 定位:为什么会卡在"open slots"

Redis Cluster 迁移一个 slot 分两步——源节点标记为 MIGRATING,目标节点标记为 IMPORTING,等这个 slot 里所有 key 都从源节点搬到目标节点后,再把 slot 的归属正式切给目标节点(状态变回 stable)。

根因:如果迁移在"key 已经搬完但状态还没切换成 stable"或"搬到一半就中断"这个中间态被打断,slot 就会一直卡在 importing(或对应地在源节点卡在 migrating),这是 Redis Cluster 迁移协议本身的设计——它不会自动回滚或自动完成,需要人工介入确认这个 slot 到底应该属于哪个节点,再手动收尾。

# 2.1 定位步骤详解

第一步:找到"悬空"的 slot

redis-cli --cluster check <HOST>:<PORT> 2>&1 | grep -E "(importing|migrating|open slots)"
1

典型输出:

[WARNING] Node <TARGET_IP>:8001 has slots in importing state 11763.
[WARNING] Node <SOURCE_IP>:8001 has slots in migrating state 11763.
1
2

这里的 11763 就是需要人工介入的 slot。

第二步:判断 key 是否已搬空

先确认这个 slot 里的 key 是否已经搬空:

# 在目标节点(importing 状态)上检查
redis-cli -h <TARGET_IP> -p 8001 cluster countkeysinslot 11763
# 输出: (integer) 0

# 在源节点(migrating 状态)上检查
redis-cli -h <SOURCE_IP> -p 8001 cluster countkeysinslot 11763
# 输出: (integer) 0
1
2
3
4
5
6
7

0 表示 key 已经全部迁移完成,只是状态没有切换——这种情况可以直接安全收尾;如果这里不是 0,说明迁移没搬完,需要先用 redis-cli --cluster fix 或手动继续搬迁 key,不能直接强行改状态,否则会丢数据。

第三步:确认节点角色

# 查看节点状态,确认是哪个节点处于 importing 状态
redis-cli -h <ANY_NODE> -p 8001 cluster nodes | grep -E "11763|importing|migrating"
1
2

# 3. 修复:手动把 slot 状态切回 stable

# 3.1 修复操作步骤

确认 key 已搬空后(cluster countkeysinslot 返回 0),在目标节点上执行:

# 在目标节点(importing 状态)上执行
redis-cli -h <TARGET_IP> -p 8001 cluster setslot 11763 stable
OK
1
2
3

stable 是告诉这个节点"停止迁移状态、这个 slot 正式归你了"。

如果源节点上也残留了 migrating 状态,同样对源节点执行一次:

# 在源节点(migrating 状态)上执行
redis-cli -h <SOURCE_IP> -p 8001 cluster setslot 11763 stable
OK
1
2
3

# 3.2 自动修复工具

如果不确定哪个节点有问题,或者有多个 slot 卡住,可以使用 redis-cli --cluster fix 自动修复:

# 自动检测并修复悬空的 slot
redis-cli --cluster fix <HOST>:<PORT> --cluster-slots <SLOT_ID>
1
2

工具会提示你是否确认修复,输入 yes 即可。

# 3.3 批量修复脚本

如果集群中有多个 slot 卡住,可以使用以下脚本批量修复:

#!/bin/bash
# 批量修复 "open slots" 问题

HOST=$1
PORT=${2:-8001}

echo "=== 检查当前集群状态 ==="
redis-cli --cluster check ${HOST}:${PORT} 2>&1 | grep -E "(importing|migrating|open slots)"

echo -e "\n=== 尝试自动修复 ==="
redis-cli --cluster fix ${HOST}:${PORT}

echo -e "\n=== 验证修复结果 ==="
redis-cli --cluster check ${HOST}:${PORT} 2>&1 | grep -E "(OK|All 16384 slots)"
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 4. 验证

执行完修复后,运行以下命令验证集群已恢复正常:

redis-cli --cluster check <PUBLIC_IP>:8001
1

验证要点:

  1. 确认输出不再出现 open slots 的 WARNING
  2. 确认出现 [OK] All 16384 slots covered 这类总结行
  3. 所有 slot 都有明确归属、集群拓扑一致
# 验证 slot 状态的完整检查
redis-cli -h <HOST> -p 8001 cluster info | grep cluster_slots_assigned
# 应该输出: cluster_slots_assigned:16384

# 验证所有节点的槽位状态正常
redis-cli -h <HOST> -p 8001 cluster info | grep cluster_state
# 应该输出: cluster_state:ok
1
2
3
4
5
6
7

# 5. 原理:Redis Cluster slot 迁移机制

# 5.1 迁移状态机

Redis Cluster 的 slot 迁移涉及三种状态:

状态 节点角色 含义
stable 正常 slot 归属明确,不再迁移
migrating 源节点 正在将 slot 迁出,key 仍在该节点
importing 目标节点 正在接收从其他节点迁入的 key

# 5.2 迁移完整流程

  1. 启动迁移:在目标节点上执行 CLUSTER SETSLOT <slot> IMPORTING <source_node_id>
  2. 标记源节点:在源节点上执行 CLUSTER SETSLOT <slot> MIGRATING <target_node_id>
  3. 迁移 key:使用 MIGRATE 命令逐个将 key 从源节点迁移到目标节点
  4. 切换归属:所有 key 搬完后,执行 CLUSTER SETSLOT <slot> NODE <target_node_id>
  5. 状态复原:源节点和目标节点的 migrating/importing 状态自动清除,恢复 stable

# 5.3 中断场景分析

中断时机 结果 处理方式
刚执行 SETSLOT MIGRATING/IMPORTING,还未搬 key 两节点处于中间态 两端都执行 setslot stable 回滚
正在搬 key 时中断 部分 key 已搬,部分还在源节点 用 redis-cli --cluster fix 继续搬完
key 全部搬完,还未执行 SETSLOT NODE slot 悬空(importing/migrating 状态残留) 执行 setslot stable 收尾
切换归属后中断 无影响,迁移动作已完成 不需要处理

# 6. 坑

  • 不要在 key 还没搬完时就执行 setslot stable——这会导致这批未搬完的 key 在逻辑上"丢失"(既不在源节点的正常 slot 范围,也没真正进入目标节点),必须先用 cluster countkeysinslot 确认为 0。

  • 命令行里带 -a password 会触发一条安全警告(Using a password with '-a' ... may not be safe)——这是提示密码可能出现在 shell 历史/进程列表里,不是操作失败,用 --pass 从环境变量或配置文件读取密码可以避免,或使用 Redis 6.0+ 的 --no-auth-warning 选项。

  • 迁移类操作尽量用 redis-cli --cluster reshard 走官方工具链而不是纯手动逐条搬 key,工具会自动处理 migrating/importing 状态机的两端同步,减少中途中断留下悬空 slot 的概率。

  • 执行 SETSLOT <slot> STABLE 不会删除源节点上残留的 key——如果源节点上还有未迁移走的 key,执行 stable 后这些 key 会变成"孤儿 key",无法通过正常的 slot 路由访问。建议在执行 stable 前再次确认源节点的 slot 内 key 数为 0。

  • 多 slot 并发迁移时中断,修复顺序有讲究——如果有多个 slot 卡住,应先修复还在迁移中(有 key 还在搬)的 slot,最后处理完全悬空的 slot。

  • 网络分区期间的迁移状态——如果迁移过程中发生网络分区,importing 节点可能永远收不到源节点的数据,导致 slot 一直卡住。这种情况即使修复了状态,key 也可能不完整,需要结合 RDB 文件或备份进行数据核对。


# 7. 可复用要点

  1. open slots 报警的本质是迁移协议的中间态没有收尾,Redis 不会自动处理,需要人工判断并执行 setslot stable。

  2. 收尾前必须用 cluster countkeysinslot 确认目标 slot 是否已经搬空——这是唯一能安全下断言的检查点。如果返回非 0,坚持用 redis-cli --cluster fix 继续迁移流程。

  3. 优先用 redis-cli --cluster reshard 而不是手动裸命令迁移,减少人为中断留下悬空状态的概率。

  4. 修复后立即执行 redis-cli --cluster check 验证集群完整性,确保所有 16384 个 slot 都有明确归属。

  5. 生产环境建议:

    • 迁移操作安排在业务低峰期
    • 提前确认集群状态健康(无 fail 节点)
    • 准备好监控告警,迁移过程中关注 cluster_stats_messages_received{type="migrate"}

# 8. 附录:常用命令速查

场景 命令
检查集群slot状态 redis-cli --cluster check <host>:<port>
查看某节点slot数 redis-cli -h <host> -p <port> cluster countkeysinslot <slot>
查看某slot归属 redis-cli -h <host> -p <port> cluster nodes \| grep <slot>
手动设置slot状态 redis-cli -h <host> -p <port> cluster setslot <slot> stable
迁移slot归属 redis-cli -h <host> -p <port> cluster setslot <slot> node <node_id>
自动修复工具 redis-cli --cluster fix <host>:<port>
#故障复盘#Redis
上次更新: 9/11/2026

← Redis槽位slot解读 Redis集群的创建、剔除节点与新增节点操作过程→

最近更新
01
DeepSeek Harness 实战 06|学习笔记:插件、工具、技能不在同一个维度上 原创
09-11
02
DeepSeek Harness 实战 05|让两个编码 Agent 共用一份长期记忆 原创
09-09
03
DeepSeek Harness 实战 04|学习笔记:从「已知限制」里读出三处设计张力 原创
09-08
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式