返回架构笔记
Arch Day 41

Arch Day 41: 金融级高可用设计 — 两地三中心、异地多活与灾备切换

金融级高可用设计是在RTO < 30分钟、RPO ≈ 0的刚性约束下,通过两地三中心/异地多活等架构模式,确保核心金融系统在任何单点故障(含整个数据中心级别的灾难)下都能持续提供服务的系统性工程——它不仅是技术方案,更是涵盖架构设计、运维流程、组织协同、演练验证的完整体系。

2026-05-10
第二阶段 - 金融域深度
核心银行高可用两地三中心异地多活RTORPO混沌工程CAP

日期: 2026-05-10 (Day 41) 阶段: 第二阶段 - 金融域深度 标签: #核心银行 #高可用 #两地三中心 #异地多活 #RTO #RPO #混沌工程 #CAP


核心概念

一句话定义

金融级高可用设计是在RTO < 30分钟、RPO ≈ 0的刚性约束下,通过两地三中心/异地多活等架构模式,确保核心金融系统在任何单点故障(含整个数据中心级别的灾难)下都能持续提供服务的系统性工程——它不仅是技术方案,更是涵盖架构设计、运维流程、组织协同、演练验证的完整体系。

为什么资深架构师必须关注

维度关注理由
监管硬性要求银保监会明确规定核心系统RTO < 30分钟、RPO ≈ 0,不达标将面临监管处罚
资金安全金融系统宕机意味着资金无法流转——ATM取不到钱、转账失败、贷款无法发放
声誉影响2018年TSB银行系统崩溃5周,直接导致CEO辞职、220万英镑罚款、客户大量流失
架构基石高可用不是事后补救,必须从架构设计第一天就考虑,事后改造代价极高
面试核心"如何设计金融级高可用系统"是架构师面试的必考题

常见误区与反模式

误区真相
"有了灾备中心就是高可用"灾备中心如果从不演练切换,关键时刻大概率切不过去。行业数据:未经演练的灾备系统首次切换成功率<50%
"RPO=0只要用同步复制就行"同步复制保证了数据不丢,但可能带来性能下降和可用性风险(如果副本不可用,主库也会阻塞)
"异地多活=两个机房都能写"真正的异地多活需要解决数据冲突、路由策略、一致性保证等极其复杂的问题
"99.99%可用性够用了"99.99%意味着每年52分钟不可用。金融核心系统的目标是99.999%(每年5分钟)
"自动故障转移总比手动好"误判导致的自动切换(brain-split)可能比故障本身更危险。金融系统通常采用"半自动"策略

知识点详解

知识点1:RTO/RPO的金融行业要求

RTO和RPO定义
━━━━━━━━━━━━

RPO (Recovery Point Objective) - 数据恢复点目标
│
│ ← 数据丢失量 → │
│                 │
▼                 ▼
最后一次备份      故障发生
时间点            时间点

RPO = 0 表示不能丢失任何已提交的数据


RTO (Recovery Time Objective) - 恢复时间目标
│
│ ← 服务中断时间 → │
│                   │
▼                   ▼
故障发生             服务恢复
时间点               时间点

RTO < 30min 表示从故障发生到服务恢复不超过30分钟

中国银行业监管要求(银保监会)

系统级别系统类型RTORPO等级
一级核心交易系统(账务/支付)< 30分钟06级
二级重要业务系统(信贷/理财)< 4小时< 30分钟5级
三级一般业务系统(报表/管理)< 12小时< 4小时4级
四级辅助系统(OA/邮件)< 24小时< 24小时3级

不同RTO/RPO对应的技术方案

RTO/RPO目标技术方案成本倍数适用
RPO=0, RTO<30s同城双活+自动切换3-5x支付宝/微信支付
RPO=0, RTO<5min同城双活+半自动切换2-3x大型银行核心
RPO=0, RTO<30min同城主备+同步复制1.5-2x中型银行核心
RPO<30min, RTO<4h异地灾备+异步复制1.2-1.5x一般业务系统
RPO<24h, RTO<24h定期备份+恢复1.1x辅助系统

知识点2:两地三中心架构

两地三中心(最主流的金融灾备架构)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

