19.9.5 跨机房/多云容灾与演练流程

跨机房/多云容灾的核心目标是将业务从单一故障域中解耦,实现跨地域、跨云的连续性保障。设计时需先完成业务分级与RPO/RTO目标映射,明确容灾等级(冷备/温备/热备/双活)、数据同步方式(异步/半同步/同步)与切换策略(手动/自动),并将指标落到演练与验收标准。

原理与架构草图(跨机房双活 + 全局流量调度):

文章图片

容灾架构常见模式:
- 跨机房主备:主站点承载业务,备站点热/温/冷备。
- 同城双活:同城双机房双活,强一致难度高。
- 两地三中心:同城双活 + 异地灾备,兼顾低RTO与极端故障。
- 多云主备/双活:跨云网络打通、镜像与配置同步、密钥管理与成本治理。

关键技术示例与命令(含安装/配置/切换/验证):

1)MySQL 半同步复制 + 故障切换(示例)
安装与启用半同步插件(主备都需要):

# 主库与备库执行
sudo yum -y install mysql-community-server
mysql -uroot -p -e "INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';"
mysql -uroot -p -e "INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';"

# 主库配置 /etc/my.cnf
cat >> /etc/my.cnf <<'EOF'
[mysqld]
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
log_bin=mysql-bin
rpl_semi_sync_master_enabled=ON
rpl_semi_sync_master_timeout=5000
EOF

# 备库配置 /etc/my.cnf
cat >> /etc/my.cnf <<'EOF'
[mysqld]
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
log_bin=mysql-bin
relay_log=relay-bin
rpl_semi_sync_slave_enabled=ON
read_only=ON
EOF

sudo systemctl restart mysqld

建立复制关系(GTID):

-- 主库
CREATE USER 'repl'@'%' IDENTIFIED BY 'replpass';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

-- 备库
CHANGE MASTER TO
MASTER_HOST='10.0.1.10',
MASTER_USER='repl',
MASTER_PASSWORD='replpass',
MASTER_AUTO_POSITION=1;
START SLAVE;
SHOW SLAVE STATUS\G

故障切换示例(手动演练):

-- 备库提升为主库
STOP SLAVE;
RESET SLAVE ALL;
SET GLOBAL read_only=OFF;

-- 应用/中间层切换指向新主库

验证与回滚:

-- 验证新主库写入
CREATE DATABASE dr_test;
SHOW DATABASES;

-- 回滚时需重新建立复制,避免脑裂

排错要点:

# 复制延迟与半同步状态
mysql -uroot -p -e "SHOW STATUS LIKE 'Rpl_semi_sync%';"
mysql -uroot -p -e "SHOW SLAVE STATUS\G" | egrep "Seconds_Behind_Master|Last_IO_Error|Last_SQL_Error"

2)Redis 哨兵跨机房(示例)
安装:

sudo yum -y install redis

主备与哨兵配置(/etc/redis/redis.conf):

# 主库
bind 0.0.0.0
protected-mode no
appendonly yes

# 备库
replicaof 10.0.1.20 6379

哨兵配置(/etc/redis/sentinel.conf):

sentinel monitor mymaster 10.0.1.20 6379 2
sentinel down-after-milliseconds mymaster 10000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1

启动与验证:

sudo systemctl start redis
redis-cli -h 10.0.1.20 info replication
redis-cli -p 26379 sentinel get-master-addr-by-name mymaster

排错:

# 哨兵无法发现主库时检查跨机房防火墙与ACL
sudo ss -lntp | grep 26379

3)Kafka 跨集群复制(MirrorMaker 2 示例)
安装(以 Kafka 3.x 为例):

tar -xzf kafka_2.13-3.6.0.tgz
cd kafka_2.13-3.6.0

配置(config/mm2.properties):

clusters = source, target
source.bootstrap.servers = 10.0.1.30:9092
target.bootstrap.servers = 10.0.2.30:9092
source->target.enabled = true
source->target.topics = .*

启动:

bin/connect-mirror-maker.sh config/mm2.properties

验证:

bin/kafka-topics.sh --bootstrap-server 10.0.2.30:9092 --list | head

4)Kubernetes 多集群切换 + 全局流量(示例)
多集群上下文:

kubectl config get-contexts
kubectl config use-context idc-a
kubectl get nodes
kubectl config use-context idc-b
kubectl get nodes

应用清单一致性(示例 Deployment 与 Service):

# /srv/dr/app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels: {app: web}
  template:
    metadata:
      labels: {app: web}
    spec:
      containers:
      - name: web
        image: nginx:1.25
        ports: [{containerPort: 80}]
---
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector: {app: web}
  ports:
  - port: 80
    targetPort: 80

部署到两集群:

kubectl config use-context idc-a && kubectl apply -f /srv/dr/app.yaml
kubectl config use-context idc-b && kubectl apply -f /srv/dr/app.yaml

全局切换(示意:DNS/GSLB 指向变更):

# 假设使用外部DNS或GSLB API,示例为伪命令
gslbctl set --domain example.com --primary idc-b --weight 100

演练流程标准化(计划—准备—执行—验证—复盘):
1. 计划:范围、时间窗口、指标、回滚方案、审批。
2. 准备:数据基线校验、链路健康检查、配置冻结、告警预置。
3. 执行:触发切换、变更DNS/GSLB、校验依赖可用性。
4. 验证:关键业务场景回归、性能与一致性检查。
5. 复盘:问题清单、改进项、脚本迭代。

演练脚本示例(健康检查 + 切换 + 回滚):

#!/usr/bin/env bash
# /srv/dr/dr-drill.sh
set -euo pipefail

PRIMARY="10.0.1.10"
SECONDARY="10.0.2.10"
APP_URL="https://example.com/health"

echo "[1] 预检查:主站点健康"
curl -sf "${APP_URL}" >/dev/null

echo "[2] 触发切换(示例:DNS/GSLB)"
gslbctl set --domain example.com --primary idc-b --weight 100

echo "[3] 验证:应用可用性"
sleep 10
curl -sf "${APP_URL}" >/dev/null

echo "[4] 回滚"
gslbctl set --domain example.com --primary idc-a --weight 100
echo "完成"

排错与常见故障定位:
- 切换后访问失败:检查DNS TTL、GSLB 权重、WAF/安全组、跨云路由。
- 复制延迟过大:检查链路时延、带宽、MySQL/Redis/Kafka队列积压。
- 脑裂风险:确认读写入口唯一、主备状态锁、仲裁/心跳正常。

关键指标与验收口径:
- RPO:允许数据丢失时间窗口(如 < 30s)。
- RTO:业务恢复时间(如 < 5min)。
- 切换耗时、告警触达率、人工介入次数、回滚成功率。

练习(建议按季度演练):
1. 基于MySQL半同步复制完成一次主备切换并回滚。
2. 在两集群Kubernetes中演练GSLB流量切换并验证健康检查。
3. 模拟跨机房链路抖动,观察复制延迟并定位瓶颈。
4. 用脚本实现“一键切换 + 自动验证 + 自动回滚”。

建议通过运维平台落地自动化与审计:一键切换、自动校验与回滚、全链路可观测仪表盘、演练证据留存与合规审计,形成可持续改进的容灾体系。