news 2026/7/29 14:42:32

【金仓数据库征文】自动故障转移如何避免脑裂:仲裁与隔离在高可用集群中的实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【金仓数据库征文】自动故障转移如何避免脑裂:仲裁与隔离在高可用集群中的实践

文章目录

    • 每日一句正能量
    • 摘要
    • 摘要
    • 1. 背景与问题
      • 1.1 为什么自动切换会产生脑裂
      • 1.2 自动故障转移的安全目标
    • 2. 环境与数据
      • 2.1 脱敏实验拓扑
      • 2.2 演练业务数据
    • 3. 复现过程
      • 3.1 基线验证
      • 3.2 场景一:仅切断主备通信
      • 3.3 场景二:主库自身网络故障
      • 3.4 场景三:仲裁节点不可用
      • 3.5 场景四:旧主假死
      • 3.6 场景五:网络抖动
    • 4. 方案实施
      • 4.1 仲裁:用多数派决定写入资格
      • 4.2 隔离:先确保旧主不能写
      • 4.3 候选备库选择
      • 4.4 访问层切换
      • 4.5 旧主恢复
    • 5. 结果对比
      • 5.1 RTO 实测
      • 5.2 RPO 实测
    • 6. 风险与复盘
      • 6.1 仲裁节点自身成为单点
      • 6.2 隔离脚本失效
      • 6.3 超时设置导致误切换
      • 6.4 同步模式与 RPO 的权衡
      • 6.5 检查清单
    • 总结

每日一句正能量

“当你能将生命的一切经历都视为成长的养分,便终于获得了内在的、不可动摇的从容。”
不筛选、不抗拒,连痛苦、失败、失去都被纳入“养分”的范畴。不依赖外部境遇的好坏来决定内心的稳定。不再与生活对抗,而是与一切遭遇合作。

摘要

本文以生产级高可用集群为背景,讨论自动故障转移中最危险的异常之一——脑裂。文中给出可落地的仲裁、隔离、故障注入、RTO/RPO 实测和检查清单。

摘要

自动故障转移的目标并不是“尽快把备库升为主库”,而是在故障、网络分区和监控误判同时出现时,仍能证明集群中只有一个节点具备写入资格。没有仲裁与隔离的自动切换,本质上只是把人工风险改成自动化风险:切换速度可能更快,但一旦旧主仍在对外写入,就会形成两个主库,各自产生业务流水,后续很难通过普通增量同步无损合并。

本文以一个两数据节点加独立仲裁节点的高可用集群为例,设计主备互联中断、主库外网中断、仲裁节点故障、旧主假死和网络抖动五类故障注入。实施方案遵循三个原则:多数派决定写入资格、提升新主之前先隔离旧主、无法确认安全时宁可停写而不是冒险双写。演练结果通过业务写探针、复制位置、订单流水、摘要校验和时间线记录,分别计算 RTO 与 RPO,并验证故障恢复后旧主只能以备库身份重新加入。

1. 背景与问题

1.1 为什么自动切换会产生脑裂

正常状态下,主库承担写入,备库持续接收并回放日志。守护进程通过数据库连接、心跳和环境检查判断节点是否健康。当主库实例真正停止时,备库提升通常没有争议;困难出现在“看不见对方”而不是“对方已死亡”的场景。

例如,主库与备库之间的复制网络断开,但主库仍能接受应用连接;备库侧守护进程发现主库不可达,误以为主库失效并触发提升。此时:

  • 原主库仍在机房 A 接收新订单;
  • 新主库在机房 B 接收另一部分订单;
  • 两边都认为自己是合法主库;
  • 主键、账户余额、库存和流水开始分叉。

这就是脑裂。它不是简单的“复制延迟”,而是产生了两个不可自动合并的写入历史。对订单、支付和账务系统而言,脑裂造成的损失往往高于短时间停机。

1.2 自动故障转移的安全目标

本次方案把安全目标写成可验收的约束,而不是模糊描述:

  1. 任一时刻,集群中可接受业务写入的数据库节点数量不超过一个。
  2. 新主提升前,必须确认旧主已经停止服务、失去网络或被 FENCE。
  3. 无法获得仲裁多数派时,节点不得自行提升。
  4. 故障恢复后的旧主不得直接以主库身份启动。
  5. 每次切换必须能计算 RTO、RPO,并留下完整时间线。

2. 环境与数据

2.1 脱敏实验拓扑

