6.5.6 容灾架构(本地/异地/多活)与切换流程

容灾架构围绕RPO/RTO与业务连续性设计,常见形态包括本地容灾、异地容灾与多活。总体原则是数据一致性、切换可控、故障可观测,结合成本与复杂度选择适配方案。以下内容包含架构草图、可执行示例、安装与排错要点及练习。

架构类型与适用场景#

  • 本地容灾:同城机房或同可用区部署,低延迟、低RPO,适用于机房级别故障防护。常见为主从或主主复制+VIP/Proxy切换。
  • 异地容灾:跨地域部署,RTO略高,抵御城市级灾害,适用于关键业务。常见为主从异地复制、异地备库+定期演练。
  • 多活架构:多区域同时对外服务,强调流量分配与数据一致性,适用于超大规模高可用业务,要求完备的冲突解决与全链路治理。

原理草图(本地/异地/多活)#

文章图片

关键组件与依赖#

  • 复制链路:半同步/异步复制、GTID、延迟监控。
  • 访问入口:VIP、DNS、ProxySQL、HAProxy、Keepalived。
  • 数据一致性:写入策略、只读节点隔离、延迟阈值控制。
  • 观测与告警:复制延迟、主从差异、心跳链路、业务可用性。

安装与基础组件准备(示例)#

以 Keepalived + HAProxy 为例(本地容灾入口):

# 安装 keepalived 与 haproxy(以 RHEL/CentOS 为例)
yum install -y keepalived haproxy

# 启动并设置开机自启
systemctl enable --now keepalived
systemctl enable --now haproxy

# 验证服务状态
systemctl status keepalived
systemctl status haproxy

命令解释:
- yum install -y:安装高可用组件。
- systemctl enable --now:启动并设为开机自启。
- systemctl status:检查运行状态与错误日志。

访问入口配置示例(Keepalived + HAProxy)#

/etc/keepalived/keepalived.conf

vrrp_instance VI_1 {
  state MASTER
  interface eth0
  virtual_router_id 51
  priority 100
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass 123456
  }
  virtual_ipaddress {
    10.0.0.100/24
  }
}

/etc/haproxy/haproxy.cfg(MySQL TCP转发)

global
  maxconn 2048

defaults
  mode tcp
  timeout connect 5s
  timeout client  1m
  timeout server  1m

frontend mysql_in
  bind *:3306
  default_backend mysql_back

backend mysql_back
  option tcp-check
  server db1 10.0.0.11:3306 check
  server db2 10.0.0.12:3306 check backup

预期效果:
- VIP 10.0.0.100 对外提供 MySQL 入口。
- db1 为主用,db2 为备份。

切换流程(本地/同城)与命令示例#

  1. 故障确认:监控触发、业务验证、数据库不可用或延迟超阈值。
  2. 写入隔离:停写或应用侧降级,避免脑裂。
  3. 备库提升:验证复制无异常,提升为主库。
  4. 路由切换:VIP/Proxy指向新主库,确认连接池刷新。
  5. 数据校验:检查数据一致性与主键冲突。
  6. 旧主处理:隔离旧主,修复后作为从库重新加入。

关键命令示例(主从切换)

-- 1) 备库确认复制状态与延迟
SHOW SLAVE STATUS\G;

-- 2) 备库停止复制并提升为主库
STOP SLAVE;
RESET SLAVE ALL;
SET GLOBAL read_only = OFF;

-- 3) 业务侧验证写入
CREATE DATABASE dr_test;
DROP DATABASE dr_test;

命令解释:
- SHOW SLAVE STATUS\G:查看复制状态与延迟。
- STOP SLAVE:停止复制线程,避免写入冲突。
- RESET SLAVE ALL:清理复制信息,为提升主库做准备。
- SET GLOBAL read_only = OFF:解除只读,允许写入。

VIP/Proxy 切换验证

# 验证 VIP 是否漂移至新主机
ip addr show | grep 10.0.0.100

# 测试入口连接
mysql -h 10.0.0.100 -uroot -p -e "SELECT @@hostname, @@read_only;"

命令解释:
- ip addr show:检查 VIP 是否在本机。
- mysql -e:快速验证读写状态。

切换流程(异地)与命令示例#

  1. 灾难判定:主站不可恢复或预计恢复超RTO。
  2. 异地备库评估:检查复制位点、延迟、业务一致性。
  3. 备库提升:强制提升并开启写入,记录切换时间点与位点。
  4. 流量牵引:DNS/全局负载均衡切换至异地主站。
  5. 业务验证:关键链路验证与数据核对。
  6. 灾后回切:主站恢复后进行数据同步与回切计划。

异地提升与DNS切换示例

# 1) 异地备库提升
mysql -h 10.1.0.11 -uroot -p -e "STOP SLAVE; RESET SLAVE ALL; SET GLOBAL read_only=OFF;"

# 2) DNS TTL 建议提前降低(示例:300秒)
# 以 BIND 为例,修改 zone 文件 TTL
# $TTL 300

命令解释:
- 异地提升与本地提升一致,重点在记录切换时间点用于回切。

多活切换与治理要点#

  • 流量路由:按地域或用户维度分流,避免跨区写冲突。
  • 数据冲突:通过全局唯一ID、幂等写、最终一致性机制解决。
  • 限制范围:核心写入建议单主或分区主控,多活侧重读与特定写域。

多活写入分区示例(按租户ID分库)

-- 约定:tenant_id 偶数写区域A,奇数写区域B
SELECT 
  CASE WHEN MOD(tenant_id,2)=0 THEN 'RegionA' ELSE 'RegionB' END AS route;

排错与自检清单(示例)#

  • 复制延迟异常:
SHOW SLAVE STATUS\G;  -- 关注 Seconds_Behind_Master 与 Last_SQL_Error
  • 脑裂风险:
SHOW VARIABLES LIKE 'read_only';
-- 应保证非主库 read_only=ON
  • 入口未切换:
# VIP 不在预期主机
ip addr show | grep 10.0.0.100
# 代理后端指向错误
echo "show servers state" | socat stdio /var/run/haproxy.sock

演练与制度化#

  • 定期演练切换流程,覆盖白天/夜间与高峰期。
  • 演练结果形成SOP与回滚方案,持续优化RTO/RPO。
  • 对外沟通机制明确,确保业务、运维、研发协同。

常见风险与规避#

  • 脑裂风险:双写入口未隔离,需强制只读与心跳裁决。
  • 复制延迟:提前设置延迟阈值与自动降级策略。
  • 依赖未切换:应用配置、连接池、缓存、任务调度需统一切换策略。

练习#

  1. 搭建一主一从环境,模拟主库宕机并完成备库提升。
    - 要求:记录切换前后 @@read_only@@hostname 的变化。
  2. 配置 Keepalived VIP 漂移,验证 VIP 在主机间切换。
    - 要求:连续观察 ip addr show 并写出切换时间点。
  3. 模拟复制延迟超过阈值,触发手工切换并复盘:
    - 要求:收集 SHOW SLAVE STATUS\G 输出并分析原因。