城市A (生产城市)                         城市B (灾备城市)
┌─────────────────────────────┐        ┌─────────────────┐
│                             │        │                 │
│  DC-1 (生产中心)    DC-2 (同城灾备)  │  DC-3 (异地灾备) │
│  ┌─────────┐       ┌─────────┐      │  ┌─────────┐    │
│  │ 应用集群 │       │ 应用集群 │      │  │ 应用集群 │    │
│  │ (Active) │       │(Standby │      │  │(Standby │    │
│  │          │       │ /Active)│      │  │  Cold)  │    │
│  ├─────────┤       ├─────────┤      │  ├─────────┤    │
│  │ 数据库   │◄─────►│ 数据库  │      │  │ 数据库  │    │
│  │ (Master) │ 同步   │(Slave)  │─────►│  │(Slave)  │    │
│  │          │ 复制   │         │ 异步  │  │         │    │
│  └─────────┘       └─────────┘ 复制  │  └─────────┘    │
│                             │        │                 │
│  距离: <100km               │        │  距离: >500km    │
│  延迟: <3ms                 │        │  延迟: 10-50ms   │
│  RPO: 0                     │        │  RPO: 秒-分钟级  │
│  RTO: <5min                 │        │  RTO: <30min     │
└─────────────────────────────┘        └─────────────────┘

三种灾难场景和恢复策略:

场景1: DC-1单机故障(服务器/网络设备)
├── 影响: 部分请求失败
├── 恢复: 自动故障转移(集群内)
├── RTO: 秒级
└── RPO: 0

场景2: DC-1整体故障(机房断电/网络中断)
├── 影响: 所有生产服务不可用
├── 恢复: 切换到DC-2(同城灾备)
├── 流程: 确认DC-1不可恢复 → DNS/负载均衡切换 → DC-2升主
├── RTO: 5-15分钟
└── RPO: 0(同步复制保证)

场景3: 城市A整体灾难(地震/洪水/大范围断电)
├── 影响: 城市A两个机房全部不可用
├── 恢复: 切换到DC-3(异地灾备)
├── 流程: 确认城市A不可恢复 → 启动DC-3 → DNS全局切换
├── RTO: 15-30分钟
├── RPO: 异步复制延迟(通常秒级,极端情况分钟级)
└── 注意: 这是最严重的场景,RPO可能>0

知识点3:异地多活架构设计

异地多活 vs 两地三中心

两地三中心:
├── 同城: Active-Standby(或Active-Active)
├── 异地: Cold Standby
├── 灾备机房平时不提供服务("养兵千日用兵一时")
└── 问题: 异地机房长期闲置=资源浪费,且切换时不确定能否正常工作

异地多活:
├── 多个地域的数据中心同时提供服务
├── 每个中心处理部分流量
├── 任一中心故障,流量自动转移到其他中心
└── 优势: 资源利用率高、切换更可靠(因为每天都在使用)


异地多活的核心设计
━━━━━━━━━━━━━━━━━

1. 单元化(Unit-based Architecture)

  ┌──────────┐   ┌──────────┐   ┌──────────┐
  │ 单元A     │   │ 单元B     │   │ 单元C     │
  │ 北京      │   │ 上海      │   │ 深圳      │
  │           │   │           │   │           │
  │ 用户:     │   │ 用户:     │   │ 用户:     │
  │ 0-33%     │   │ 34-66%   │   │ 67-100%  │
  │           │   │           │   │           │
  │ ┌───────┐ │   │ ┌───────┐ │   │ ┌───────┐ │
  │ │应用层 │ │   │ │应用层 │ │   │ │应用层 │ │
  │ ├───────┤ │   │ ├───────┤ │   │ ├───────┤ │
  │ │数据层 │ │   │ │数据层 │ │   │ │数据层 │ │
  │ └───────┘ │   │ └───────┘ │   │ └───────┘ │
  └─────┬─────┘   └─────┬─────┘   └─────┬─────┘
        │               │               │
        └───────────────┼───────────────┘
                        │
              数据同步(异步/准实时)

  原则:
  ├── 每个单元包含完整的应用+数据(自治)
  ├── 用户按规则路由到固定单元(如按user_id Hash)
  ├── 单元内操作是本地操作(不需要跨单元)
  ├── 跨单元操作通过消息异步处理
  └── 关键: 如何确定"用户归属单元"

2. 数据同步策略

  方案A: 单向主从复制(简单但有局限)
  ├── 数据写入: 只在用户归属单元写入
  ├── 数据读取: 从本地单元读取
  ├── 跨单元操作: 路由到归属单元处理
  └── 适用: 读多写少、用户维度可分片的场景

  方案B: 双向异步复制(复杂但灵活)
  ├── 数据写入: 在任何单元都可以写入
  ├── 冲突处理: Last-Writer-Wins / 业务规则仲裁
  ├── 一致性: 最终一致性(有冲突窗口)
  └── 适用: 非资金类场景(如用户信息修改)

  方案C: 全局一致性(性能代价高)
  ├── 数据写入: 通过Paxos/Raft跨地域同步
  ├── 一致性: 强一致
  ├── 代价: 跨地域延迟(50-100ms)
  └── 适用: 资金类核心场景(如跨单元转账)

