数据库高可用

场景

某天凌晨,数据库主节点宕机。

事件:
- 主数据库服务器硬件故障
- 所有写操作失败
- 从库无法同步
- 系统部分不可用

影响:
- 用户注册失败
- 订阅更新失败
- 日志记录失败
- 持续时间:2 小时(人工处理)

解决方案:自动故障转移

选型边界

为什么从人工切换走向 MHA

触发问题
主库故障后人工处理耗时 2 小时,写操作长时间不可用,恢复过程也依赖人的判断。
候选方案
人工主从切换、自研故障转移脚本、MHA、托管数据库高可用版。
选择理由
MHA 比自研脚本更成熟,可以处理主库故障检测、候选从库提升和复制关系重建,适合教学阶段理解自动切换链路。
代价
仍要关注复制延迟、脑裂、防止误切换和切换后的数据校验;自动化不等于零风险。
暂不解决
暂不讨论强一致多主写入,当前目标是把单主 MySQL 的故障恢复时间从小时级降下来。

1. MySQL 主从切换

最朴素的高可用就是主从切换:主库负责写,从库实时复制,主库挂了就把某个从库提升为新主。可这个动作本身就是一次危险的改写——谁是主、复制链怎么接、旧主回来怎么归位,每一步都可能造成脑裂或丢数据。所以手动切换时必须先确认状态再动手,而不是照着文档一路敲命令。

设计流程

1. MySQL 主从切换

  1. 步骤 1:确认主库确实不可用,区分宕机、网络中断和误判三种情况
  2. 步骤 2:在各从库中比较复制位点,选出数据最新的一台作为候选主库
  3. 步骤 3:停止候选库的写入并执行提升,重建其他从库指向新主的复制关系
  4. 步骤 4:校验新主的写入与数据一致性,并规划旧主恢复后的重新纳管

关注点:提升前的一致性确认、复制关系重建与旧主的回切处理。

2. 自动故障转移脚本

手动切换两个小时都救不回业务,必须让机器来判断。这一节要做的是把切换逻辑写成脚本:由探活组件判断主库是否真的挂了,脚本据此执行提升、修复复制、重连应用连接。整个自动化最怕的不是不切换,而是切换错了——网络抖动被当成宕机,就会把主从关系搅乱,所以误判阈值和二次确认是脚本里最关键的两行参数。

设计流程

2. 自动故障转移脚本

  1. 步骤 1:配置探活组件,明确心跳超时和判定主库失效的阈值
  2. 步骤 2:脚本先做二次确认,排除网络抖动和代理层误判后再触发切换
  3. 步骤 3:执行提升、复制重建和应用连接重连,并记录每一步的执行结果
  4. 步骤 4:在真实故障下演练,测量恢复时长并确认脚本失败时可由人工接管

关注点:故障判定准确性、误切换防护与切换动作的可回退性。

3. 使用 MHA(MasterHA)

自己写脚本要处理复制、选主、切换、回切一整套逻辑,而 MHA 已经把这些打磨成熟。它的部署分两部分:管理端负责监控和决策,节点端跑在每台 MySQL 服务器上,负责上报状态和执行切换命令。配置的关键是写清楚检查脚本、复制关系和 VIP 漂移规则,部署完必须先在测试环境演练一次真实切换。

设计流程

3. 使用 MHA(MasterHA):部署操作

  1. 步骤 1:在管理端和每台 MySQL 节点部署 MHA,配置 SSH 免密和节点互信
  2. 步骤 2:编写 check、repl 和 failover 脚本,明确复制检查与切换执行逻辑
  3. 步骤 3:配置 VIP 漂移和故障切换阈值,指定候选从库的提升优先级
  4. 步骤 4:在测试环境演练一次主库宕机,核对切换结果与数据一致性

关注点:管理端与节点端分工、切换配置正确性与演练验证。

监控和告警

自动切换跑起来之后,人就退到了二线,这时监控就是唯一的眼睛。要盯的不只是主库存活,还包括复制延迟、主从位点差、切换事件本身和 MHA 管理端的状态。告警要能在复制悄悄停摆、MHA 进程异常时立刻叫醒人——这类问题平时无感,一旦真发生,自动切换也救不了。

设计流程

监控和告警

  1. 步骤 1:采集主库存活、复制延迟、主从位点差和 MHA 进程状态等指标
  2. 步骤 2:对复制停滞、延迟越线和 MHA 异常分别配置不同级别的告警
  3. 步骤 3:把每次切换事件记录成可追溯的日志,含触发原因和恢复耗时
  4. 步骤 4:定期核对监控数据与实际状态,防止指标口径与真实链路脱节

关注点:复制延迟、切换事件可追溯与自动化组件自身的健康。

上线前多想一步

  • 切换要多快? 先给自己定一个目标,例如 1 分钟内恢复写入,而不是等故障时再临场判断。
  • 会不会丢数据? 主库挂掉前最后几秒写入的订单、订阅和日志,要有办法查清楚。
  • 会不会误切? 网络抖动不等于主库真的死了,自动切换前要有足够的确认信号。

当前架构

技术架构
客户端

用户请求

GET https://api.kuaiyizhi.cn/v4/weather?city=上海
负载均衡层

智能 DNS(GeoDNS)

应用服务

Nginx

Python

Public API Gateway

Admin API

Static

Admin Dashboard


MySQL

Redis 集群 + 哨兵

外部服务

MySQL 多地域主从

消息队列

离线数仓

发现内容有问题?

告诉我们哪里需要改进。