Redis跨机房容灾不能依赖哨兵或纯主从,因网络延迟高易致脑裂或误切;必须用Keepalived结合redis-cli健康检测、角色切换脚本、repl-diskless-sync等严格配置实现可控切换。

跨数据中心的 Redis 容灾切换,不能靠 Redis 自身主从或哨兵实现——哨兵要求多数派通信,跨 DC 网络延迟高、丢包多,sentinel failover 极易误判或卡死;纯主从又无自动故障识别能力。必须引入外部健康探测与 VIP 控制机制,Keepalived 是最轻量、最可控的选择。
Keepalived 的 vrrp_script 必须检测 Redis 实例连通性而非进程存活
很多人直接用 killall -0 redis-server 或 ps aux | grep redis 判断服务“活着”,这会导致严重误切:Redis 进程在,但已卡死、无法响应命令、主从复制中断、或因内存满被 OOM kill 后残留僵尸进程。
- 正确做法是用
redis-cli -h <code>127.0.0.1-p6379-ayourpassping + 超时控制(如timeout 2)作为检测命令 - 脚本返回非 0 时,Keepalived 才触发状态降级;建议加
weight -5配合rise 3 fall 2防抖 - 若 Redis 启用了
requirepass,检测脚本中必须带-a参数,否则PING返回NOAUTH,被判定为失败 - 跨 DC 场景下,检测脚本还应检查主从同步状态:
redis-cli info replication | grep "master_link_status:up"(仅对 Slave 节点启用该检查)
双机房 VIP 漂移必须配合 redis-cli 的 role 切换脚本
Keepalived 只管 IP 归属,不管 Redis 角色。VIP 漂到 B 机房后,B 机房的 Redis 必须立刻从 slave 切成 master,否则客户端连上 VIP 却写不进数据。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 在
vrrp_instance的notify_master中调用切换脚本,例如:notify_master "/etc/keepalived/redis_role_switch.sh master" - 脚本内需执行:
redis-cli -h 127.0.0.1 -p 6379 -a $PASS slaveof no one(升主),并确认返回OK - 同理,
notify_backup中执行:redis-cli -h 127.0.0.1 -p 6379 -a $PASS slaveof <code>172.18.40.2226379(降从),其中 IP 应为 A 机房当前 VIP - 注意:所有
slaveof命令必须显式指定端口,否则默认 6379 可能掩盖配置错误
跨 DC 数据同步延迟导致脑裂,必须禁用 auto-aof-rewrite-on-bgsave-error 和开启 repl-diskless-sync
当 A 机房短暂网络分区恢复后,若未等 B 机房数据完全同步就切回,会丢数据;更危险的是,两边同时写入,产生不可逆冲突。
- 在两机房 Redis 配置中,强制设置
repl-diskless-sync yes,避免全量同步时磁盘 IO 拖慢进度 - 关闭
auto-aof-rewrite-on-bgsave-error yes,防止子进程失败导致 AOF 阻塞,进而阻塞主从同步 - 关键约束:B 机房升主后,A 机房节点恢复时,**不能自动重连同步**,必须人工确认 B 机房
INFO replication中master_repl_offset≥ A 机房当前 offset,再手动执行slaveof - 建议在切换脚本末尾写入时间戳和 offset 到本地文件(如
/var/run/redis_last_failover.offset),便于事后比对
Keepalived 的 vrrp_instance 优先级配置极易引发单边抢占
常见错误是把 A、B 机房的 priority 都设成 100,或只差 1,导致网络抖动时 VIP 频繁来回漂移。
- A 机房(主中心)设
priority 110,B 机房(容灾中心)设priority 90,差值 ≥ 20,留出足够缓冲空间 - 必须配置
advert_int 2(通告间隔 2 秒),避免跨 DC 网络延迟导致误判 MASTER_DOW N - 禁用
preempt_delay—— 容灾场景下,B 机房接管必须零延迟,不能等 30 秒才生效 - 所有
vrrp_instance必须使用相同virtual_router_id,否则根本无法形成 VRRP 组
真正难的不是让 VIP 漂过去,而是确保漂过去之后 Redis 真的能写、数据不丢、恢复时不冲突。每个环节都要有可验证的反馈,而不是依赖“脚本跑完了就以为成功了”。尤其是跨 DC 场景,网络不可信,一切状态变更都得靠 redis-cli info 和日志双重确认。

















