点击上方 "程序员小乐"关注, 星标或置顶一起成长

每天凌晨00点00分, 第一时间与你相约

每日英文

Life is too short to wake up in the morning with regrets. So, love the people who treat you right and forget about the ones who do not.

生命太短,没留时间给我们每日带着遗憾醒来。所以去爱那些对你好的人,忘掉那些不知珍惜你的人。

每日掏心

再长的路,一步步也能走完;再短的路,不迈开双脚也无法到达。不要让太多的昨天占据你的今天。

来自:阿凡卢 | 责编:乐乐

链接:cnblogs.com/luxiaoxun/p/8832915.html

程序员小乐(ID:study_tech)第 919 次推文  图源:百度

往日回顾:某程序员动了公司的祖传代码“屎山”,半年后怒交辞职报告!

     

   正文   

一 分布式系统特点

现今互联网界,分布式系统和微服务架构盛行。业界著名的CAP理论也告诉我们,在设计和实现一个分布式系统时,需要将数据一致性、系统可用性和分区容忍性放在一起考虑。

1、CAP理论

在分布式系统中,一致性(Consistency)、可用性(Availability)和分区容忍性(Partition Tolerance)3 个要素最多只能同时满足两个,不可兼得。其中,分区容忍性又是不可或缺的。

  • 一致性:分布式环境下多个节点的数据是否强一致。

  • 可用性:分布式服务能一直保证可用状态。当用户发出一个请求后,服务能在有限时间内返回结果。

  • 分区容忍性:特指对网络分区的容忍性。

举例:Cassandra、Dynamo 等,默认优先选择AP,弱化C;HBase、MongoDB 等,默认优先选择CP,弱化A。

2、BASE 理论

核心思想:

  • 基本可用(Basically Available):指分布式系统在出现故障时,允许损失部分的可用性来保证核心可用。

  • 软状态(Soft State):指允许分布式系统存在中间状态,该中间状态不会影响到系统的整体可用性。

  • 最终一致性(Eventual Consistency):指分布式系统中的所有副本数据经过一定时间后,最终能够达到一致的状态。

二 一致性模型

数据的一致性模型可以分成以下 3 类:

  1. 强一致性:数据更新成功后,任意时刻所有副本中的数据都是一致的,一般采用同步的方式实现。

  2. 弱一致性:数据更新成功后,系统不承诺立即可以读到最新写入的值,也不承诺具体多久之后可以读到。

  3. 最终一致性:弱一致性的一种形式,数据更新成功后,系统不承诺立即可以返回最新写入的值,但是保证最终会返回上一次更新操作的值。

分布式系统数据的强一致性、弱一致性和最终一致性可以通过Quorum NRW算法分析。

三 分布式事务

分布式事务的目的是保障分布式存储中数据一致性,而跨库事务会遇到各种不可控制的问题,如个别节点宕机,像单机事务一样的ACID是无法奢望的。

1、Two/Three Phase Commit

2PC,中文叫两阶段提交。在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败。当一个事务跨越多个节点时,为了保持事务的ACID特性,需要引入一个作为协调者的组件来统一掌控所有节点(称作参与者)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交。两阶段提交的算法如下:

第一阶段:

  1. 协调者会问所有的参与者结点,是否可以执行提交操作。

  2. 各个参与者开始事务执行的准备工作:如:为资源上锁,预留资源。

  3. 参与者响应协调者,如果事务的准备工作成功,则回应“可以提交”,否则回应“拒绝提交”。

第二阶段:

  • 如果所有的参与者都回应“可以提交”,那么,协调者向所有的参与者发送“正式提交”的命令。参与者完成正式提交,并释放所有资源,然后回应“完成”,协调者收集各结点的“完成”回应后结束这个Global Transaction。

  • 如果有一个参与者回应“拒绝提交”,那么,协调者向所有的参与者发送“回滚操作”,并释放所有资源,然后回应“回滚完成”,协调者收集各结点的“回滚”回应后,取消这个Global Transaction。

两段提交最大的问题就是第3)项,如果第一阶段完成后,参与者在第二阶没有收到决策,那么数据结点会进入“不知所措”的状态,这个状态会block住整个事务。也就是说,协调者Coordinator对于事务的完成非常重要,Coordinator的可用性是个关键。