3. 流量调度

  ┌──────────┐
  │ 全局DNS  │
  │ /GSLB    │
  └────┬─────┘
       │ 路由规则:
       │ ├── 地理位置(就近接入)
       │ ├── 用户归属(Hash路由)
       │ └── 负载均衡(流量分配)
       │
  ┌────┼────┐────┐
  ▼    ▼    ▼    ▼
  北京  上海  深圳  (其他)

知识点4:金融级灾备切换流程

灾备切换决策流程(关键: 不能随意切换)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Step 1: 故障检测 (0-3分钟)
├── 自动监控检测到异常
│   ├── 心跳超时(连续3次)
│   ├── 应用健康检查失败
│   ├── 数据库连接中断
│   └── 网络不可达
├── 排除误报
│   ├── 是网络波动还是真正故障?
│   ├── 是单点故障还是整体故障?
│   └── 等待确认期(通常30秒-2分钟)
└── 输出: 故障确认报告

Step 2: 故障评估 (3-5分钟)
├── 评估影响范围
│   ├── 受影响的系统/服务
│   ├── 受影响的用户数
│   └── 预估恢复时间(原地恢复)
├── 决策: 原地恢复 or 切换灾备
│   ├── 如果预估原地恢复时间 < RTO → 原地恢复
│   └── 如果预估原地恢复时间 > RTO → 启动灾备切换
└── 输出: 切换决策

Step 3: 切换审批 (5-10分钟)
├── 技术负责人确认切换方案
├── 业务负责人确认业务影响
├── 高管审批(CEO/CTO级别)
│   └── 注意: 这一步不能省略,误切换的代价可能比宕机更大
├── 通知监管(如果影响客户)
└── 输出: 切换审批通过

Step 4: 执行切换 (10-20分钟)
├── 停止生产中心写入(防止脑裂)
├── 确认数据同步状态
│   ├── 同步复制: 数据已一致
│   └── 异步复制: 检查延迟量,确认可接受的数据丢失
├── 灾备中心数据库升主
├── 灾备中心应用启动/预热
├── DNS/负载均衡切换流量
├── 验证服务可用性
│   ├── 自动化健康检查
│   ├── 关键交易测试(模拟转账/查询)
│   └── 监控指标恢复正常
└── 输出: 服务恢复

Step 5: 善后处理 (切换后)
├── 持续监控灾备中心运行状态
├── 分析故障原因
├── 制定回切计划(从灾备切回生产)
├── 数据补偿(如果RPO>0,补偿丢失的交易)
├── 客户通知(如果有影响)
├── 监管报告
└── 事后复盘(RCA根因分析)


关键决策: 自动切换 vs 手动切换
━━━━━━━━━━━━━━━━━━━━━━━━━━━━

          自动切换                      手动切换
  ┌──────────────────┐        ┌──────────────────┐
  │ RTO: 秒-分钟级    │        │ RTO: 10-30分钟    │
  │ 风险: 误切换(脑裂) │        │ 风险: 人为延误     │
  │ 适用: 无状态服务   │        │ 适用: 有状态服务   │
  │ 举例: Web应用     │        │ 举例: 核心数据库   │
  └──────────────────┘        └──────────────────┘

金融行业推荐: 半自动
├── 无状态应用层: 自动切换
├── 核心数据库: 自动检测+人工确认+自动执行
└── 全局流量: 人工触发+自动执行

知识点5:CAP理论在金融场景的实际选择

CAP理论回顾
━━━━━━━━━━━

       Consistency(一致性)
          ╱       ╲
         ╱   CA    ╲
        ╱   (理论上 ╲
       ╱   不存在于  ╲
      ╱   分布式系统) ╲
     ╱_________________╲
    │                   │
 CP │                   │ AP
    │   强一致+分区容忍  │   高可用+分区容忍
    │   牺牲可用性       │   牺牲一致性
    │                   │
    └───────────────────┘
       Partition Tolerance(分区容忍)

金融场景的实际选择:
━━━━━━━━━━━━━━━━━

并非简单的CP或AP二选一,而是按场景混合选择:

场景1: 资金交易(转账/扣款/记账)
├── 选择: CP (强一致)
├── 原因: 资金不能多也不能少,宁可暂时不可用也不能数据不一致
├── 实现: 同步复制 + 分布式事务
├── 代价: 网络分区时拒绝写入(返回"系统繁忙请稍后")
└── 示例: OceanBase(Paxos) → 多数派不可用时停止写入

