1个原理
大道至简-异地多活核心原理
异地多活本质上是 CAP 中的AP
大道至深-CAP
粒度
CAP 关注的粒度是数据,而不是系统,需要根据不同业务的数据特点来设计异地多活
延迟
CAP 是忽略网络延迟的 ,但工程落地不可能做到零延迟
分区容忍
C和A只能取1个是在发生分区的时候,正常运行情况下,可以同时满足 CA
补救
放弃 != 无为,需要为分区恢复后做准备,包括人工修复数据
3大原则
原则1-只保证核心业务
不同业务的数据特性不同,无法全部做到异地多活
原则2-只能做到最终一致性
复制肯定有时间窗,抛弃实时一致性的幻想,PACELC 理论
原则3-只能保证绝大部分用户
不要为了0.01%的用户,而影响了99.9%的用户
4个步骤
业务分级
将业务按照某个维度进行优先级排序,优先保证TOP3 业务异地多活
维度 | 说明 |
---|---|
访问量 | 登录>注册>修改密码 |
核心场景 | 聊天>朋友圈>摇一摇 |
收入来源 | 订单>搜索>编辑 |
数据分类
分析 TOP3 中的每个业务的关键数据特点,将数据分类
维度 | 说明 |
---|---|
数据修改量 | 数据被修改的数量和频率,包括新增、删除、修改 |
一致性 | 数据的一致性要求,例如:强一致性(余额、库存),最终一致性(动态) |
唯一性 | 数据的唯一性要求,例如:全局唯一(用户ID)、可重复(昵称) |
可丢失性 | 数据是否可丢失,例如:不可丢失(账户余额)、可丢失(微博、密码) |
可恢复性 | 数据是否可恢复,例如:用户恢复(微博)、系统提供恢复(密码找回)、内部恢复(编辑和运营重发) |
数据同步
针对不同的数据分类设计不同的数据同步方式
多管齐下,“不择手段”,不要局限于存储系统同步
数据同步技巧
数据修改量 | 一致性 | 唯一性 | 可丢失 | 可恢复 | 同步技巧 | |
---|---|---|---|---|---|---|
账号 | 小 | 强一致性 | 全局唯一 | 否 | 否 | 数据库同步+消息队列同步 |
密码 | 小 | 最终一致性 | 不涉及 | 是 | 是 | 数据库同步 |
余额 | 大 | 强一致性 | 不涉及 | 否 | 否 | 数据库同步 |
库存 | 大 | 强一致性 | 不涉及 | 否 | 否 | 数据库同步 |
微博、资讯、朋友圈动态 | 大 | 最终一致性 | 可重复 | 是 | 是,用户或运营重发 | 存储系统同步 |
Session | 大 | 最终一致性 | 全局唯一 | 是 | 是,系统重新生成 | 重新生成+回源读取 |
异常处理
针对极端异常的情况,考虑如何处理,可以是技术手段或非技术手段
业务兼容
体验不好 优于 无法体验
- 数据短时间不一致:业务有损,例如微博、朋友圈
- 数据无法获取:转账申请,支付核对中
事后补偿
少量用户损失,用钱解决
- 礼包、红包
- 礼物、物品(暴雪炉石回档补偿)
- 保险赔偿
人工修正
尽力而为,减少损失
- 人工订正数据,达到最终一致性
- 重要事情说三遍:日志、日志、日志
5个技巧
消息队列同步
适合全局唯一的数据,因为可以覆盖;不适合余额之类的数据,因为数据修改无法做到幂等性
库存拆分
事务合并
例如:游戏玩家异地充值100,消费60,即使 IDC-B 的业务服务器不知道玩家的实际余额(在 IDC-A 的数据库中),业务也是可以继续处理的,具体实现逻辑如下:
- 正常情况下通过数据库同步来同步余额,对应上图的 IDC-A 到 IDC-B 的“余额同步”
- 异常情况下,IDC-A 机房挂掉,余额同步中断,可能会导致 IDC-A 和 IDC-B 的数据不同步,例如图中两个余额表的余额,IDC-A 是 30,IDC-B 是65
- 玩家到 IDC-B 想消费60块,无论 IDC-B 的余额表中是大于还是小于60,都不能直接消费,因为无法判断这个余额数据是否一致
- 玩家到 IDC-B 先充值100块,再消费60块,无论 IDC-B 的余额表中是大于还是小于60,都是允许的,此时 IDC-B 在临时事务表中记录两个事务
- IDC-A 恢复后,IDC-B 将临时事务表中的事务发给 IDC-A,IDC-A 进行合并,合并后的真实余额是70元,然后再通过“余额同步”这个通道将70元余额同步给 IDC-B 的余额表
实时改异步
适当容忍
业务上稍微放开一些约束,例如:电话会议系统允许欠费也能发起会议