因些,我们引入三段提交,三段提交在Wikipedia上的描述如下,他把二段提交的第一个段break成了两段:询问,然后再锁资源。最后真正提交。三段提交的核心理念是:在询问的时候并不锁定资源,除非所有人都同意了,才开始锁资源。但三阶段提交也存在一些缺陷,要彻底从协议层面避免数据不一致,可以采用Paxos或者Raft 算法。

目前两阶段提交、三阶段提交存在如下的局限性,并不适合在微服务架构体系下使用:

  • 所有的操作必须是事务性资源(比如数据库、消息队列、EJB组件等),存在使用局限性(微服务架构下多数使用HTTP协议),比较适合传统的单体应用;

  • 由于是强一致性,资源需要在事务内部等待,性能影响较大,吞吐率不高,不适合高并发与高性能的业务场景;

2、Try Confirm Cancel(TCC)

一个完整的TCC业务由一个主业务服务和若干个从业务服务组成,主业务服务发起并完成整个业务活动,TCC模式要求从服务提供三个接口:Try、Confirm、Cancel。

  1. Try:完成所有业务检查,预留必须业务资源。

  2. Confirm:真正执行业务,不作任何业务检查;只使用Try阶段预留的业务资源;Confirm操作满足幂等性。

  3. Cancel:释放Try阶段预留的业务资源;Cancel操作满足幂等性。

整个TCC业务分成两个阶段完成:

第一阶段:主业务服务分别调用所有从业务的try操作,并在活动管理器中登记所有从业务服务。当所有从业务服务的try操作都调用成功或者某个从业务服务的try操作失败,进入第二阶段。

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

与2PC比较:

  • 位于业务服务层而非资源层。

  • 没有单独的准备(prepare)阶段,Try操作兼备资源操作与准备能力。

  • Try操作可以灵活选择业务资源的锁定粒度。

  • 开发成本较高。

缺点:

  • Canfirm和Cancel的幂等性很难保证。

  • 这种方式缺点比较多,通常在复杂场景下是不推荐使用的,除非是非常简单的场景,非常容易提供回滚Cancel,而且依赖的服务也非常少的情况。

  • 这种实现方式会造成代码量庞大,耦合性高。而且非常有局限性,因为有很多的业务是无法很简单的实现回滚的,如果串行的服务很多,回滚的成本实在太高。

3、基于消息的分布式事务

核心思想:

eBay 的架构师Dan Pritchett,曾在一篇解释BASE 原理的论文《Base:An Acid Alternative》中提到一个eBay 分布式系统一致性问题的解决方案。它的核心思想是将需要分布式处理的任务通过消息或者日志的方式来异步执行,消息或日志可以存到本地文件、数据库或消息队列,再通过业务规则进行失败重试,它要求各服务的接口是幂等的。

基于消息的分布式事务模式核心思想是通过消息系统来通知其他事务参与方自己事务的执行状态。消息系统的引入更有效的将事务参与方解耦,各个参与方可以异步执行。

该种模式的难点在于解决本地事务执行和消息发送的一致性:两者要同时执行成功或者同时取消执行。

实现上主要有两种方式:

  • 基于事务消息的方案

  • 基于本地消息的方案

1)基于事务消息的分布式事务

普通消息是无法解决本地事务执行和消息发送的一致性问题的。因为消息发送是一个网络通信的过程,发送消息的过程就有可能出现发送失败、或者超时的情况。超时有可能发送成功了,有可能发送失败了,消息的发送方是无法确定的,所以此时消息发送方无论是提交事务还是回滚事务,都有可能不一致性出现。

解决这个问题,需要引入事务消息,事务消息和普通消息的区别在于事务消息发送成功后,处于 prepared 状态,不能被订阅者消费,等到事务消息的状态更改为可消费状态后,下游订阅者才可以监听到次消息。