角色节点位置说明
数据库节点db-a数据中心 A初始主库
数据库节点db-b数据中心 B同步或优选同步备库
仲裁节点arb-c独立故障域 C只参与投票,不承载业务数据
访问入口db-vip / 代理双中心将写流量指向唯一主库
监控系统monitor独立管理区记录心跳、切换与业务恢复时间

KingbaseES 高可用集群由主库、备库与守护进程组成,守护进程负责状态检查和故障处理;官方资料还说明网络故障容易造成脑裂,集群可通过信任网关等方式辅助判断本机网络是否异常。正式部署时应以当前版本手册和实际组件能力为准。

2.2 演练业务数据

为了测量 RPO,不能只看数据库进程是否启动,而要持续写入带序号的业务流水。本文使用ha_drill_order表记录:

  • 连续订单号;
  • 演练批次号;
  • 提交时间;
  • 实际写入节点;
  • 业务载荷摘要。

压测程序每秒写入 100~500 条,发生故障时继续请求,记录成功、失败和重试结果。这样可在切换后检查订单号缺口、重复写入及两个节点是否曾经同时成功写入。

3. 复现过程

3.1 基线验证

演练前先确认:

  • 主库可写,备库只读;
  • 复制状态正常,回放延迟在阈值内;
  • 仲裁节点与两个数据库节点均可达;
  • 访问入口只指向当前主库;
  • FENCE、远程停库或网络隔离脚本已在维护窗口验证;
  • 业务写探针、对账脚本和时间同步均正常。

基线不健康时禁止故障注入。否则演练结果无法区分是方案问题还是既有故障。

3.2 场景一:仅切断主备通信

阻断 db-a 与 db-b 之间的复制和心跳端口,但保留两边到应用网络及仲裁节点的连接。这个场景最能暴露“仅靠节点互相心跳”的风险。

错误实现会出现:db-a 继续写,db-b 因看不到 db-a 而提升,形成双主。正确实现应由仲裁多数派决定哪一侧继续服务,少数派主动停止数据库写入或退出服务入口。

3.3 场景二:主库自身网络故障

隔离 db-a 到信任网关、应用网络和仲裁节点的连接,但 db-a 本机数据库进程仍在运行。此时 db-a 应判断是“本机网络异常”,而不是错误地认为其他节点全部故障。保护动作包括停止对外服务、关闭写入口或执行节点隔离。

3.4 场景三:仲裁节点不可用

停止 arb-c 后再模拟数据库节点间网络异常。由于无法形成可靠多数派,系统应进入保护模式:保持当前已确认主库,或停止自动提升;不能让两个节点分别自选为主。

3.5 场景四:旧主假死

模拟数据库进程无响应、磁盘长时间阻塞或操作系统卡顿,但节点电源仍开、网络时断时续。仅执行“提升备库”是不够的,新主提升前必须确认旧主已被停库、断网、断电或由 FENCE/STONITH 隔离。

3.6 场景五:网络抖动

持续注入延迟、丢包和短时断连。若超时阈值过低,集群会频繁切换;若过高,RTO 又会被拉长。因此应通过多轮实验确定心跳间隔、连续失败次数、切换冷却时间和回切抑制时间。

4. 方案实施

4.1 仲裁:用多数派决定写入资格

两节点集群最大的问题是出现网络分区时双方票数相同。增加独立仲裁节点后,形成奇数票:

  • db-a 与 arb-c 可达:db-a 获得多数派;
  • db-b 与 arb-c 可达:db-b 获得多数派;
  • db-a 与 db-b 可达但仲裁不可达:维持既有主从,不随意提升;
  • 单个数据库节点与其他节点均隔离:该节点失去写入资格。

仲裁节点应部署在独立故障域,不能与任一数据库节点共享同一台主机、同一交换机或同一电源故障点。仲裁服务也要监控,否则“有仲裁配置”不等于“仲裁真实可用”。

4.2 隔离:先确保旧主不能写

仲裁解决“谁应该成为主库”,隔离解决“旧主是否真的失去写能力”。常见隔离方式包括:

  • 远程停止数据库服务;
  • 将旧主从业务 VLAN 或负载均衡中摘除;
  • 通过 IPMI、云主机 API 或电源控制执行 FENCE;
  • 共享存储场景使用 STONITH 保障资源唯一所有者;
  • 撤销旧主的写入 VIP、路由或代理注册。

安全顺序应是:

  1. 确认故障与仲裁结果;
  2. 执行旧主隔离;
  3. 验证旧主写探针失败;
  4. 选择回放位置最优且健康的备库;
  5. 提升新主;
  6. 更新访问入口;
  7. 验证业务恢复。