场景2: 余额查询
├── 选择: AP + 弱一致性
├── 原因: 查询短暂不一致(延迟几秒)是可接受的
├── 实现: 读从库 + 缓存
├── 代价: 可能查到旧余额(交易后几秒)
└── 补偿: 页面显示"余额仅供参考"或交易后走主库查询

场景3: 用户信息(地址/手机号等)
├── 选择: AP + 最终一致性
├── 原因: 信息变更几分钟后生效可以接受
├── 实现: 异步复制 + 消息队列
└── 代价: 修改后几分钟内不同渠道可能看到不同版本

场景4: 风控决策
├── 选择: 混合(AP for 读 + CP for 决策写入)
├── 原因: 风控需要快速响应(AP),但决策结果不能丢(CP)
└── 实现: 读缓存(最新的用户画像) + 写入强一致存储(风控决策记录)

知识点6:混沌工程在金融系统的应用

混沌工程 (Chaos Engineering) 在金融系统的实践
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

定义: 通过主动注入故障来验证系统的容错能力

原则:
├── 在生产环境测试(但金融系统需要更谨慎)
├── 从小范围开始,逐步扩大
├── 有明确的停止条件(爆炸半径控制)
└── 每次实验都要有假设和验证

金融系统可以做的混沌实验:
━━━━━━━━━━━━━━━━━━━━━━━━━

Level 1: 基础设施层(风险低)
├── 单台服务器宕机(kill process)
├── 网络延迟注入(tc netem)
├── 磁盘I/O变慢
├── CPU压力注入
└── 验证: 负载均衡是否自动剔除故障节点

Level 2: 应用层(风险中)
├── 微服务实例随机kill
├── 数据库连接池耗尽
├── 缓存大面积过期(缓存雪崩)
├── 消息队列积压
└── 验证: 熔断/降级/限流是否生效

Level 3: 数据层(风险高 - 金融系统需谨慎)
├── 数据库主从切换
├── 数据库只读副本延迟增大
├── Redis主节点故障
└── 验证: 数据一致性是否保证

Level 4: 机房级别(最高风险 - 通常只在演练中进行)
├── 模拟整个机房断电
├── 模拟网络分区(两个机房互不可达)
├── 模拟DNS故障
└── 验证: 灾备切换是否正常


金融混沌工程的安全边界:
━━━━━━━━━━━━━━━━━━━━━━

绝对不能做:
├── 在真实生产数据上做破坏性测试
├── 在交易高峰期做任何混沌实验
├── 在没有回滚方案的情况下做实验
├── 在监管审查期间做实验
└── 涉及真实客户资金的故障注入

必须遵守的规则:
├── 实验前获得高管审批
├── 实验在非高峰期进行(凌晨2-5点)
├── 实验有明确的爆炸半径(最多影响5%流量)
├── 实验有紧急停止按钮(一键回滚)
├── 实验全程有值班人员监控
└── 实验结果当天出报告

知识点7:灾备演练体系

灾备演练分级体系
━━━━━━━━━━━━━━━━

Level 1: 桌面演练(Table-top Exercise)
├── 频率: 每月1次
├── 方式: 会议室讨论,不涉及真实操作
├── 内容: 走查切换流程、确认角色分工、更新联系人
├── 参与: 技术团队
└── 目的: 保持团队对流程的熟悉度

Level 2: 功能演练(Functional Drill)
├── 频率: 每季度1次
├── 方式: 在灾备环境上执行切换操作(不影响生产)
├── 内容: 验证灾备系统可用性、数据同步正确性
├── 参与: 技术团队 + 运维团队
└── 目的: 验证技术方案可行性

Level 3: 全流程演练(Full-scale Exercise)
├── 频率: 每半年1次
├── 方式: 真正切换生产流量到灾备中心(灰度方式)
├── 内容: 完整的切换 + 业务验证 + 回切
├── 参与: 技术 + 业务 + 管理层
└── 目的: 验证端到端切换能力

Level 4: 监管演练(Regulatory Exercise)
├── 频率: 每年1次(监管要求)
├── 方式: 在监管机构监督下执行全流程切换
├── 内容: 从故障检测到服务恢复全流程
├── 参与: 全行 + 监管机构
└── 目的: 满足监管合规要求

演练效果评估指标:
├── 实际RTO vs 目标RTO
├── 实际RPO vs 目标RPO
├── 业务验证通过率(关键交易成功率)
├── 问题发现数(演练中发现的问题)
└── 改进闭环率(上次演练问题的修复比例)

对比分析

高可用架构模式对比