本地事务和事务消息的发送的处理流程如下:

  • 事务发起者预先发送一个事务消息。

  • MQ 系统收到事务消息后,将消息持久化,消息的状态是“待发送”,并给发送者一个 ACK 消息。

  • 事务发起者如果没有收到 ACK 消息,则取消本地事务的执行;如果收到了 ACK 消息,则执行本地事务,并给 MQ 系统再发送一个消息,通知本地事务的执行情况。

  • MQ 系统收到消息通知后,根据本地事务的执行情况更改事务消息的状态,如果成功执行,则将消息更改为“可消费”并择机下发给订阅者;如果事务执行失败,则删除该事务消息。

  • 本地事务执行完毕后,发给 MQ 的通知消息有可能丢失了。所以支持事务消息的 MQ 系统有一个定时扫描逻辑,扫描出状态仍然是“待发送”状态的消息,并向消息的发送方发起询问,询问这条事务消息的最终状态如何并根据结果更新事务消息的状态。因此事务的发起方需要给 MQ 系统提供一个事务消息状态查询接口。

  • 如果事务消息的状态是“可发送”,则 MQ 系统向下游参与者推送消息,推送失败会不停重试。

  • 下游参与者收到消息后,执行本地事务,本地事务如果执行成功,则给 MQ 系统发送 ACK 消息;如果执行失败,则不发送 ACK 消息,MQ 系统会持续推送给消息。

2)基于本地消息的分布式事务

基于事务消息的模式对 MQ 系统要求较高,并不是所有 MQ 系统都支持事务消息的,RocketMQ 是目前为数不多的支持事务消息的 MQ 系统。如果所依赖的 MQ 系统不支持事务消息,那么可以采用本地消息的分布式模式。

该种模式的核心思想是:

上游服务:

  • 事务的发起方维护一个本地消息表,业务执行和本地消息表的执行处在同一个本地事务中。业务执行成功,则同时记录一条“待发送”状态的消息到本地消息表中。

  • 系统中启动一个定时任务定时扫描本地消息表中状态为“待发送”的记录,并将其发送到 MQ 系统中,如果发送失败或者超时,则一直发送,直到发送成功后,从本地消息表中删除该记录(或修改状态为“已发送”)。

  • 消息会重试发送,可能会重复,所以每条消息需要一个唯一ID。

下游服务:

  • 后续的消息订阅者从MQ消费消息,进行下游的本地事务操作。

  • 为了避免消息重复消费,下游服务可以维护一个本地的“消息记录表”记录已经处理消费过的消息,每次处理消息前通过该表检查消息是否消费过。

基于消息的分布式事务可以将分布式系统之间更有效的解耦,各个事务参与方之间的调用不再是同步调用。

对MQ系统的要求较高,对业务实现也有一定的侵入性,要么提供事务消息状态查询接口,要么需要维护本地消息表。并且原则上只接受下游分支事务的成功,不接受事务的回滚,如果失败就要一直重试,适用于对最终一致性敏感度较低的业务场景,例如跨企业的系统间的调用,适用的场景有限。

总结

阅读了不少这方面的文章,在此基础上,总结一下分布式事务一致性的解决方案。分布式系统的事务一致性本身就是一个技术难题,目前没有一种很简单很完美的方案能够应对所有场景。分布式系统的一个难点就是因为“网络通信的不可靠”,只能通过“确认机制”、“重试机制”、“补偿机制”等各方面来解决问题。在综合考虑可用性、性能、实现复杂度等各方面的情况上,比较好的选择是“异步消息确保最终一致性”,只是具体实现方式上有一些差异。

参考:

分布式系统的事务处理

分布式系统事务一致性解决方案

理性撕逼!分布式事务:不过是在一致性、吞吐量和复杂度之间,做一个选择

知乎:常用的分布式事务解决方案介绍有多少种?

一次给女朋友转账引发我对分布式事务的思考

用消息队列和消息应用状态表来消除分布式事务

程立:《大规模SOA系统中的分布事务处事》

欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。欢迎加入程序员小乐技术交流群,在后台回复“加群”或者“学习”即可。

猜你还想看

阿里、腾讯、百度、华为、京东最新面试题汇集

面试官问我:kill -9 进程杀不掉,怎么办?

前、后端分离权限控制设计和实现思路

我在谷歌,女友在亚马逊,晒出2人总收入,网友:好酸!

关注订阅号「程序员小乐」,收看更多精彩内容

嘿,你在看吗

