我是靠谱客的博主 哭泣小松鼠,最近开发中收集的这篇文章主要介绍分布式系统CAP----数据的【最终一致性】 一、解题思路:二、最终一致性的常用做法三、实现方法说明,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

 一、解题思路:

二、最终一致性的常用做法

三、实现方法说明

3.1、两阶段提交协议 2PC

3.2、三段提交协议3PC(弥补 2PC 协议缺点)

3.3、TCC模式(Try-Confirm-Cancel)----这个像 【两阶段提交协议】

3.4、 可靠事件模式

3.5、业务补偿模式


 一、解题思路:

【最终一致性】:是指系统中的所有数据副本经过一段时间后,最终能够达到一致的状态。这里所说的一段时间,也要是用户可接受范围内的一段时间。

eg: 第一阶段----完成某项业务;第二阶段----n个dataSource的数据都进行更新并保证一定成功; 

第一阶段好说,但你如何保证第二阶段的n个dataSource更新一定都成功?比如就有1个dataSource没更新呢?你凭什么保证,如何代码控制?

  • 事务:n个dataSource要么全部更新成功,要么全部都不更新;

        eg: 两阶段提交协议,三阶段提交协议;

  • 非事务: 不用事务概念后搞不好就有某个dataSource失败的,真这样了只能补偿;

         但凭什么保证补偿一定成功?

         要么我暴力的“不停重试,直到成功”;eg:事务型消息队列

         要么“第二阶段失败的概率比较小”,我稍微补偿一下就可以;eg:补偿任务

         ps: 还有小概率真的不会成功,那怎么办?第二阶段每隔一段时间主动汇报执行结果;


二、最终一致性的常用做法

1、单数据库事务

      如果应用系统是单一的数据库,那么这个很好保证,利用数据库的事务特性来满足事务的一致性,这时候的一致性是强一致性的;

2、多数据库事务

     针对多数据库事务可以根据“二阶段提交协议”,采用spring 3.0 + Atomikos + JTA进行支持;

3、基于【事务型消息队列】的最终一致性

     业务逻辑处理成功后,提交消息,确保消息是发送成功的,之后消息队列投递来进行处理,如果成功,则结束,如果没有成功,则重试,直到成功;

    不过仅仅适用业务逻辑中,第一阶段成功,第二阶段必须成功的场景。

4、基于【消息队列+定时补偿机制】的最终一致性

     前面部分和上面基于事务型消息的队列,不同的是,第二阶段重试的地方,不再是消息中间件自身的重试逻辑了,而是单独的补偿任务机制。

    其实在大多数的逻辑中,第二阶段失败的概率比较小,所以单独把补偿任务标出来,可以更加清晰,能够比较明确的知道当前多少任务是失败的。

5、【异步回调】机制的引入

     A应用调用B,在同步调用的返回结果中,B返回成功给到A,一般情况下,这时候就结束了;

    其实在99.99%的情况是没问题的,但是有时候为了确保100%,最起码在系统设计中100%,这时候B系统再回调A一下,告诉A,你调用我的逻辑,确实成功了。

    其实这个逻辑,非常类似 “TCP协议中的三次握手” 。

6、类似【double check】机制的确认机制

    A在同步调用B,B返回成功了。这次调用结束了,但是A为了确保,在过一段时间,这个时间可以是几秒,也可以是每天定时处理,再调用B一次,查询一下之前的那次调用是否成功。

    例如A调用B更新订单状态,这时候成功了,延迟几秒后,A查询B,确认一下状态是否是自己刚刚期望的。上图中的D流程。

三、实现方法说明

3.1、两阶段提交协议 2PC

要保证一致性得有个人来做总指挥协调,单机服务的此角色是事务,分布式事务得把这个角色单独拎出来——TM;

此处注意一个概念:TM----事务协调器

分布式事务来保证数据一致性,也就是常说的两阶段提交协议(2PC,Two Phase Commitment Protocol)

