notify_master脚本不执行,根本原因是VRRP状态未发生真实切换:常见于track_script检测逻辑缺陷(如未设超时、忽略退出码)、priority配置错误导致状态僵持或震荡,或健康检查误判(如Redis降级后仍响应PING)。

脚本没执行,不是权限或路径问题,而是Keepalived根本没触发notify_master/notify_backup回调——这通常意味着VRRP状态没变,或者哨兵事件没被正确捕获。
为什么notify_master脚本压根不运行
Keepalived的vrrp_instance只有在角色真正切换(即当前节点从BACKUP升为MASTER,或MASTER降为BACKUP)时,才会调用notify_master或notify_backup。但现实中常见几种“假切换”:
- 哨兵完成了
+switch-master,但Keepalived还在用旧的健康检查逻辑,比如它只检测redis-cli ping是否通,而旧主节点降级为从后仍能响应PING,导致VRRP状态卡住不动 -
track_script里写的检测命令没加超时或失败退出码判断,例如redis-cli -h 127.0.0.1 -p 6379 PING || exit 1漏了|| exit 1,脚本永远返回0,Keepalived认为服务“一直健康” - VRRP优先级配置错误:两个节点priority相同,或BACKUP节点priority高于MASTER,导致角色反复震荡,notify脚本被频繁调用甚至并发执行,最终因竞态失败
redis-cli slaveof命令执行失败的典型表现
即使notify脚本被调用了,redis-cli命令也可能静默失败。最常踩的坑是:
- 没传密码:
redis-cli -a $PASS中的$PASS为空或未导出到子shell环境,命令实际等价于redis-cli slaveof no one,Redis返回(error) NOAUTH Authentication required.但脚本没检查返回值,继续往下走 - 端口写错:
slaveof 172.18.40.222 6379写成slaveof 172.18.40.2226379(少空格),Redis解析IP时把2226379当IP段,报错(error) Invalid argument,但脚本没捕获 - 新主节点还没准备好:脚本里执行
slaveof no one后立刻执行INFO replication检查role,但Redis内部状态更新有延迟,可能返回role:slave,误判失败
如何验证VIP漂移与Redis角色同步是否真正生效
不能只看ip addr show有没有VIP,也不能只看redis-cli INFO replication | grep role,必须交叉验证:
- 在VIP所在机器上执行:
redis-cli -h 127.0.0.1 -p 6379 ROLE,确认返回1) "master"(不是"slave"或报错) - 在其他从节点上执行:
redis-cli -h,确认172.18.40.222-p 6379 INFO replication | grep master_hostmaster_host指向的是VIP地址,而非物理IP - 检查Keepalived日志:
grep "Transition to MASTER" /var/log/messages,再查紧随其后的脚本输出,例如grep "slaveof no one" /var/log/messages - 手动模拟一次切换:停掉当前MASTER的Redis进程,观察Keepalived是否在
advert_int×3秒内完成升主,并且redis-cli ROLE结果同步变更
真正危险的不是脚本不执行,而是脚本执行了但没做状态确认——比如slaveof no one返回OK,但后续没检查redis-cli INFO replication | grep connected_slaves是否≥1,也没等从节点完成全量同步就放行业务流量。这种“伪成功”比彻底失败更难排查。











