容灾切换\|同城双活架构脑裂防护与VIP漂移实战指南

举报
数据库小学妹 发表于 2026/07/22 10:27:07 2026/07/22
【摘要】 一次真实机房断电引发的容灾切换复盘,拆解仲裁节点单点、VIP漂移、DNS缓存三个连环故障,以及从演练通过到生产可用的改造方案。

大家好,我是数据库小学妹 👋

凌晨两点十四分,手机把我震醒。来电显示是监控告警,接起来就听到机房值班同事的声音:"机房A断电,UPS快撑不住了,你来看下监控。"我打开面板,第一反应是松了口气。机房B的数据库确实提升成了主库,容灾切换成功了。

但这个安心只持续了三十秒。监控图上,机房B的数据库CPU飙升到百分之九十五,连接数爆满,应用端的错误日志在疯狂滚动。所有服务都在报"数据库连接超时",用户端的表现是加不了购物车、付不了款、已经提交的订单卡在"处理中"动不了。客服群里也开始炸,“大量用户投诉无法下单”“客服电话已经打不进来了”。

我一边拉网络团队进群排查,一边翻切换日志。从告警到切主库,高可用框架用了47秒,看起来很快。但从47秒之后,事情就开始不对劲了。VIP漂过去了,应用连不上。DNS更新了,用户还在访问旧地址。两台数据库都在拒绝写入,因为触发了脑裂保护。

那天晚上我们折腾了将近一个小时才恢复。后来对着切换日志一行行看,才意识到这套容灾方案在演练环境里跑得很漂亮,到了生产环境却几乎每个环节都漏了。这篇文章我复盘了整个过程,希望你们在遇到同样问题的时候,能帮大家少走弯路少踩坑。

概念对齐:容灾的核心指标

容灾这件事,核心看两个指标。RPO(恢复点目标)意思是故障后最多丢多少数据,RPO为零就是不丢数据。RTO(恢复时间目标)意思是故障后多久能恢复服务。这两个指标越低越好,但也越贵,你得根据业务重要性和预算来选。

我们这次事故涉及的架构是同城双活。同一个城市两个机房,各部署一套数据库,通过专线同步数据,延迟通常在五毫秒以内,理论上RPO可以为零、RTO分钟级。架构图看着挺完美:两个机房,一主一备,VIP做浮动地址,DNS做入口调度。但真实故障从来不是按架构图来的。

事故前的架构

出事故之前,我们的部署是这样的:机房A放主库,机房B放备库,通过同步复制保证数据一致性。一个VIP(10.0.0.100)挂在主库上,应用连接这个VIP,DNS域名解析到这个VIP。高可用框架负责监控主库状态,检测到故障后自动把VIP漂到备库,同时提升备库为主。听着没毛病吧?我也觉得没毛病,直到那天晚上出了问题。

问题一:脑裂——两边都以为自己是主库

机房A断电后,机房B和机房A之间的网络断了。B在提升为主库之前,需要确认A是真的挂了还是只是网络不通,因为如果A没挂,两边同时写入,数据就分叉了。我们的高可用框架用了一个仲裁节点来解决这个问题:当主备失联时,两边都去问仲裁节点,能联系上仲裁节点的那方升主,另一方只读。

但那天晚上,仲裁节点部署在机房A。机房A断电,仲裁节点也跟着挂了。机房B联系不上仲裁节点,不敢升主,等我们手动强制提升的时候,已经过去了十分钟。事后我查文档才发现,仲裁节点不能放在任何一个业务机房,它必须放在第三个独立的网络环境里,否则业务机房一挂,仲裁跟着挂,保护机制就变成了故障源。排查脑裂时的几个关键命令:

# 查看高可用集群状态
pcs status                  # Pacemaker+Corosync
SHOW STATUS LIKE 'wsrep%';  # Galera集群

# 查看主备复制状态
SHOW SLAVE STATUS\G
# 重点关注:Slave_IO_Running、Slave_SQL_Running、Seconds_Behind_Master

那次之后我们改了架构:三个仲裁节点分布在三个不同的网络环境,多数派投票,两个还活着就能决策。这样任何一个机房挂了,仲裁还能工作。

问题二:VIP漂移——漂过去了,应用连不上

VIP确实漂到了机房B,但应用还是连不上。我查了三层原因。

第一层,ARP缓存没更新。交换机和路由器还记着VIP对应的旧MAC地址,流量还是往机房A送。VIP漂移到新机器后,新机器需要主动发送免费ARP报文来刷新网络设备的缓存,但很多高可用框架默认不发,或者只发一次被交换机忽略了。

第二层,云平台的安全组规则没跟着VIP走。VIP切过去了,但安全组入站规则只绑定了旧IP,流量到了机房B被拦住了。

第三层,机房B的防火墙入站规则没配VIP的放行规则。VIP漂过来了,防火墙不认识,直接丢弃。

# VIP漂移后的排查步骤:

# 1. 确认VIP在当前机器上
ip addr show | grep "10.0.0.100"

# 2. 发送免费ARP刷新缓存
arping -I eth0 -c 3 -s 10.0.0.100 10.0.0.1

