从「备份」到「多活」的容灾演进

容灾的三代演进:冷备(备份机房平时不跑流量——故障时切换——冷备的两大问题:切换慢(开机、预热、DNS 生效——分钟到小时级)、备份是空的(平时没跑流量——切换后不知道能不能扛住——「没验证过的容灾」风险);热备(备份机房跑着但只读——故障时切写——热备的资源浪费(一半的资源平时闲置);多活(所有机房同时对外服务(读写都活——「多活」的本质:容灾资源不再闲置——「平时多活,故障时互备」**——多活是容灾的终局形态,也是工程复杂度的顶点。
这篇拆解多活架构的选择与工程账:同城双活与异地多活的差异、多活的前置条件、以及「单元化」的终极设计。
同城双活 vs 异地多活:两个层级的选项
同城双活:同一城市两个机房(距离 10-50 公里——「同城」的网络条件:延迟 1-3ms(接近同机房——「同城双活的优势」:数据同步的性能损耗小(跨机房的复制延迟可接受——「同步复制」的可行性(同城的光纤延迟允许同步复制(「半同步复制」的可行性——数据一致性接近单机房——「同城双活的容灾范围」:防机房级故障(火灾、断电、网络中断——「同城防不了」:城市级灾难(地震、洪水——「同城的局限」是地理的。异地多活:跨城市多个机房(北京+上海+深圳——「异地」的网络现实:延迟 30-50ms+(跨城的物理极限(光速——「异地同步」的代价:同步复制的延迟不可接受——「异步复制」的选择——数据一致性的弱化(「异地多活的数据一致性」是最大的工程挑战——「异地多活的容灾范围」:城市级灾难——「异地多活的成本」**:至少两倍的基础设施+复杂的数据同步。
选择的关键:RTO 与 RPO 的目标(「RTO」(恢复时间目标——多长时间恢复、「RPO」(恢复点目标——丢多少数据——「同城双活」:RTO 分钟级、RPO 接近零(同步复制)、「异地多活」:RTO 分钟级、RPO 秒到分钟(异步复制——「RPO」的容忍度决定架构——业务能接受丢几秒数据吗(支付业务不能——支付要强一致(「强一致的代价」——资金数据的跨城强一致(延迟与成本——「业务分级的多活」:核心资金数据同城强一致、一般数据异地多活——「按数据分级的多活」是务实的架构。
多活的前置条件:不是所有系统都能多活
前置条件一:流量的可路由。流量必须能按用户/地域路由到指定机房(「路由的维度」:按用户 ID 哈希、按地理位置、按业务线——「路由的依据」与「数据的归属」要一致(用户 X 的流量路由到 A 机房、用户 X 的数据在 A 机房——「归属一致」是多活的前提——路由错了=读不到数据(「路由与数据的一致」是多活架构的灵魂约束。前置条件二:数据的分区。数据必须能按同样的维度分区(「数据分片」的多活化(用户 ID 的分片在多活下的延伸——「分片的归属机房」(每个数据分片有一个「主归属机房」——「归属机房」的写入权——「一写多读」的多活模型(每个机房对自己的数据有写权、对其他机房的数据只读——「单元化(set 化)」的思想——「单元」=「一组机房+一批用户+对应的数据」——「单元化」是多活架构的终局设计(蚂蚁金服的 LDC(单元化部署)——「单元的封闭性」:一个单元内的业务闭环(读写都在本单元完成——「单元封闭」的实现:数据按单元分片、流量按单元路由、「单元间零依赖」——「跨单元调用」的最小化——依赖越少、故障的隔离越干净。前置条件三:全局服务的独立。有些服务无法按单元拆(「全局服务」(全局唯一 ID 发放、全局配置、全局库存——「全局服务」的处理:全局 ID 的话段发放(每个单元一段 ID 库——「号段的单元化」(分布式 ID 篇的号段模式在多活的延伸——全局库存的问题(「全局库存」的难题(一个商品的总库存是全局的——「库存的多活」方案:库存的分段预分配(每个单元一段库存——「预分配」的回收与再平衡——「全局状态」的多活是架构的皇冠难题(账户余额、全局库存、秒杀配额——「状态不可分」的业务不适合多活——多活架构的适配性评估要先做。
graph TD
A[多活三前置] --> B[流量可路由: 路由与数据归属一致]
A --> C[数据可分区: 单元化 set<br/>一写多读 单元封闭]
A --> D[全局服务独立: 号段发放+库存分段<br/>状态不可分的业务不适合多活]
多活的工程账:成本、一致性与演练
多活的成本账:基础设施翻倍(至少两个完整机房——「翻倍」的真实成本(不是 1.5 倍是 2 倍(每个机房都要能独立承载全量——「N+1 容量」的设计(每个机房都要有余量承接另一个机房的流量——「双活的双倍」是容灾的保险费——「保险费」的价值观(业务中断的损失 vs 多活的成本——「损失评估」决定架构投入(年交易额 10 亿的业务、停机一小时的损失——「停机损失」的量化是多活决策的第一步。一致性的工程账:跨城数据同步的延迟(30-50ms 的同步延迟——「同步的架构」(binlog 的跨城复制(DTS 类工具——「复制延迟」的用户感知(写入后立刻读——读到了旧数据——「写后读」的一致性(「写后读」的解决:读写路由到同一机房(「会话粘连」(用户会话粘在写入机房——「粘性路由」的会话设计——「粘住」的时间窗(复制完成前的粘连。演练的强制:多活的「故障演练」是常态(「演练」的常态化——定期拔机房(「拔机房」的演练(真实切断一个机房的流量——「拔机房的勇气」(演练的彻底性——「演练发现」的问题清单(路由的切换、数据的同步、业务的降级——「不演练的多活是纸面多活」**——切换的能力只有演练能验证。
多活的进阶:流量路由的精细设计与「多活的数据一致性」
多活架构的进阶:流量路由的精细设计与跨机房数据一致性的治理。「流量路由」的精细设计:「路由层」的架构:全局路由的组件(DNS 的粗粒度+接入层的细粒度——「路由的决策点」:DNS(机房级)、网关(用户级)、微服务(调用级——「多级路由」的协同——「路由的一致性」:路由决策与数据归属的实时一致(「路由表的权威源」——路由表的更新与数据迁移的协同——「路由切换的原子性」(「切流」的原子性(切流的过程中的数据访问——「切流的暂停写入」策略——「切流窗口」的一致性保护。「单元化的细化」:「单元的闭环度」:单元内的调用占比(「闭环率」的指标——「跨单元调用」的治理(跨单元的延迟与故障传染——「闭环率」的提升路径(依赖的本地化——「全局服务的单元化改造」(配置中心、ID 发放的单元化——「单元化的深度」决定多活的自治性。「跨机房数据一致性」的治理:「同步延迟」的治理:跨城复制的延迟(30-50ms——「延迟的监控」——「写后读」的解决方案:会话粘连(「粘连的实现」(网关层的会话路由——「粘连的时长」(复制延迟的时间——「粘连的失效」(机房故障时的粘连失效——「粘连与容灾的冲突」(粘连到故障机房——「粘连的故障切换」(机房故障时粘连解除——「粘连的动态调整」。「冲突的检测与处理」:「双活写的冲突」(两机房同时写同一数据——「冲突的避免」(归属机房的唯一写权——「归属切换时」的冲突窗口——「冲突的检测」(版本号/时间戳——「冲突的处理策略」(最后写入胜——「LWW」的数据丢失风险——「业务级冲突处理」(合并策略——「冲突处理」是双活写的深水区——「避免写冲突」优于「处理写冲突」——归属清晰是避免冲突的根本。多活的进阶总结:流量路由的精细设计(多级路由协同、切流的原子性)+单元化的深化(闭环率、全局服务改造)+数据一致性的治理(会话粘连、写冲突的避免优先)——多活的成熟度指标:「闭环率」与「切流的原子性」——「单元越封闭、切流越原子,多活越真」——「纸面多活」到「实战多活」的距离,全在这两个指标里。
小结
多活架构的工程账:同城双活(10-50km 延迟小——同步复制可行、防机房级故障——RPO 近零);异地多活(跨城延迟——异步复制、RPO 秒到分钟——防城市级灾难);三个前置条件(流量可路由且与数据归属一致、数据可分区到单元(单元化 set 的终局设计)、全局服务可独立(不可分的业务不适合多活——按数据分级的多活是务实解);工程账(双倍的基础设施——「保险费」的价值观由停机损失量化、写后读的一致性——会话粘连的解决、拔机房演练的强制——不演练的多活是纸面多活)。给架构师的决策框架:多活不是技术选择,是业务选择——先用「停机损失」量化业务对可用性的支付意愿、再评估业务数据是否「可分区」——两者都过关才进多活——「多活」是容灾的终局,但不是每个业务的必经之路——同城双活+异地冷备的组合,对多数业务已是「够好的容灾」。
多活的每一分复杂度,都是用「可用性」换来的——先算清可用性值多少钱,再决定付多少复杂度。
读者留言
COMMENTS 暂无还没有留言,来说第一句?