内容纲要
核心思想
不要把鸡蛋放在同一个篮子里
- 异地
- 地理位置上的不同地方
- 多活
- 服务存在多个活跃副本
标准
- 用户访问不同地点的业务副本,都能得到正确的业务服务
- 某个地方异常的时候,用户能够正确访问其他地方的服务
复杂度
- 设计复杂
- 异地多活架构涉及到很多问题,设计复杂
- 成本极高
- 在多个地区搭建服务各种成本都会成倍增加
不要想着一步登天,系统应遵循演化原则,不是所有系统都需要异地多活的,体量达不到也不需要考虑太多
架构模式
同城异区
将服务系统部署到同一个城市的不同区的多个机房。
特点
地理位置上极为接近使其传输速度延迟极低,逻辑上可以视其为同一个机房,设计复杂度比其余架构低很多,也能提供小范围区域故障后可用能力,但对大型灾难无力(地震等,但发生概率不大)。
跨城异地
将服务系统部署在不同的地理位置的城市(防地震等区域性灾难)的多个机房,保证不影响数据同步等问题的同时距离尽量远。
特点
地理位置上距离遥远带来的问题是网络传输的问题(延迟高;不可控因素多),对于延迟问题,服务的设计中必须处理数据不一致问题(对于设计金额等操作,一般不做跨城异地,最多做同城异区)。
设计技巧
核心思想:采用多种手段,保证绝大多数用户的核心业务异地多活。
保证核心业务的异地多活
- 并非所有业务都需要异地多活
- 优先实现核心业务异地多活
保证核心数据的最终一致性
- 不需要所有数据都实时同步
- 选择合适的地理位置,使其距离不会对数据一致性造成太大影响
- 搭建高速网络(要考虑成本)
- 尽量减少数据同步,只同步核心业务相关数据
- 保证最终一致性,不保证实时一致性
- 最终一致性需要根据不同的数据特征,进行差异化处理(同步时间间隔等)
采用多种手段同步数据
数据同步是异地多活架构的设计核心(大部分存储系统有同步功能)。
- 不能只依赖存储系统的同步功能
- 结合自定义的同步方案
- 消息队列方式
- 二次读取方式(A 中心生成业务数据,访问 B 时获取刚产生的业务数据失败时,访问 A 中心)
- 回源读取方式(判断数据来源,访问来源数据中心)
- 重新生成数据方式(通过其它方式访问失败时,重新生成数据)



只保证绝大多数用户的异地多活
100% 可用性目前是达不到的(Q:怎么办?A:忍着吧。)。
忍的艺术(让用户好受点):
- 挂公告
- 事后补偿
- 补充体验(牺牲一部分最优体验(通过其它方式优化阉割后的体验),保证业务稳定、可用)
设计步骤
业务分级
按照一定的标准将业务分级,挑出核心业务,只为核心业务做异地多活(降低整体复杂度和成本)。
常见分级标准
- 访问量大的业务
- 核心业务
- 产生大量收入的业务
数据分类
对核心业务的数据进行分类,识别数据的特征(数据特征影响后续设计方案)。
常见数据特征分析维度
- 数据量(包括数据本身和数据的增删改查量,数据量越大,同步延迟越高)
- 唯一性(保证多个中心数据唯一,使用唯一数据生成算法等)
- 实时性(实时性越高,方案越复杂)
- 可丢失性
- 可恢复性
数据同步
设计不同数据分类的数据同步方案。
常见数据同步方案
- 存储系统同步(简单但难定制)
- 消息队列同步(适合无事务性和时序要求的数据)
- 重复生成(适合可以重复生成的数据:Cookie、Session 等)
异常处理
再完美的同步方案也解决不了极端情况造成的数据异常(同步延迟、数据丢失)。
异常处理的目的是:
- 问题发生时,避免少量数据异常导致整体业务不可用
- 问题回复后,将数据修正
- 对用户进行安抚,弥补损失
常见异常处理措施
- 多通道同步
- 原理:采取多种方式进行数据同步(其中某种故障时,通过健康的方式同步)
- 设计关键
- 一般采用两种即可,过多成本增加很多
- 采用不同的网络连接,避免网络问题导致多个方式均失效
- 需要数据可覆盖(不同通道传输数据可以不论先后)
- 同步和访问结合
- 原理:访问异地机房通过系统接口访问
- 设计关键
- 接口访问通道和同步通道使用不同网络
- 数据有路由规则,可以根据路由规则判断访问哪个机房
- 优先读取本地数据,读取不到再通过接口访问(适合实时性要求高的数据)
- 日志记录
- 原理:用于数据恢复,记录每个关键操作及前后操作,将日志独立记录
- 日志保存方式
- 服务器上保存日志,数据库保存数据(应对单台数据库故障或宕机等)
- 本地独立系统保存日志(应对服务器和数据库同时故障的情况)
- 日志异地保存(应对机房宕机)
- 用户补偿
- 原理:最后一公里问题(系统保证 99.99% 可用,人工弥补 0.01% 损失)
- 常见措施
- 代金券、礼品、红包(需要考虑成本,谁不喜欢钱多呢?)
跨国异地
将服务系统部署在不同国家的多个机房。
特点
距离及其遥远,延迟可能高到不满足异地多活架构的访问不同地区服务得到结果正确的标准。因此,跨国异地的应用场景有别于跨区和跨城。
应用场景
- 为不同地区用户提供服务(服务系统可能不相连)
- 只读类业务做多活