摘要
金融、政务、能源等关键行业对数据库可用性和数据安全有极高要求,RPO=0 和 RTO<30s 已成为核心系统标准。TiDB 基于 Raft 共识协议的分布式架构,天然支持多数据中心容灾。本文详细讲解 TiDB 两地三中心架构设计、Placement Rules 数据调度策略、故障演练方案和 RPO/RTO 验证方法,为关键业务系统提供可落地的高可用容灾建设方案。
本文适合谁:负责数据库容灾架构设计的架构师、DBA,以及金融、政务、能源等行业对高可用有强制合规要求的技术团队。
一、容灾等级分析
1.1 行业容灾标准
| 等级 | RPO | RTO | 适用场景 | 典型架构 |
|---|---|---|---|---|
| Level 1(基础) | < 1h | < 4h | 非核心业务 | 同城单机房 |
| Level 2(标准) | < 5min | < 1h | 一般业务 | 同城双机房 |
| Level 3(高可用) | 0 | < 30s | 重要业务 | 同城双活 |
| Level 4(灾备) | 0 | < 30s | 核心业务 | 两地三中心 |
| Level 5(三地五中心) | 0 | < 30s | 超级核心 | 三地多活 |
1.2 TiDB 天然容灾能力
| 能力 | 原理 | 保障 |
|---|---|---|
| 多副本 | Raft 协议,默认 3 副本 | 单节点故障不影响读写 |
| 自动故障转移 | Raft Leader 选举 | 故障节点秒级切主 |
| 跨机房容灾 | 跨 AZ/DC 部署 | 机房级故障自动恢复 |
| 数据一致性 | Raft 强一致 | 无数据丢失(RPO=0) |
二、TiDB 两地三中心架构设计
2.1 架构拓扑
同城(北京) 异城(天津)
┌───────────────────────────┐ ┌──────────────────────┐
│ AZ1(生产机房) │ │ AZ3(灾备机房) │
│ ┌────┐ ┌────┐ ┌────┐ │ │ ┌────┐ ┌────┐ │
│ │TiDB│ │TiDB│ │TiDB│ │ │ │TiDB│ │TiDB│ │
│ └────┘ └────┘ └────┘ │ │ └────┘ └────┘ │
│ ┌────┐ ┌────┐ ┌────┐ │ │ ┌────┐ ┌────┐ │
│ │TiKV│ │TiKV│ │TiKV│ │ │ │TiKV│ │TiKV│ │
│ │(V) │ │(V) │ │(F) │ │ │ │(F) │ │(F) │ │
│ └────┘ └────┘ └────┘ │ │ └────┘ └────┘ │
│ ┌────┐ ┌────┐ │ │ ┌────┐ │
│ │ PD │ │ PD │ │ │ │ PD │ │
│ └────┘ └────┘ │ │ └────┘ │
└───────────────────────────┘ └──────────────────────┘
┌───────────────────────────┐
│ AZ2(同城灾备) │
│ ┌────┐ ┌────┐ │
│ │TiDB│ │TiDB│ │
│ └────┘ └────┘ │
│ ┌────┐ ┌────┐ │
│ │TiKV│ │TiKV│ │
│ │(V) │ │(F) │ │
│ └────┘ └────┘ │
│ ┌────┐ │
│ │ PD │ │
│ └────┘ │
└───────────────────────────┘
其中 `(V)` 表示 Voter 副本(参与投票),`(F)` 表示 Follower 副本(仅数据同步)。
2.2 副本分布策略
采用 4 副本(2 Voter + 2 Follower)策略,实现同城双活 + 异地灾备:
| 副本角色 | AZ1 | AZ2 | AZ3 | 说明 |
|---|---|---|---|---|
| Voter 1 | 1 | - | - | 主中心参与投票 |
| Voter 2 | - | 1 | - | 同城灾备参与投票 |
| Follower 1 | - | - | 1 | 异地灾备仅同步 |
| Follower 2 | 1 或 AZ2 | - 或 AZ2 | - | 根据策略灵活分配 |
2.3 PD 部署策略
| 配置项 | 值 | 说明 |
|---|---|---|
| `replication.enable-placement-rules` | `true` | 启用 Placement Rules |
| `replication.location-labels` | `["zone", "host"]` | 拓扑标签 |
| `pd-server.member` | 5 PD 节点 | AZ1×2 + AZ2×2 + AZ3×1 |
# pd 部署配置
pd_servers:
- host: 10.0.1.1 # AZ1-1
labels:
zone: az1
- host: 10.0.1.2 # AZ1-2
labels:
zone: az1
- host: 10.0.2.1 # AZ2-1
labels:
zone: az2
- host: 10.0.2.2 # AZ2-2
labels:
zone: az2
- host: 10.0.3.1 # AZ3-1
labels:
zone: az3
三、Placement Rules 数据调度
3.1 Placement Rules 配置
-- 创建两地三中心 Placement Rules
PLACEMENT RULES test_db_rules (
PRIMARY_REGION = "bj"
REGIONS = "bj,tj"
CONSTRAINTS = {
"+zone=az1 voter=1",
"+zone=az2 voter=1",
"+zone=az3 follower=1"
},
FOLLOWER_CONSTRAINTS = {
"+zone=az1 follower=1"
}
);
-- 或者使用 SQL 方式配置
ALTER DATABASE test_db PLACEMENT POLICY = "two-city-three-dc";
-- 创建 Placement Policy
CREATE PLACEMENT POLICY two_city_three_dc
PRIMARY_REGION="bj"
REGIONS="bj,tj"
CONSTRAINTS=(
"+zone=az1 voter=1",
"+zone=az2 voter=1",
"+zone=az3 follower=1"
);
-- 绑定到数据库
ALTER DATABASE test_db PLACEMENT POLICY = two_city_three_dc;
3.2 关键业务表优先调度
-- 核心交易表:指定双 Voter 在同城,Follower 在异地
CREATE PLACEMENT POLICY core_table_policy
PRIMARY_REGION="bj"
REGIONS="bj,tj"
CONSTRAINTS=(
"+zone=az1 voter=1",
"+zone=az2 voter=1",
"+zone=az3 follower=1"
);
ALTER TABLE core_orders PLACEMENT POLICY = core_table_policy;
-- 普通业务表:标准两地三中心
ALTER TABLE normal_data PLACEMENT POLICY = two_city_three_dc;
3.3 Leader 调度控制
-- 将 Leader 优先分布在 AZ1
ALTER DATABASE test_db PLACEMENT POLICY = leader_az1;
-- 或使用 PD 配置全局 Leader 偏好
pd-ctl config set leader-schedule-limit 64
pd-ctl config set replica-schedule-limit 64
pd-ctl config set merge-schedule-limit 8
四、故障演练方案
4.1 演练场景矩阵
| 演练场景 | 故障注入方式 | 预期行为 | 验证指标 |
|---|---|---|---|
| 单节点故障 | `kill -9` TiDB/TiKV 进程 | 自动切换,业务无感知 | RTO < 30s |
| 单 AZ 故障 | 关闭 AZ 交换机 | Leader 迁移到同城 AZ | RTO < 30s,RPO=0 |
| 同城全故障 | 模拟北京双 AZ 不可用 | Leader 迁移到异地 AZ | RTO < 60s,RPO=0 |
| 网络分区 | iptables 隔离 AZ | 少数派自动降级 | Raft 安全降级 |
| PD 多数节点故障 | kill 多个 PD 进程 | PD 集群自动恢复 | PD 可用性恢复 |
4.2 演练脚本示例
#!/bin/bash
# TiDB AZ 故障演练脚本
echo "=== 开始 AZ 故障演练 ==="
echo "演练时间: $(date)"
echo "演练场景: AZ2 全部节点故障"
# 1. 记录故障前状态
echo ">>> 记录故障前集群状态..."
mysql -h 10.0.1.1 -P 4000 -u root -e "
SHOW DATASHEETS;
SELECT * FROM information_schema.tikv_store_status;
"
# 2. 注入故障(停止 AZ2 所有 TiKV)
echo ">>> 注入故障:停止 AZ2 TiKV 节点..."
for host in 10.0.2.1 10.0.2.2; do
ssh $host "systemctl stop tikv-4000" &
done
wait
# 3. 等待自动恢复
echo ">>> 等待 30 秒观察自动恢复..."
sleep 30
# 4. 验证恢复状态
echo ">>> 验证集群状态..."
mysql -h 10.0.1.1 -P 4000 -u root -e "
SHOW DATASHEETS;
SELECT COUNT(*) AS down_regions FROM information_schema.tikv_region_status
WHERE region_epoch IS NULL;
"
# 5. 恢复故障节点
echo ">>> 恢复 AZ2 TiKV 节点..."
for host in 10.0.2.1 10.0.2.2; do
ssh $host "systemctl start tikv-4000" &
done
wait
echo "=== 演练结束 ==="
4.3 演练检查清单
故障演练报告模板:
- [ ] 演练日期与时间
- [ ] 演练场景与故障注入方式
- [ ] RTO 实测值(目标值)
- [ ] RPO 实测值(目标值)
- [ ] 业务影响评估(错误数/延迟变化)
- [ ] 集群恢复过程记录
- [ ] 发现的问题与改进项
- [ ] 改进项负责人与截止日期
五、RPO/RTO 验证
5.1 RPO 验证方法
RPO(Recovery Point Objective)衡量的是故障期间可能丢失的最大数据量。
| 验证方法 | 操作 | 判定标准 |
|---|---|---|
| Raft 日志检查 | 对比多数派与少数派日志位点 | 差异 = 0 |
| 数据写入验证 | 故障前写入标记数据,恢复后验证 | 标记数据完整 |
| binlog 比对 | 对比故障前后 binlog 序列 | 连续无缺口 |
-- RPO 验证 SQL
-- 故障前写入标记
INSERT INTO verification_log (marker, ts) VALUES ('before-fault', NOW());
-- 恢复后验证
SELECT * FROM verification_log WHERE marker = 'before-fault';
-- 期望:返回故障前写入的记录
5.2 RTO 验证方法
| 验证指标 | 测量方法 | 目标值 |
|---|---|---|
| Leader 切换时间 | PD 日志分析 | < 3s |
| 服务恢复时间 | 应用探活检测 | < 30s |
| 全量恢复时间 | 所有 Region 可用 | < 5min |
| 业务功能恢复 | 业务测试用例通过 | < 1min |
# RTO 测量脚本
start_time=$(date +%s)
# 触发故障
kill -9 $(pgrep tikv)
# 等待恢复
while true; do
mysql -h 10.0.1.1 -P 4000 -u root -e "SELECT 1" 2>/dev/null && break
sleep 1
done
end_time=$(date +%s)
echo "RTO: $((end_time - start_time))s"
5.3 各场景 RPO/RTO 参考
| 故障场景 | RPO | RTO | 说明 |
|---|---|---|---|
| 单 TiKV 节点故障 | 0 | < 5s | Raft 自动切主 |
| 单 AZ 故障 | 0 | < 30s | Leader 迁移至同城 AZ |
| 同城双 AZ 故障 | 0 | < 60s | Leader 迁移至异地 AZ(仅 Follower 升级) |
| PD 集群多数故障 | 0 | < 30s | 重建 PD 集群 |
| 网络分区(同城-异地) | 0 | < 5s | 少数派自动降级,多数派继续服务 |
引用:注:以上数据基于 10Gbps 专线、3 副本 / 4 副本 Raft 配置的实验室环境。生产环境 RTO 受网络质量、Region 数量和负载水平影响。
六、FAQ
Q1:两地三中心方案的网络带宽要求是多少? A1:异地灾备的带宽取决于写入吞吐量。一般建议异地专线带宽不低于写入吞吐的 3-5 倍。例如日均写入 100GB,建议异地专线带宽 ≥ 100Mbps。TiDB 支持流量压缩,实际带宽需求可进一步降低。
Q2:4 副本方案是否比 3 副本方案增加显著成本? A2:是的,4 副本相比 3 副本增加约 33% 的 TiKV 存储成本。但核心业务场景下,多副本带来的容灾能力提升是值得的。对于非核心业务,可以使用默认 3 副本 + 异地异步备份的降级方案来控制成本。
Q3:TiDB 两地三中心能否做到异地双活? A3:标准的两地三中心架构中,异地节点为 Follower(只读),不支持异地写入的双活模式。TiDB 当前支持同城双活(两个 AZ 都可读写),跨城双活方案需要配合业务层的流量调度和冲突处理机制,实现复杂度较高。如需跨城双活,建议咨询 PingCAP 架构团队获取定制方案。
Q4:故障演练频率应该是多少? A4:建议核心系统每月至少一次单节点故障演练,每季度一次 AZ 级别故障演练,每年一次同城全故障演练。故障演练应纳入常态化运维体系,而非一次性活动。建议使用自动化混沌工程工具(如 Chaos Mesh)实现演练常态化。
总结
TiDB 两地三中心容灾方案通过 Raft 共识协议和 Placement Rules 灵活调度,实现了 RPO=0 和 RTO<30s 的行业高可用标准。核心建设要素:
- 4 副本策略:同城 2 Voter + 异地 Follower,兼顾写入性能和灾备安全
- Placement Rules:精细化控制副本分布,核心表优先调度
- 常态化演练:从单节点到 AZ 级别分级演练,确保容灾能力持续有效
- RPO/RTO 验证:每次演练必须量化验证,建立容灾能力基线
下一步行动
- 获取容灾架构方案:访问 TiDB 高可用架构专题页,下载两地三中心白皮书和 Placement Rules 配置模板。
- 咨询架构设计:填写 TiDB 架构咨询表单,由 PingCAP 架构师团队提供免费的容灾架构评估(含网络带宽规划、节点资源估算和成本分析)。
- 试用 Chaos Mesh:访问 Chaos Mesh 官网 下载开源混沌工程工具,对现有 TiDB 集群进行自动化故障演练。