任何“先提升、后慢慢隔离”的流程都扩大了双写窗口。

4.3 候选备库选择

多备库环境不能只按节点名称固定提升。应综合判断:

  • WAL 接收和回放位置;
  • 当前复制状态;
  • 复制延迟;
  • 数据目录、磁盘和文件系统健康;
  • 是否具备多数派;
  • 是否能够被应用访问;
  • 是否存在长时间恢复或损坏告警。

在同步复制模式下,RPO 可以接近零;异步复制下,仍需根据故障瞬间的发送、接收和回放差距计算实际数据窗口。不能把“自动切换成功”直接等同于“零数据丢失”。

4.4 访问层切换

数据库提升完成不代表业务已经恢复。还需处理:

  • VIP 漂移;
  • DNS 缓存;
  • 数据库代理主节点刷新;
  • 连接池失效连接清理;
  • 事务重试与幂等控制;
  • 只读/读写路由更新。

应用重试必须有上限并具备幂等键,否则切换期间的超时重试可能造成重复订单。业务恢复时间点应以真实接口成功为准,而不是以数据库提升命令返回为准。

4.5 旧主恢复

旧主重新联网后,不允许直接恢复成主库。标准步骤是:

  1. 保持业务入口隔离;
  2. 确认时间线和分叉点;
  3. 判断是否需要重新构建;
  4. 以备库身份从新主同步;
  5. 对账通过后加入集群;
  6. 观察稳定窗口后才恢复读流量。

若脑裂已经发生,应冻结两边写入,按业务流水确定权威数据源并制定专项合并方案,不能直接让两端互相覆盖。

5. 结果对比

本文以三轮脱敏实验展示记录方式,数值仅为示例。

方案故障发现旧主隔离新主提升与路由业务 RTO实测 RPO脑裂结果
仅心跳、无仲裁15 秒未完成35 秒50 秒无法可信计算出现双写
有仲裁、无强隔离15 秒45 秒25 秒85 秒0~2 秒存在短暂风险
仲裁 + FENCE + 路由门禁12 秒8 秒18 秒38 秒0~1 秒未发生脑裂

对比说明一个容易忽略的事实:最短 RTO 不一定是最安全方案。若为了追求几秒切换而省略旧主隔离,可能用极短停机换来不可逆的数据分叉。更合理的目标是先保证写入唯一性,再持续压缩检测、隔离、提升和应用恢复时间。

5.1 RTO 实测

RTO 按下列时间线计算:

  • T0:故障注入;
  • T1:监控告警;
  • T2:旧主隔离完成;
  • T3:新主提升完成;
  • T4:应用首个关键写接口成功;
  • T5:业务对账完成。

严格的业务 RTO 取T4 - T0。若业务要求“对账通过才算恢复”,则采用T5 - T0。报告中必须说明口径,避免只统计数据库提升时间。

5.2 RPO 实测

RPO 至少使用两种方式交叉验证:

  1. 时间窗口:比较故障前最后确认提交时间与新主最后连续可见时间;
  2. 流水缺口:检查连续订单号、消息偏移量或业务版本号;
  3. 摘要对账:比较数量、金额、状态分布和逐批摘要;
  4. 客户端确认:核对已向客户端返回成功但新主不存在的交易。

只有数据库行数相等并不能证明 RPO 为零,重复提交、状态回退和跨表不一致也必须检查。

6. 风险与复盘

6.1 仲裁节点自身成为单点

仲裁节点不承载业务数据,但其故障会影响自动切换决策。应至少保证:

  • 独立故障域;
  • 服务自动拉起;
  • 容量和磁盘告警;
  • 时间同步;
  • 多路径网络或清晰的降级策略;
  • 定期验证投票状态。

6.2 隔离脚本失效

FENCE 设备、云 API 凭证、IPMI 密码或远程命令可能长期未使用而失效。建议每季度在维护窗口验证一次,并将“隔离成功”作为自动提升的前置条件,而不是仅记录告警后继续切换。

6.3 超时设置导致误切换

超时阈值应依据真实网络 RTT、抖动、磁盘延迟和数据库恢复时间设定。过低会误切换,过高会增加 RTO。建议使用历史监控的 P99 延迟加安全余量,并设置连续失败次数与冷却时间。

6.4 同步模式与 RPO 的权衡

实时同步有助于降低 RPO,但会增加提交路径对网络和备库性能的依赖。异步模式可保持主库写入吞吐,却无法承诺故障时零丢失。应按业务等级分别配置,不应把所有系统套用同一模式。

