Redis哨兵不执行CONFIG REWRITE,仅动态调整复制关系;下线节点需人工停服、清理redis.conf中slaveof行、检查AOF/RDB及启动参数,再验证config get slaveof返回nil。

哨兵重写配置文件时,CONFIG REWRITE 不生效?
Redis 哨兵不会主动调用 CONFIG REWRITE 重写从节点或旧主节点的配置文件。它只在故障转移后,通过 SLAVEOF(或 REPLICAOF)命令动态调整从节点的复制关系,而配置文件本身保持原样——哪怕你手动改过 redis.conf 里的 slaveof 行,重启后也会被哨兵覆盖。
这意味着:下线节点(比如旧主)如果还活着但已脱离集群,它的 redis.conf 里可能仍残留着过期的 slaveof 配置,导致重启后自动尝试连一个不存在的主节点,反复报错 Connection refused 或卡在 connecting 状态。
- 真实场景:旧主节点被降级为从节点后又被手动下线,但没清理配置,下次启动就自己连回已销毁的“前主”
- 关键区别:
SLAVEOF no one是运行时指令,不写盘;CONFIG REWRITE只保存当前运行时有效配置,但哨兵不触发它 - 兼容性注意:Redis 6.2+ 默认禁用
CONFIG命令,需在redis.conf中显式开启config-command CONFIG(或改名),否则连执行都失败
怎么安全清理下线节点的 slaveof 配置?
不能只靠哨兵,得人肉介入。核心原则是:先停服务,再改配置,再确认无残留运行时状态。
- 停掉 Redis 进程:
redis-cli -p <port> shutdown</port>,避免CONFIG REWRITE把还在内存里的错误slaveof写进磁盘 - 编辑
redis.conf,删掉或注释掉slaveof(或replicaof)行;如果用了include,检查所有被包含的文件 - 启动前用
redis-check-aof --fix和redis-check-rdb扫描持久化文件,确认里面没藏旧的复制元数据 - 启动后立刻执行
redis-cli config get slaveof,返回nil才算干净;若返回地址,说明配置没清或 AOF 里有残留命令
SENTINEL RESET 能不能让哨兵“忘记”旧节点?
能,但只影响哨兵自身的监控状态,不影响 Redis 实例本身的配置文件。它是清理哨兵内部字典的必要操作,否则哨兵会持续尝试向已下线节点发 PING,日志刷屏 Connection refused。
- 执行
redis-cli -p <sentinel-port> sentinel reset *</sentinel-port>(星号重置全部主节点)或sentinel reset <master-name></master-name> - 重置后,哨兵会重新
SENTINEL SENTINELS发现其他哨兵,并在下次SENTINEL MONITOR时重建拓扑——但前提是目标节点网络可达且redis.conf配置正确 - 常见坑:重置后立刻
SENTINEL GET-MASTER-ADDR-BY-NAME返回空,是因为哨兵需要几秒到几十秒完成一次完整发现周期,不是命令失败 - 别用
SENTINEL REMOVE后不重置:它只删监控项,哨兵缓存里仍存着该节点的 IP/端口,下次自动加回来
为什么改完配置还要检查 redis-server 启动参数?
因为 --slaveof 这类命令行参数优先级高于 redis.conf,如果启停脚本或 systemd service 文件里硬编码了 ExecStart=redis-server /etc/redis.conf --slaveof x.x.x.x 6379,改配置文件完全无效。
- 查正在运行的进程:
ps aux | grep redis,看有没有带--slaveof或--replicaof - 查 systemd 服务:
systemctl cat redis.service,重点看ExecStart行 - 查 Docker 启动命令:如果用
docker run直接起的,检查是否有--slaveof参数;K8s 则检查args:字段 - 最保险做法:统一用配置文件管理,启动命令只写
redis-server /path/to/redis.conf,彻底规避参数污染
redis.conf 更隐蔽,也更顽固。

















