异地多活概念

异地多活状态

  • 正常情况下,用户无论访问哪一个地点的业务系统,都能够得到正确的业务服务。
  • 某个地方业务异常的时候,用户访问其他地方正常的业务系统,能够得到正确的业务服务。

异地多活的复杂度

  • 系统复杂度会发生质的变化,需要设计复杂的异地多活架构。
  • 成本会上升,毕竟要多在一个或者多个机房搭建独立的一套业务系统。

是否异地多活

  • 根据损失可接受度来决定是否进行异地多活
  • 常见的新闻网站、企业内部的 IT 系统、游戏、博客站点等,没有必要异地多活,损失不大
  • 共享单车、滴滴出行、支付宝、微信这类业务,就需要做异地多活了。
  • 强一致性数据,不能做跨城异地。

异地多活模式

  • 同城异区
    • 应对情况:解决单个机房出现的故障,如机房火灾、机房停电、机房空调故障等。
    • 复杂度方面:同城异区相当于同一个机房,设计更容易。
    • 专线延迟一般在 1ms~3ms。
  • 跨城异地
    • 应对情况:极端灾难,如山崩海啸台风等。
    • 复杂度方面(1):两个机房的网络传输速度会降低,延迟增加,丢包可能性增加
    • 复杂度方面(2):挖掘机把光纤挖断、中美海底电缆被拖船扯断、骨干网故障等不可控概率增大。
    • 注意:强一致性数据,不能做跨城异地,例如金融相关业务。应该也可以,但是难度更大。
    • 比如,北京到天津的专线延迟会在 10ms 之内;而北京到上海的延迟就会提高到接近 30ms;如果想要在北京和广州部署双机房,那么延迟就会到达 50ms 了。
  • 跨国异地
    • 应对情况:为不同地区用户提供服务(亚马逊购物),只读类业务做多活(搜索引擎)。
    • 从国内想要访问部署在美国西海岸的服务,这个延迟会在 100ms~200ms 左右。

异地多活优化

优先保证核心业务的异地多活

挑战

  • 实现所有业务的异地多活可能导致复杂性和成本过高。
    • 用户在 A 节点注册后节点宕机,但是数据未同步到其他节点,导致在其他节点重复注册,A 节点恢复后,手机号唯一性冲突。
    • 两个节点同时修改用户数据,导致数据冲突问题。
  • 通过时间戳判断最新会遇到全局时钟一致性问题。
  • 通过全局唯一 ID 会遇到服务本身的异地多活和一致性问题。
  • 修改核心业务规则(如一个手机号只能注册一个账号)以适应架构,改动太大,得不偿失。

解决方案

  • 聚焦核心业务。对于“用户子系统”,确定最需要保障的核心业务——“登录”。相比“注册”和“用户信息”的修改,“登录”对用户体验的影响更大,对其进行异地多活更简单。而对于其他的业务,可以不进行异地多活。

保证核心数据的最终一致性

挑战

  • 异地多活要求数据在多个地点之间同步,但物理距离导致延迟不可避免,追求所有数据的实时同步既不可行也不经济。

解决方案

  • 尽量减少异地多活机房的距离,搭建高速网络。
  • 尽量减少数据同步,只同步核心业务相关的数据。如新账号信息同步及时,账号的登录 IP 等可以晚一点。
  • 保证最终一致性,不保证实时一致性。

结合多种手段进行数据同步

挑战

  • 单纯依赖存储系统的内置同步功能可能无法满足复杂的业务需求,特别是在面对网络波动或大量数据同步时。

解决方案

  • 多样化同步方式:结合使用消息队列、二次读取/回源读取、重新生成数据等方法来增强数据同步的可靠性和效率。其中回源读取是指,判断出数据源头在哪节点上,再去真正节点读取。
  • 自定义同步机制:针对特定业务场景开发定制化的同步方案,避免过度依赖单一技术栈带来的局限性。

容忍小部分用户的体验损失

挑战

  • 尽管尽力实现了异地多活,但在极端情况下仍可能出现服务中断或数据不同步的情况,影响一小部分用户的体验。

解决方案

  • 接受有限度的服务降级:理解并接受不可能达到100%可用性的事实,通过合理的业务流程设计(如转账申请代替实时转账)来减轻负面影响。
  • 用户沟通与补偿:及时向用户通报问题,并提供适当的补偿措施,如代金券、礼包等,以维护品牌形象和服务满意度。

异地多活设计流程

  • 业务分级:访问量大的业务、核心业务、大量收入的业务
  • 数据分类:增删改的数据量和数据总量、数据中的唯一性要求、数据同步时延要求、数据可丢失性、数据可恢复能力。
  • 数据同步:存储系统同步、消息队列同步、重复生成(session)。
  • 异常处理:多数据同步方式备用、日志记录、用户补偿
    • 异常处理的目的:
      • 问题发生时,避免少量数据异常导致整体业务不可用。
      • 问题恢复后,将异常的数据进行修正。
      • 对用户进行安抚,弥补用户损失。

参考链接