维度主备(Active-Standby)同城双活异地多活单元化+异地多活
架构复杂度极高
资源利用率50%(备机闲置)80-100%100%100%
RTO5-30分钟1-5分钟秒-分钟级秒级
RPO同步:0 / 异步:>000或接近00(单元内)
切换复杂度低(已在服务)低(流量调度)低(流量调度)
数据一致性简单(单写)中等复杂(多写冲突)中等(单元内自治)
适用规模中小银行大型银行超大型/互联网银行蚂蚁/微众级别
成本1.5x2x2.5-3x3-4x
典型案例多数城商行工行/建行蚂蚁金服蚂蚁LDC架构
演练难度中(需要切换)低(已在双活)

金融高可用 vs 互联网高可用

维度金融系统互联网系统
一致性要求强一致性(资金零差错)最终一致性(可接受短暂不一致)
RPO容忍度RPO ≈ 0(零数据丢失)RPO可以接受秒级丢失
切换决策半自动(需要人工审批)全自动(自动故障转移)
监管要求银保监会/央行标准无强制要求
演练要求年度监管演练(强制)自主决定
故障容忍零容忍(资金安全)可以容忍(体验降级)
设计哲学宁可停服务不能数据错宁可数据暂时不一致不能停服务

架构设计实操

设计目标

为一家股份制银行核心交易系统设计两地三中心高可用方案。

要求:

  • RTO < 15分钟(比监管要求更严格)
  • RPO = 0(零数据丢失)
  • 日常TPS: 20,000, 峰值: 50,000
  • 支持年度灾备演练
  • 在线扩缩容不影响业务

高可用架构方案

两地三中心 + 同城双活方案
━━━━━━━━━━━━━━━━━━━━━━━━

北京 (生产城市)
┌──────────────────────────────────────────────────────┐
│                                                      │
│  DC-Beijing-1 (亦庄)              DC-Beijing-2 (顺义)│
│  ┌──────────────────┐            ┌──────────────────┐│
│  │ GSLB/LB入口层    │            │ GSLB/LB入口层    ││
│  │  (50%流量)       │            │  (50%流量)       ││
│  ├──────────────────┤            ├──────────────────┤│
│  │ 应用层 (Active)  │            │ 应用层 (Active)  ││
│  │ ┌────┐┌────┐    │            │ ┌────┐┌────┐    ││
│  │ │App ││App │... │            │ │App ││App │... ││
│  │ └────┘└────┘    │            │ └────┘└────┘    ││
│  ├──────────────────┤            ├──────────────────┤│
│  │ 中间件层         │            │ 中间件层         ││
│  │ Redis Cluster    │◄──同步──►│ Redis Cluster    ││
│  │ RocketMQ         │◄──同步──►│ RocketMQ         ││
│  ├──────────────────┤            ├──────────────────┤│
│  │ 数据库层         │            │ 数据库层         ││
│  │ OceanBase        │◄──Paxos──►│ OceanBase        ││
│  │ (Zone1: Leader)  │  同步复制  │ (Zone2: Follower)││
│  └──────────────────┘            └──────────────────┘│
│        距离: 60km, 延迟: <2ms                        │
│        网络: 双路万兆专线                             │
└──────────────────────────────────────────────────────┘
         │
         │ OceanBase异步复制 (延迟: 50-200ms)
         │ RocketMQ异步复制
         ▼
上海 (灾备城市)
┌──────────────────────────┐
│  DC-Shanghai (灾备中心)   │
│  ┌──────────────────────┐│
│  │ 应用层 (Warm Standby)││
│  │ 已部署,定期预热      ││
│  ├──────────────────────┤│
│  │ 中间件层 (同步中)    ││
│  ├──────────────────────┤│
│  │ OceanBase            ││
│  │ (Zone3: Follower)    ││
│  │ 异步复制,延迟秒级   ││
│  └──────────────────────┘│
│  距离: 1200km            │
│  网络: 双路专线          │
└──────────────────────────┘

OceanBase跨机房部署

OceanBase Paxos三副本部署
━━━━━━━━━━━━━━━━━━━━━━━━

Zone1 (北京亦庄): 包含Paxos Leader
Zone2 (北京顺义): Paxos Follower (同步)
Zone3 (上海):     Paxos Follower (异步)

写入流程:
1. 客户端写请求 → Zone1 Leader
2. Leader写WAL日志
3. Leader同步复制到Zone2(同城,<2ms)
4. Zone1 + Zone2 = 2/3多数派确认 → 提交成功
5. 异步复制到Zone3(上海)

关键配置:
├── 多数派: 2/3 (Zone1+Zone2即可,不依赖Zone3)
├── 同城RPO: 0 (Zone1故障,Zone2有完整数据)
├── 异地RPO: 秒级 (Zone1+Zone2都故障,Zone3有秒级延迟)
└── 分区策略: 按Locality配置Leader分布