分布式系统事务一致性相关推荐

  1. 分布式系统事务一致性解决方案

    2019独角兽企业重金招聘Python工程师标准>>> http://www.infoq.com/cn/articles/solution-of-distributed-system ...

  2. 分布式系统事务一致性解决方案大对比,谁最好使?

    " 在分布式系统中,同时满足"一致性"."可用性"和"分区容错性"三者是不可能的.分布式系统的事务一致性是一个技术难题,各种解决方 ...

  3. 分布式系统事务一致性解决方案(转)

    本文首发于InfoQ,版权所有,请勿转载!!! http://www.infoq.com/cn/articles/solution-of-distributed-system-transaction- ...

  4. 消息中间件(一)分布式系统事务一致性解决方案大对比,谁最好使?(转)...

    原文转载至:https://blog.csdn.net/lovesomnus/article/details/51785108 在分布式系统中,同时满足"一致性"."可用 ...

  5. 聊聊分布式事务分布式系统事务一致性解决方案

    事务就是一个会话过程中,对上下文的影响是一致的,要么所有的更改都做了,要么所有的更变都撤销掉.就要么生,要么死.没有半死不死的中间不可预期状态. 参考下薛定谔的猫. 事务是为了保障业务数据的完整性和准 ...

  6. 如何解决分布式系统数据事务一致性问题

    如何解决分布式系统数据事务一致性问题 (HBase加Solr) 摘要:对于所有的分布式系统,我想事务一致性问题是极其非常重要的问题,因为它直接影响到系统的可用性.本文以下所述所要解决的问题是:对于入H ...

  7. 关于mysql数据库分库分表、事务一致性问题的学习

    很多人张嘴就是分库分表,好像不分库分表就不算牛逼的系统,不谈分库分表就没有逼格一样. 个人觉得,在设备配置别太挫.业务拆分别太渣.sql写法别太low.单表数据不上亿的情况下,靠读写分离.索引优化.表 ...

  8. 如何解决分布式系统数据事务一致性问题(HBase加Solr)

    如何解决分布式系统数据事务一致性问题(HBase加Solr) 参考文章: (1)如何解决分布式系统数据事务一致性问题(HBase加Solr) (2)https://www.cnblogs.com/wg ...

  9. 分布式系统漫谈【拾】_分布式事务一致性:阿里方案

    上篇文章:分布式系统漫谈[玖]_分布式事务一致性:协议支持 其实对于生产环境的分布式事务一致,各大互联网公司都是自己实现的解决方案,总结起来无非是异步.补偿.实时查询.定期校对几种模式,大部分场景都是 ...

最新文章

  1. 机器学习算法集锦:从贝叶斯到深度学习及各自优缺点
  2. 一大波数据来袭 网络桃色陷阱暗藏致命危机
  3. 重磅推荐《南瓜书》:周志华《机器学习》的代码实现
  4. 版本分支管理标准 - Trunk Based Development 主干开发模型
  5. python 多条件判断 生成新列_pandas DataFrame 根据多列的值做判断,生成新的列值
  6. Web Service Software Factory
  7. mini139聊天软件
  8. 联想Y9000P2021双SSD系统win10下ubantu20.04+ROS的安装(记录非教程)
  9. 动易CMS2006安装与配置
  10. python处理access数据库教程_Python操作Access数据库基本步骤分析
  11. java u盘检测工具,BadUSB测试记录
  12. win8虚拟机_老司机教你如何在虚拟机安装win8系统,双系统也可以这样实现
  13. 常用各种网络模块总结
  14. 在某网课学习前端笔记整理js篇24-js正则表达式
  15. maven创建eclipse wtp项目
  16. Nginx服务器软件学习记录
  17. 2021支付宝 商户私钥 + 商户公钥 设置教程
  18. gallery3D(3)
  19. 微信小程序实现瀑布流 仿小红书
  20. Unity URP渲染管线下体积光的实现

热门文章

  1. 爱,请在来得及的时候说出口
  2. linux更换桌面图,桌面应用|在 Linux 上安装必应桌面墙纸更换器
  3. 情感语音合成技术难点突破与未来展望
  4. flexpaper php 代码,FlexPaper Flex在线显示PDF文档的php源码下载|FlexPaper Flex在线显示PDF文档的php源码官方下载-太平洋下载中心...
  5. 数据库、计算机网络,操作系统刷题笔记8
  6. python安装prosail库及Fortran编译器下载与配置
  7. JS FormData
  8. i9 12900HX和i9 12900HK有什么区别
  9. 如何制定数字时代的数据隐私策略
  10. 【windows】如何全部关闭360安全的弹出guang告?(已解决)