第一阶段:TM联系业务相关的所有数据库,通知其进行准备;相关数据库可以应答说OK,也可以应答说 NO OK;

  1. 各数据库节点执行本地事务操作,但在执行完成后并不会真正提交数据库本地事务;
  2. 数据库只要应答了说OK,那就默认你一定都做好准备,只要提交事务,你肯定不会失败;
  3. 数据库若应答了 NO OK,那你得考虑回滚(比如做准备需要3步,前2步你都做了,删除数据库的代码已经运行了,到第3步发现做不了了,你说NO OK,那已经做的前2步是不是得回滚);

第二阶段:TM收到应答,收集综合意见决定下一步操作;若所有的数据库都OK,那就指示大家都提交事务;只要有一个数据库响应说NO OK,那就指示大家都做回退;

                  

3.2、三段提交协议3PC(弥补 2PC 协议缺点)

2PC协议缺点:

  1. 在2PC完成期间,所有的 参与者资源 和 协调者资源 都是被锁住的;
  2. 由于 TM 的重要性,一旦 TM 发生故障。参与者数据库 会一直阻塞下去;

3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有CanCommit、PreCommit、DoCommit三个阶段;

第一阶段: 跟2PC一样,只不过CanCommit是 尝试获取数据库锁,2PC不是

第二阶段:跟第一阶段差不多,只不多 协调者和参与者都引入了超时机制 (2PC中只有协调者可以超时,参与者没有超时机制);

第三阶段:跟第二阶段差不多;

这个3PC网上找的资料感觉写的不是很详细,先不深究了,知道有这么个东西就行;

3.3、TCC模式(Try-Confirm-Cancel)----这个像 【两阶段提交协议

TCC模式要求从服务提供三个接口:Try、Confirm、Cancel;

第一阶段:【主业务服务】在活动管理器中登记所有从业务服务,并分别调用所有【从业务】的try操作,所有从业务服务的try操作要么都调用成功,要么某个从业务服务的try操作失败;

第二阶段:活动管理器根据第一阶段的执行结果来执行confirm或cancel操作。如果第一阶段所有try操作都成功,则活动管理器调用所有从业务活动的confirm操作。否则调用所有从业务服务的cancel操作。

3.4、 可靠事件模式

举例: 客户成功下单---->消息代理---->支付服务,支付成功---->消息代理---->下单成功待出库

这个感觉像消息中间件的模式,放这怎么感觉有些混乱,我认为这可能是因为可靠事件模式属于【事件驱动架构】,事件来了这样解决更合适,消息中间件是解决此问题的一个工具,但还得在消息中间件上加一层【可靠】保证;

那么单纯这样做有哪些【不可靠】的地方呢?

  1. 某个服务在更新了业务实体后发布事件却失败
  2. 虽然服务发布事件成功,但是消息代理未能正确推送事件到订阅的微服务
  3. 接受事件的微服务重复消费了事件

【可靠事件模式】解决了上述的不可靠问题,具体怎么解决的此处不细说;

3.5、业务补偿模式

举例:旅行社给你的行程【预定航班】--》【预定酒店】--》【预定火车】,若【预定火车】失败,那么取消之前预订的酒店、航班即为【补偿过程】;

【补偿模式】使用一个额外的协调服务来协调各个需要保证一致性的微服务,协调服务按顺序调用各个微服务,如果某个微服务调用异常就取消之前所有已经调用成功的微服务;

最后

以上就是哭泣小松鼠为你收集整理的分布式系统CAP----数据的【最终一致性】 一、解题思路:二、最终一致性的常用做法三、实现方法说明的全部内容,希望文章能够帮你解决分布式系统CAP----数据的【最终一致性】 一、解题思路:二、最终一致性的常用做法三、实现方法说明所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(94)

评论列表共有 0 条评论

立即
投稿
返回
顶部