故障场景:
├── Zone1故障 → Zone2升为Leader(秒级切换),RPO=0
├── Zone2故障 → Zone1继续服务(单副本模式)
├── Zone1+Zone2故障 → Zone3升为Leader,RPO=异步延迟
└── 网络分区(北京-上海) → 北京继续服务(2/3多数派)

切换流程设计

# 灾备切换流程(Runbook)
disaster_recovery_runbook:
  name: "核心交易系统灾备切换"
  version: "2.1"
  last_updated: "2026-05-10"

  detection:
    auto_detection:
      - heartbeat_timeout: 30s (连续3次)
      - health_check_failure: 5 (连续5次)
      - db_connection_failure: 10s
    confirmation_period: 120s  # 等待2分钟确认非误报

  decision:
    scenario_1_single_node:
      action: "集群内自动故障转移"
      approval: "自动"
      rto_target: "<30s"

    scenario_2_dc_failure:
      action: "同城切换(DC-1 → DC-2)"
      approval: "技术总监确认(5分钟内)"
      steps:
        - "确认DC-1不可恢复(预估恢复时间>RTO)"
        - "确认DC-2数据库状态(OceanBase Leader已在Zone2)"
        - "DNS/LB切换100%流量到DC-2"
        - "验证关键交易(5笔测试转账)"
        - "通知业务部门"
      rto_target: "<10min"
      rpo: "0"

    scenario_3_city_disaster:
      action: "异地切换(北京 → 上海)"
      approval: "CTO + 业务副总裁审批(10分钟内)"
      steps:
        - "确认北京两个DC均不可恢复"
        - "评估上海Zone3数据延迟量"
        - "OceanBase强制Zone3升为Leader"
        - "启动上海应用集群(Warm→Active)"
        - "全局DNS切换到上海入口"
        - "执行完整业务验证(50笔测试交易)"
        - "通知监管机构"
        - "启动数据补偿流程(如果RPO>0)"
      rto_target: "<15min"
      rpo: "秒级(异步复制延迟)"

  post_recovery:
    - "持续监控上海运行状态(24小时)"
    - "故障根因分析(24小时内)"
    - "制定回切计划(48小时内)"
    - "向监管提交事件报告(24小时内)"
    - "客户通知(如果有影响)"

ADR: 高可用架构决策

# ADR-041: 核心交易系统高可用架构

## 状态
ACCEPTED

## 上下文
股份制银行核心交易系统需要满足RTO<15min、RPO=0的高可用要求,
同时需要支持年度灾备演练和在线扩缩容。

## 决策
采用"两地三中心 + 同城双活 + OceanBase Paxos三副本"方案。

架构要点:
1. 同城双活: 北京两个DC各承担50%流量,任一DC故障自动切换
2. 数据同步: OceanBase Paxos三副本(2个同城+1个异地)
3. 同城RPO=0: Paxos多数派确认不依赖异地(2/3=同城两个Zone)
4. 异地RPO≈0: 异步复制延迟通常<1秒
5. 切换策略: 同城自动切换 + 异地半自动切换

## 不选异地多活的原因
- 异地多活要求业务做单元化改造,当前核心系统改造成本太高
- 跨地域数据一致性在资金交易场景极难保证
- 两地三中心已满足监管要求,且技术成熟度更高

## 后果
- 正面: 满足RTO<15min/RPO=0要求
- 正面: 同城双活提高了日常资源利用率
- 正面: OceanBase Paxos三副本简化了数据同步管理
- 负面: 异地灾备仍有秒级RPO风险(极端场景)
- 负面: 同城双活增加了应用层的复杂度
- 演进: 未来可逐步向单元化+异地多活演进

AI增强实践

AI在高可用系统中的应用

AI增强的高可用体系
━━━━━━━━━━━━━━━━━

1. AI驱动的故障预测(Predictive HA)
   ├── 基于历史监控数据训练故障预测模型
   ├── 提前30分钟-2小时预警潜在故障
   │   ├── 磁盘SMART指标异常 → 预测磁盘即将损坏
   │   ├── 内存错误率升高 → 预测即将OOM
   │   ├── 网络丢包率增加 → 预测网络设备故障
   │   └── 数据库慢查询增多 → 预测性能瓶颈
   ├── 自动触发预防性措施
   │   ├── 自动迁移VM到健康节点
   │   ├── 自动扩容应用实例
   │   └── 自动切换到备用数据库
   └── 从"被动响应"转变为"主动预防"