# 3. 检查防火墙规则
iptables -L -n | grep "10.0.0.100"

# 4. 从应用服务器测试连通性
telnet 10.0.0.100 3306

VIP漂移只是第一步,网络层的每个环节都得跟上。我们在切换脚本里加上了同步更新安全组规则和防火墙策略的步骤。

问题三:DNS延迟——你以为很快其实很慢

VIP搞定了,还有一层DNS切换。外部用户通过域名访问,域名解析到VIP,VIP切了DNS理论上也要更新。我们设的TTL是六十秒,理论上六十秒内全球DNS缓存都会刷新。但实际情况是,运营商的DNS缓存不遵守TTL,可能缓存更久,部分移动网络的用户半小时后还在访问机房A的旧IP。

我查了下资料,国内三大运营商的递归DNS服务器对TTL的遵守程度参差不齐,有的会强制缓存最低十分钟。这意味着即使你把TTL设成一秒,用户的请求到了运营商DNS那里,照样被缓存十分钟。

我们换了策略:不用DNS做故障切换,DNS只做全局流量调度,真正的主备切换靠VIP加应用层连接池的failover机制。

# 连接池多地址配置示例(HikariCP):
jdbc:mysql://10.0.0.100:3306,10.0.0.200:3306/shop
  ?failOverReadOnly=false
  &autoReconnect=true
  &connectTimeout=3000
  &socketTimeout=10000

应用连接池里维护多个数据库地址,主地址不可达时自动切到备地址,不用等DNS刷新,秒级切换。

改造后的架构

那次事故之后,我把整套容灾架构重新设计了一遍。
仲裁层三个仲裁节点分布在三个独立网络环境,多数派投票决策,不再依赖任何单一业务机房。
网络层切换脚本自动更新安全组规则和防火墙策略,VIP漂移后立即发送三次免费ARP,ARP超时从六十秒降到五秒。
应用层连接池维护主备两个地址自动failover,DNS只做全局流量调度不参与故障切换。
数据校验层切换完成后自动跑checksum对比核心表,确认数据一致后再开放写入。

改完之后,我们又做了一轮完整的容灾演练,这次不只是跑"主库正常关停"一种场景。

容灾演练场景

场景一:主库进程崩溃。数据库进程意外退出,但机器还在,看高可用框架能不能检测到并切换。
场景二:主库整机断电。模拟机房断电,看备库升主、VIP漂移、网络策略更新的完整链路。
场景三:网络分区。用iptables切断主备之间的网络,看仲裁机制能不能正确判断,不会两边同时升主。
场景四:切换中途回滚。备库升主到一半主库恢复了,看系统怎么处理,不会造成数据冲突。
场景五:数据一致性校验。切换完成后对比主备两边的数据,确认没有丢失或不一致。

每个场景跑完,记录RPO和RTO的实际值。达不到指标的,改架构、改配置、改脚本,直到跑通为止。

信创环境经验

断电事故之后不久,我参与了一个信创项目的容灾部署,发现国产数据库在容灾这块有自己的一套逻辑。KES的复制协议、脑裂处理、切换流程都有一套独立的机制,迁移之前必须针对KES的容灾能力做专项演练,不能直接套用MySQL的经验。

特别是脑裂检测的超时参数,KES有自己的一套默认配置,需要结合实际的机房距离、网络延迟、业务容忍度来重新评估。我在一个项目里做过KES的两地三中心部署,同城双活用同步复制保证RPO为零,异地灾备用异步复制做兜底。切换流程大体类似,但底层参数调优的思路不同。信创项目对RPO和RTO通常有明确的合规要求,政务系统一般要求RPO为零、RTO不超过三十分钟,这些指标在架构设计阶段就要纳入考虑,不是上线后再补的。

避坑清单

写几条实操中踩出来的经验,供参考。

演练环境不等于生产环境。演练环境的网络延迟通常很低,生产环境的跨城延迟可能是几十毫秒。超时参数必须按生产环境的实际延迟来设。演练之前先在生产环境测一遍网络延迟和带宽,我吃过这个亏。

切换脚本要自动化,别靠人工。安全组、防火墙、ARP刷新这些步骤都得写进脚本里,不能靠人工临时配。凌晨两点的状态你信不过的。

异常场景都要测。容灾演练不能只跑成功流程,网络延迟升高、部分节点失联、切换中途回滚这些异常场景都得覆盖。只有演练里踩过的坑,生产里才不会重演。

切完先校验数据,别急着开香槟。用checksum对比主备两边的核心表,确认一致再开放写入。数据不对,切得再快也是白搭。


那次断电事故之后,我在团队白板上写了一句话:"高可用架构存在的意义,不是保证不出故障,而是保证出了故障能快速恢复。"接受故障的必然性,把精力放在缩短恢复时间上,比追求"永不宕机"靠谱得多。你现在的容灾方案,真正切过一次吗?如果没有,找个时间窗试试吧。

朋友,你在容灾切换中遇到过哪些意外?欢迎在评论区聊聊。

我是数据库小学妹,咱们下篇见 👋

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。