)
开篇用 Keepalived 做高可用最怕的不是主挂了切不过来而是两台同时认为自己才是 Master——这就是脑裂Split Brain。脑裂一旦发生VIP 被两台机器同时持有流量被撕成两半数据库双写、缓存双份、服务互相打架后果比不切换还严重。本文作为 Keepalived 系列完结篇把脑裂这件事讲透它怎么发生的、有什么危害、怎么检测、怎么防。一、脑裂是怎么发生的回顾 VRRP 的机制详见系列第 2 篇Master 每advert_int秒发一次心跳通告Backup 通过收不到通告就抢占 VIP来实现故障转移。问题就出在这个收不到就抢占上——它只能说明心跳断了无法区分两种完全不同的情况情况 AMaster真的宕机了 → 该切换正确。情况 BMaster还活着但心跳链路断了网卡down、交换机故障、组播被禁、防火墙拦截→ Backup 误判 Master 死了也去抢 VIP。情况 B 就是脑裂Master 和 Backup 都以为对方挂了于是同时持有 VIP、同时对外服务。心跳链路中断交换机/网卡/组播被禁------------------------------------------| |--------------- ---------------| node1 MASTER | 心跳互不可见 | node2 MASTER || 持 VIP 100 | ---------X---------- | 也抢到 VIP100 || 对外提供服务 | | 对外提供服务 |---------------- ----------------二、脑裂的典型触发场景场景说明心跳网卡/交换机故障业务网卡和心跳网卡共用业务网卡down了但系统活着组播被禁/被丢弃云服务器、部分交换机默认禁组播心跳收不到防火墙拦截 VRRP安全策略拦截了协议 112 的组播报文网络抖动高延迟/丢包导致 Backup 连续超时误判两台配置不一致virtual_router_id 或 auth_pass 不一致导致心跳互相不认其中业务网卡和心跳网卡共用是最常见隐患——业务卡一堵心跳也跟着断脑裂概率飙升。三、脑裂的危害为什么必须重视脑裂的危害取决于后面的业务业务脑裂后果Web 无状态两台同时持 VIP负载被分流服务错乱但未必致命MySQL / 缓存双写数据冲突、缓存双份数据损坏难以恢复消息队列重复消费、消息丢失网关/认证会话错乱、重复登录对有状态服务脑裂几乎是灾难性的。所以生产环境脑裂必须检测 防御双管齐下。四、如何检测脑裂4.1 人工排查事发时bash# 两台都执行看 VIP 是否同时存在ip addr show eth0 | grep 192.168.1.100# 两台同时出现该 IP → 脑裂发生4.2 看日志bash# 两台都看若都出现 Entering MASTER STATE → 脑裂tail -f /var/log/messages | grep -i Entering MASTER4.3 自动检测脚本推荐创建/opt/check_split_brain.sh在第三方或两节点互相定期执行bash#!/bin/bashVIP192.168.1.100LOCAL_IP192.168.1.11 # 本机 IPPEER_IP192.168.1.12 # 对端 IPALERT_EMAILadminexample.com# 本机是否持有 VIPHAS_LOCAL$(ip addr show eth0 | grep -c $VIP)# 对端是否持有 VIP能 ping 通才算活着if ping -c 1 -W 1 $PEER_IP /dev/null 21; thenHAS_PEER1elseHAS_PEER0fi# 关键判定本机和对端都持有 VIP对端还活着 脑裂if [ $HAS_LOCAL -ge 1 ] [ $HAS_PEER -eq 1 ]; thenecho $(date) SPLIT BRAIN detected! VIP$VIP /var/log/split_brain.log# 告警邮件 / 短信 / 钉钉webhookecho Split brain on $LOCAL_IP | mail -s KEEPALIVED SPLIT BRAIN $ALERT_EMAILexit 1fiexit 0配合 cron 每分钟执行bashecho * * * * * /opt/check_split_brain.sh /var/spool/cron/root检测脚本放在第三个节点最稳妥两节点互相检测可能因网络断裂而互相 ping 不通无法判断。也可用一套独立的仲裁线如机房带外管理口做 ping 源。五、如何防御脑裂核心实操Keepalived 自身对脑裂的防御能力有限真正的防脑裂需要组合拳5.1 心跳隔离业务网卡与心跳网卡分离最有效不要让 VRRP 心跳和业务流量走同一张网卡。让心跳走独立/带外网络confvrrp_instance VI_1 {state MASTERinterface eth1 # 心跳专用网卡独立网络...}这样即使业务卡eth0down 了心跳eth1仍通不会误判。5.2 云环境强制单播避免组播被弃导致的误判confunicast_src_ip 10.0.0.11unicast_peer {10.0.0.12}详见系列第 2、3 篇云环境几乎必用单播。5.3 健康检查 降低误判延长判定窗口confvrrp_script chk_net {script /etc/keepalived/check_net.shinterval 2fall 3 # 连续3次失败才判定抗网络抖动rise 2weight 0 # 失败直接放弃Master不靠减分更严格}fall 3让节点连续多次收不到心跳才判定主失效减少因单次抖动引发的误判抢占。5.4 优先级错开 非抢占priority 严格唯一150 / 100避免平票生产用nopreempt减少主恢复时来回切换的抖动窗口。5.5 仲裁 / fencing数据库等高危场景对 MySQL 等有状态服务Keepalived 不够必须加仲裁用 MHA / Orchestrator 这类专业的选主机制或引入fencing隔离检测到脑裂时强制隔离其中一台如通过 IPMI 关机、SNMP 关闭网卡保证同一时刻只有一台可写。六、脑裂处理流程应急预案一旦确认脑裂按以下顺序处置先止血再恢复1. 确认两台状态ip addr show eth0 | grep VIP 两台都看2. 立即隔离其中一台止血保留数据完整的一台- 方式A停掉备机 keepalivedsystemctl stop keepalived- 方式B有状态服务关掉一台的服务/网卡systemctl stop mysqld # 或 ip link set eth0 down3. 保留数据最新/逻辑正确的一台继续对外VIP 保留在这台4. 修复故障源交换机、网卡、组播、防火墙配置5. 恢复被隔离的一台重新加入集群确认心跳恢复6. 确认只有一台持 VIP业务恢复铁律有状态服务脑裂时先确保一台独占、数据一致再谈恢复宁停业务不乱双写。七、防脑裂自检清单上线前逐项确认[ ] 心跳是否走独立网卡/网络最有效[ ] 云环境是否已用单播替代组播[ ] priority 是否严格唯一[ ] 是否加了fall 2~3抗抖动[ ] 是否需要nopreempt减少来回切换[ ] 是否部署了脑裂检测脚本 告警第三方节点最稳[ ] 有状态服务是否有仲裁/fencing 机制八、总结一句话Keepalived 的收不到心跳就切换机制天生无法区分主挂了和心跳断了这就是脑裂的根源。防御思路分三层减少误判心跳隔离、单播、抗抖动参数。检测告警第三方节点跑脑裂检测脚本第一时间发现。仲裁止血有状态服务上 fencing脑裂时强制隔离一台。Keepalived 是把双刃剑——用得好是高可用的利器用不好无视脑裂是高可用的灾难。配置之前先想清楚脑裂怎么办这才是一个成熟运维的素养。本文为 Keepalived 高可用系列完结篇第 6 篇。全系列回顾① KeepalivedNginx 实战 → ② VRRP 原理篇 → ③ 配置与排障 → ④ KeepalivedMySQL 主从 → ⑤ KeepalivedLVS 四层负载均衡 → ⑥ 脑裂专题。