优化背景
当前产品业务服务创建链路较长,内部有很多数据实体需要在创建链路中同步创建,并且部分是通过远程服务的方式进行的,不可避免的会由于调用超时或者底层服务失败导致创建的实体不完整,从而影响部分功能。
问题原因
- 根本原因
- 分布式系统存在必然的数据一致性问题(此处特指跨表数据一致性)
- 产生原因
- 代码逻辑Bug
- 并发场景处理不当
- 幂等处理不当
- 基础组件(网络、数据库、中间件)故障
- 跨系统间缺乏原生的一致性保障
CAP理论
- CAP理论是目前分布式系统中的处理分布式事务的理论基础。主要是在目前分布式系统中都无法同时满足如下三个属性:
- 一致性(Consistency):多个服务的数据需要保持在同一时刻的数据一致性。
- 可用性(Availability):指单个系统提供的服务需要一直保持可用状态,对于每一个请求,都能及时的响应,超时或不无响应则认为系统不可用。
- 分区容错性(Partition Tolerance):分布式系统再遇到任何网络分区故障时,仍能够保证对外提供满足一致性和可用性的服务,除非整个网络环境发生故障。
BASE理论
- 核心思想 - 即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。
- 基本可用(Basically Available):指分布式系统在出现不可预知故障的时候,允许损失部分可用性。注意,这绝不等价于系统不可用。比如:
- 响应时间上的损失。正常情况下,一个在线搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障,查询结果的响应时间增加了1~2秒
- 系统功能上的损失:正常情况下,在一个电子商务网站上进行购物的时候,消费者几乎能够顺利完成每一笔订单,但是在一些节日大促购物高峰的时候,由于消费者的购物行为激增,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面。
- 软状态(Soft State):软状态指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
- 最终一致(Eventually Consistent):最终一致性强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
技术方案
- 最大努力 - 推荐(成本较低、效果可以接受)
- 在调用Service B超时或失败时进行重试:
- 同步调用,捕获异常重新调用Service B
- 异步消息,捕获异常发送延迟消息重新调用Service B
- 异步线程,捕获异常开启异步线程重新调用Service B
- 最大重试次数之后则触发报警,人工干预
- 最大努力 - 异步消息
- 当事务请求调用服务A时,如果服务A的操作执行失败了,那么直接事务执行失败
- 如果执行服务A的事务成功了,但是执行服务B的事务失败了,先将失败的请求落地(请求参数和被调用方信息入到消息表),然后将请求抛到消息队列中去进行重试,通过消息队列的ACK机制,保证重试消息最终可以被消费成功。
- 例如重试次数是3次,每次的重试的时间间隔不一样(退避算法),重试三次之后如果消息还没有被ACK,那么就直接发送预警通知给开发人员,进行人工干预。
- 如果发送消费失败了,还有定时任务去定时刷数据库里的消息表,来保证消息一定会被发送。
- 分布式事务 - 不推荐(成本高、复杂度高)
- 2PC-XA
- 3PC
- TCC
- Saga
- 业务兜底方案
- 业务一致性核对平台
- 数据核对与订正
- 监听drc消息
- 监听业务消息
- 监听drc消息
方案设计
- 设计思考
- 不管使用何种一致性方案,很难保障100%的一致性,人为干预是最有效的、也是最后的保障
- 正常的分布式系统中的故障概率总归是小概率,我们需要思考成本
- 重要的业务需要额外的数据检查、核对、兜底方案
- 对现有无侵入才能更好的保障业务的稳定性
- 设计方案
- 实时业务核对系统(Real-time Checking System)
- 设计要点
- 实现秒级核对
- 尽量减少数据库查询
- 核对数据变更,而非核对数据快照
- 简单灵活的接入方式
- 系统设计
- 变更数据获取(Data Fetching Layer)
- 数据核对(Data Checking Layer)
- 核对结果处理(Result Handling Layer)
- 业务流程
- 详细设计
- 变更数据获取
- 当 MySQL 产生数据变更时,高可用的binlog同步组件会获取到对应 binlog,并将其投递至 Kafka 中,以此获取变更数据的数据值用于核对。
- 变更数据获取
- 数据核对
- Data Checking Layer 负责处理接收到的数据流,包括获取特定的核对规则,接收到数据时进行暂存或比对。
- 数据对比流程
- 核对项的上游数据到达,暂存 Redis 和延迟队列。
- RCS 等待核对项的下游数据:
- 比对数据到达,进行核对,并删除 Redis key;
- 比对数据未到达,判断延迟队列中的数据。
- 延迟队列到达时间后,再次查询在 Redis 中是否有对应数据:
- 存在,则超过核对时间阈值,发送异常告警,删除 Redis key;
- 不存在,则已核对。
- 核对结果处理
- RCS的目标是及时发现数据不一致的问题,Result Handling Layer中接入企业IM机器人进行告警。