2. AI辅助故障诊断
   ├── 故障发生时自动收集所有相关日志/指标
   ├── AI关联分析(Log → Trace → Metric)
   ├── 自动生成根因分析报告
   ├── 推荐修复方案(基于历史Similar事件)
   └── 将MTTR(平均修复时间)缩短50%+

3. 智能灾备切换决策
   ├── AI评估"原地恢复"vs"切换灾备"的最优策略
   ├── 基于当前系统状态预测切换成功概率
   ├── 模拟切换影响(受影响用户数/交易量)
   └── 辅助决策者快速做出准确判断

4. AI驱动的混沌工程
   ├── AI分析系统架构,自动发现薄弱点
   ├── 自动生成混沌实验方案(针对薄弱点)
   ├── 智能控制爆炸半径
   └── 自动评估实验结果并生成改进建议
# AI故障预测引擎
class AIFaultPredictor:
    """基于时序异常检测的故障预测"""

    def predict_failures(self, metrics_window: pd.DataFrame) -> list:
        """
        输入: 过去24小时的系统指标数据
        输出: 未来2小时内可能发生的故障列表
        """
        predictions = []

        # 1. 磁盘故障预测
        disk_health = self.disk_model.predict(
            metrics_window[['disk_io_latency', 'smart_errors', 'disk_usage']]
        )
        if disk_health.failure_probability > 0.8:
            predictions.append(FaultPrediction(
                type='DISK_FAILURE',
                probability=disk_health.failure_probability,
                time_to_failure=disk_health.estimated_ttf,
                affected_node=disk_health.node_id,
                recommended_action='迁移数据到备用磁盘,更换故障磁盘'
            ))

        # 2. 数据库性能退化预测
        db_trend = self.db_model.predict(
            metrics_window[['query_latency_p99', 'active_connections',
                          'lock_waits', 'buffer_pool_hit_ratio']]
        )
        if db_trend.degradation_probability > 0.7:
            predictions.append(FaultPrediction(
                type='DB_PERFORMANCE_DEGRADATION',
                probability=db_trend.degradation_probability,
                time_to_impact=db_trend.estimated_tti,
                root_cause=db_trend.likely_cause,
                recommended_action=db_trend.recommended_fix
            ))

        return predictions

与Web3/DeFi的关联

金融高可用 vs 区块链可用性

维度传统金融高可用区块链可用性
架构模式两地三中心/异地多活全球数万节点分布式
单点故障需要精心设计消除天然无单点故障(去中心化)
数据冗余2-3副本数千-数万全节点副本
故障恢复需要灾备切换自动(节点宕机不影响网络)
一致性强一致(Paxos/Raft)概率性终结(区块确认)
停机维护需要窗口无需停机(协议升级通过硬分叉)
99.999%极难达到以太坊主网接近100%可用
成本极高(2-4x基础设施)由全球节点共同承担

DeFi的高可用设计

DeFi协议的高可用考量
━━━━━━━━━━━━━━━━━━━

1. 智能合约层: 天然高可用
   ├── 部署在区块链上,全球节点冗余
   ├── 无需灾备(区块链本身就是"异地多活")
   └── 风险: 合约bug无法修复(不可变性的代价)

2. 前端/API层: 需要高可用设计
   ├── Uniswap前端: IPFS分布式托管
   ├── Aave前端: CDN + 多区域部署
   ├── API(如Alchemy/Infura): 多节点负载均衡
   └── 风险: Infura宕机导致大量DApp不可用(2020年事件)

3. 预言机层: 高可用是安全关键
   ├── Chainlink: 多节点聚合(去中心化预言机)
   ├── 单个节点故障不影响价格Feed
   ├── 风险: 极端行情下预言机延迟(如2020年3月12日)
   └── 设计: 偏差阈值触发更新 + 心跳更新

4. L2网络: 需要考虑L1回退
   ├── L2 Sequencer宕机 → 用户可以通过L1强制退出
   ├── Optimistic Rollup: 7天挑战期是"终极灾备"
   └── 设计: Escape Hatch(逃生舱)机制

传统金融可以学习区块链的高可用思路:
├── 去中心化: 消除对单一供应商/单一机房的依赖
├── 自愈能力: 节点自动加入/退出,无需人工干预
├── 透明性: 所有节点状态公开,便于监控
└── 不可变性: 数据一旦确认就不可能丢失

今日思考

深度问题1

"异地多活在金融系统的最大挑战是什么?"

最大挑战是跨地域的数据一致性。资金交易要求强一致性,但跨地域延迟(50-200ms)使得同步复制的性能不可接受。解决方案是单元化——将用户分配到固定单元,单元内强一致(本地事务),跨单元通过异步消息处理。但这要求业务可以按用户维度分片,且跨单元操作(如跨地域转账)需要分布式事务或补偿机制。蚂蚁金服通过LDC单元化架构实现了异地多活,但改造历时3年以上。