6.5 检查清单

部署前

  • 仲裁节点位于独立故障域;
  • 数据库节点、仲裁节点和信任网关地址正确;
  • FENCE/停库/断网方式至少一种可验证;
  • 主备时间同步和证书、密钥有效;
  • 应用连接串、代理和 VIP 具备切换能力;
  • 写接口具备幂等键。

演练前

  • 复制状态健康,延迟低于门槛;
  • 备份与回退方案可用;
  • 业务写探针和时间线表已启动;
  • 明确暂停条件和人工接管人;
  • 记录主备位置、连接数和业务基线。

演练中

  • 逐项记录 T0~T5;
  • 确认旧主隔离后再提升;
  • 验证同一时间仅一个节点写入成功;
  • 检查新主读写、序列、任务和权限;
  • 监控连接池重连、错误率和重试量。

演练后

  • 计算并复核 RTO、RPO;
  • 完成数量、金额、状态和流水对账;
  • 旧主以备库方式重建;
  • 清理临时规则与测试数据;
  • 更新阈值、脚本和应急预案;
  • 保存日志、截图与个人复盘。

总结

自动故障转移避免脑裂的核心,不是某一条切换命令,而是一条不可绕过的安全链:健康检查发现异常,仲裁确认多数派,隔离剥夺旧主写权限,再提升新主并切换业务入口。其中任何一步缺失,都可能让“高可用”变成“双主高风险”。

真正可信的高可用方案必须通过故障注入证明:主备互联中断、主库网络故障、仲裁失效、旧主假死和网络抖动时,集群仍然最多只有一个写主;还必须用业务流水实测 RTO 与 RPO,而不是只引用产品能力值。高可用演练的目标不是追求一次漂亮的秒级切换,而是形成可重复、可审计、可回退的生产保障流程。

转载自:https://blog.csdn.net/u014727709/article/details/163271002
欢迎 👍点赞✍评论⭐收藏,欢迎指正

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/29 14:42:32

基于改进MOPSO算法的电力系统储能优化配置

1. 项目背景与核心挑战 在电力系统规划中,储能系统的选址与定容是个经典的多目标优化问题。33节点系统作为电力系统分析的标准测试案例,常被用来验证各类算法的有效性。传统方法往往将选址和定容分开处理,导致整体方案次优。而多目标粒子群算…

作者头像 李华
网站建设 2026/7/29 14:41:53

三阶十二步工业AI小模型训练实战 · 第12篇

工业时序窗口怎么定: 观察长度、步长、事件对齐与多尺度特征 窗口不是切片参数,而是模型观察历史、承担延迟和定义样本独立性的合同 作者:黄山 | 专栏序号:12 / 30 | 阅读时间:约25分钟 图1 同一台设备既有毫秒级冲击、分钟级工况,也有天级退化趋势;窗口设计决定…

作者头像 李华
网站建设 2026/7/29 14:41:50

Midscene.js终极指南:如何用自然语言彻底改变UI自动化测试

Midscene.js终极指南:如何用自然语言彻底改变UI自动化测试 【免费下载链接】midscene AI-powered, vision-driven UI automation for every platform. 项目地址: https://gitcode.com/GitHub_Trending/mid/midscene Midscene.js是一款革命性的AI驱动、视觉感…

作者头像 李华
网站建设 2026/7/29 14:41:33

JAVA-api-ArrayListMath

集合: 长度可变的容器 ArrayList: package APIlearn;import java.util.ArrayList;public class ArrayLIstTest {public static void main(String[] args) {int[] arrnew int[3];//无限制集合里面可以存储任意类型的数据ArrayList listnew ArrayList()…

作者头像 李华
网站建设 2026/7/29 14:41:31

超级电容备用电源设计:从原理到实战的电路方案与避坑指南

1. 项目概述:为什么是超级电容?聊到备用电源,大家脑子里蹦出来的第一个词多半是“蓄电池”,铅酸、锂电,这些老朋友我们太熟了。但最近几年,尤其是在一些对可靠性、响应速度和循环寿命要求近乎苛刻的场合&am…

作者头像 李华
网站建设 2026/7/29 14:38:08

macOS终极Windows程序运行方案:Whisky完全指南

macOS终极Windows程序运行方案:Whisky完全指南 【免费下载链接】Whisky A modern Wine wrapper for macOS built with SwiftUI 项目地址: https://gitcode.com/gh_mirrors/wh/Whisky 在macOS上运行Windows程序不再是难题!Whisky作为一款基于Swift…

作者头像 李华