深度问题2

"如何做到RPO≈0?"

RPO=0意味着不丢失任何已提交的数据。技术上通过同步复制实现——每次写入必须等待至少一个副本确认。OceanBase使用Paxos协议,写入需要多数派(2/3)确认,保证即使一个副本故障数据也不丢。但同步复制的代价是:(1)写入延迟增加(+2-10ms);(2)如果副本不可用,可能导致写入阻塞。权衡:在同城双活场景下延迟代价可接受(<3ms),但异地同步复制延迟太高(>50ms)不实际。因此通常同城RPO=0(同步),异地RPO≈0(异步但延迟很小)。

深度问题3

"以太坊的可用性为什么远超传统金融系统?"

以太坊主网自2015年上线以来几乎100%可用(除了少数次短暂的共识问题)。原因:(1)极度冗余——全球数十万节点,任何子集故障不影响整体;(2)无状态节点——新节点可以快速同步加入;(3)去中心化——没有"单一运营方"可以导致全面宕机。但代价是:性能低(15TPS)、一致性弱(需要等待多个区块确认)、升级困难(需要社区共识)。传统金融系统为了高性能和强一致性,必须使用中心化或半中心化架构,这天然增加了单点故障风险。


面试题准备

面试题1:异地多活在金融系统的最大挑战是什么?

30秒版本: 最大挑战是跨地域数据一致性与性能的矛盾。资金交易要求强一致性,但跨地域网络延迟(50-200ms)使同步复制不现实。解决方案是单元化架构——将用户分配到固定地域的单元,单元内强一致,跨单元通过异步消息处理。但这要求业务可按用户维度分片,改造成本极高。

2分钟版本: 异地多活在金融系统面临三个核心挑战:

第一,数据一致性。这是最根本的挑战。资金交易不能接受最终一致性——如果用户在北京扣了100元,上海的副本还没更新,用户又在上海消费100元,就会出现超额透支。传统解决方案是单元化:将用户绑定到一个地域,该用户的所有写操作都在这个地域完成,保证本地强一致。跨地域操作通过分布式事务或异步补偿处理。

第二,流量路由。需要一个全局路由层,将用户请求准确路由到其归属的单元。路由规则一旦设计不当(如路由抖动),会导致数据写入错误的单元。蚂蚁金服的实践是在请求中携带用户ID的Zone信息,通过多层路由确保准确性。

第三,故障域隔离。异地多活的一个核心假设是"一个地域故障不影响其他地域"。但如果共享了某些全局组件(如统一的配置中心、统一的消息队列),这些全局组件的故障会导致所有地域同时受影响。因此需要确保每个单元完全自治,全局组件必须有独立的高可用方案。

实际经验中,蚂蚁金服从传统架构改造到LDC单元化异地多活花了3年以上,涉及数百个系统的改造。这不是一个轻易可以做的决策。

可能的追问

  • Q:如果不做异地多活,两地三中心够不够?
  • A:对大多数银行来说,两地三中心配合同城双活已经能满足监管要求(RTO<30min, RPO≈0)。异地多活的核心价值是提高资源利用率和进一步降低RTO,但代价是架构复杂度大幅增加。建议先做好两地三中心,在此基础上逐步向异地多活演进。

面试题2:如何做到RPO≈0?

30秒版本: 通过同步复制——每次数据写入必须等待至少一个副本确认后才返回成功。具体实现上,OceanBase使用Paxos协议要求多数派(2/3)确认,CockroachDB使用Raft协议。在同城场景下(<3ms延迟)性能代价可接受。异地场景下同步复制延迟过高,通常用异步复制+最小化延迟的策略,RPO从"=0"变为"≈0"(通常秒级)。


学习资源

资源类型推荐理由
《银行信息系统灾难恢复规范》(银保监)监管文件理解中国金融灾备的监管要求
蚂蚁金服异地多活架构(InfoQ)技术文章最详细的金融异地多活实践
OceanBase Paxos多副本文档技术文档理解金融级数据同步
Netflix Chaos Engineering书籍/实践混沌工程方法论
《Site Reliability Engineering》(Google)书籍SRE高可用方法论
AWS Multi-Region Architecture白皮书异地多活的云原生实践

明日预告

Day 42: 案例分析(3):Thought Machine Vault — 深入分析这家前Google工程师创立的云原生核心银行公司:不可变分类账(Immutable Ledger)、Smart Contract(Vault Contract)、事件溯源架构、Kubernetes原生部署。理解下一代核心银行的架构设计哲学。