精华内容
下载资源
问答
  • 最终一致性

    万次阅读 2012-05-14 22:11:45
    在全球范围构建可靠的分布式系统...最终一致性 Eventually Consistent   作者: Werner Vogels Werner Vogels is vice president and chieftechnology officer at amazon.com, where he is responsible for driving

    在全球范围构建可靠的分布式系统,需要在一致性和可用性之间进行权衡。

     

    最终一致性  Eventually Consistent

     

    作者: Werner Vogels

    Werner Vogels is vice president and chieftechnology officer at amazon.com, where he is responsible for driving thecompany’s technology vision of continuously enhancing innovation on behalf ofamazon’s customers at a global scale.

     

    Amazon云计算的基础是一些基础设施服务,比如Amazon的S3、SimpleDB、和EC2(弹性计算云)来提供资源,构建互联网范围上的计算平台以及大量丰富的应用。对这些基础设施的要求是非常严格;它们需要在安全性、扩展性、可用性、性能,以及能耗方面获得很高的分数,它们需要在满足这些要求的同时不间断的服务全球数百万的用户。

         藏在这些服务背后,是运行在全球范围上的大规模分布式系统。全球范围带来了新的挑战,当一个系统需要处理数以万亿的请求时,平时很低概率的事件也必然会出现,必须在设计和构建系统的前期将其考虑进来。考虑到在世界范围内运行这些系统,我们无处不在地使用复制技术来获得一致的性能和高可用性。

        尽管复制让我们接近了我们的目标,但它仍不能以一种透明的方式完美的实现他们;在若干环境下,服务的用户将会面临,在服务内部使用复制技术的不足。这个一点在系统提供的数据一致性类型方面就有所体现。特别是许多普遍的大规模分布式系统在数据复制时提供最终一致性模型。在Amazon设计大规模系统时,我们使用了一系列与大规模数据复制相关的指导原则和抽象概念,集中在对高可用性和数据一致性之间进行权衡。这里,我介绍一些相关背景,它们启发我们设计了在全球范围内可靠运行的分布式系统。

        历史的角度

        在理想的世界中,只有一个一致性模型:当一个更新发生,所有观察者都能看到更新。在1970年代后期,第一次发现这个模型难以实现。关于这个话题最好的“period piece(历史文章)”文章是“Notes on DistributedDatabases” by Bruce Lindsayet.它奠定了数据库复制的基本原则,讨论了实现一致性的许多技术。这些技术中的大部分试图透明地实现分布式,对于用户,它展现为一个系统而不是大量的协作系统。那个时期的许多系统都采用这种方法,宁可系统实现失败,也不愿破坏透明性。(批注:由此可见大师级永远是少数,其他人都是沿着大师级人物给出的方向前进)

    在1990年代中期,随着更大规模的网络系统出现,之前的实践被重新审视。那时人们开始考虑,将可用性作为系统最重要的属性,但人们仍挣扎于什么需要被牺牲。Eric Brewer, UC Berkeley的系统教授,同时是Inktomi的带头人,在2000年PODC会议上一个主题演讲中将不同的权衡方面放在一起。他提出了CAP理论,对于一个数据共享系统:数据一致性、系统可用性、网络分区容忍性,在任意时刻仅能同时满足两点。更加正式的描述在2002年的论文中可以被找到,由Seth Gilbert 和 Nancy Lynch撰写。

    一个系统如果不进行网络分隔,通常采用事务协议,来同时获得数据一致性和可用性,。客户端和服务器通常处于相同环境下,在某些情况下他们作为一个整体而失效,就这点而言客户端不会观察到分隔情况。在较大的分布式系统中,网络分隔是必然的;因此,一致性和可用性不可能同时被达到。这意味着有两种选择:放松一致性将使系统在分隔环境下获得高可用性;优先考虑一致性,则在某些情况下系统不可用。

    对于两种选择,客户端开发人员明确知道系统提供的是那一种。如果系统强调一致性,开发人员则需要处理系统无法访问的情况,比如写请求。如果因为系统不可用而无法写入,开发人员需要处理被写入的数据。如果系统强调可用性,它将接受写入,但在某些情况下读请求不能获得最新写入的结果。开发人员需要决定客户端是否需要随时都访问最新的更新。有很多应用可以容忍轻微的脏数据,在这个模型下他们能很好的工作。

    (思考:在构建大型系统时,对每一个子系统都将有很严格的响应时间、一致性等指标要求,不然大系统将无法构建。)

    在这个原则下(CAP理论),事务系统的一致性属性被定义为ACID(atomicity, consistency, isolation, durability)是一种不同类型的一致性保证。在ACID中,一致性保证当一个事务完成时数据库处于一致的状态;例如,当从一个账户转钱到另一个账户,两个账户的总数是不变的。在基于ACID的系统中,通常由编写事务的开发人员负责一致性,数据库的完整性约束能辅助开发。

    一致性—客户端和服务器

    有两种方式看待一致性。一种是从开发者/客户端的角度:他们是如何观察数据更新的。另一种是从服务器端:更新是如何在系统中流动以及对于更新系统能提供什么样的保证。

    客户端观察到的一致性指的是,何时以及如何能观察到对存储系统中数据对象所做的更新。下面的例子说明不同类型的一致性,进程A对一个数据对象进行了更新。

    强一致性。当更新完成,后续所有访问都将获得更新值。

    弱一致性。系统不能保证后续访问都将获得更新值。在更新返回前有许多条件需要被满足。从收到更新到所有观察者能看到更新的这段时间被称为不一致窗口

    最终一致性。一种特殊的弱一致;存储系统保证如果没有新的更新提交,最终所有的访问都将获得最后的更新。如果没有故障发生,不一致窗口的大小取决于通信延迟,系统负载,以及复制策略中涉及的副本数。最常见实现最终一致性的系统是DNS。对于name更新的传播依赖,配置模式以及基于时间控制的缓存;最终,所有的节点将会看到更新。

    最终一致性模型有很多变种需要重视。

    因果一致性。如果进程A告诉进程B它更新了数据,接下来进程B的访问将会获得更新数据,进程B的写操作也将取代原先的写。进程C与进程A没有因果关系,则遵循最终一致性原则。

    Read-your-wirtes一致性。对于进程A这是一个很重要的模型,在更新了一个数据项后,进程A后续访问到的都是更新后数据,绝不会看到旧值。这是因果模型的一个特例。

    Session一致性。这是Read-your-writes模型的一个现实版本,当一个进程在一个上下文环境中访问存储系统。只要Session存在,系统将保证read-your-writes一致性。如果因为某种故障让Session中断,一个新的Session将被创建,同时保证不能重叠Session.

    单调读取一致性。如果一个进程看到对象的一个特定值,那么后续所有访问将不会返回任何之前的值。

    单调写一致性。这种情况下,系统保证串行化来自同一个进程的写操作。众所周知,系统如果不能保证单调写一致性,上层的程序将非常难以开发。

    这些属性是可以同时具备的。例如,可以通过保证单调读和session-level一致性。从实际角度出发,这两种一致性(单调读和read-your-writes)在最终一致性系统中是最需要的。

    从这些变种中你可以看到,还是有相当多的不同情境存在。它依赖于特定应用是否能处理这些后果。

    最终一致性对于极端的分布式环境下并不是深奥的特性。现代的RDBMs提供的主-备可靠性,通过同步和异步的复制技术实现。在同步模式下,复制更新是事务的一部分。在异步模式中,更新以一种延迟方式到达备份节点,通常通过日志传输。在后者模型中,如果主节点在日志传送完成前失效,从远程备份节点读取到的将是旧的,不一致的数据。为了支持更好的扩展读性能,RDBMSs开始提供从备份中读取的能力,这是一种提供最终一致性保证的经典方式,其中不一致窗口依赖于日志传送的周期。

    在服务器端,我们需要深入的观察更新是如何流经系统的,从而理解是什么造成了模型的不同,使用系统的开发人员能体会到这一点。让我们在开始前先创建一些定义:

    N=存储副本数据的节点数。

    W=需要接收更新的节点数,在完成更新前。

    (注释:更新完成指将更新写入N个节点,但系统可以在写入W个节点后就返回更新完成,剩余N-W个节点在后续进行同步。)

    R=读操作获取数据时需要连接的副本数。

    (注释: 读取数据时从R个节点同时读取,经过合并去除掉不合理数据再返回给用户。)

    如果W+R>N,写操作和读操作请求节点集会存在重叠,从而保证强一致性。在主-备的RDBMS场景中,采用同步复制,N=2,W=2,R=1。无论客户端从哪一个副本读取,它总能获得一致的结果。在异步复制模式下,允许客户端从备份节点读取,N=2,W=1,R=1。这时R+W=N,一致性不能获得保障。

    W、R、N的配置是法定人数协议的基础。当因故障造成系统无法写入到W个节点时,写操作失败,系统不可用。在N=3,W=3而只有两个节点可用时,那么系统将写失败。提供高性能、高可用性的分布式存储系统,通常节点数大于2个。系统如果关注的重点是容错通常设置N=3(W=2以及R=2)。系统为了满足更高的读取负载,通常保存数据副本的节点数会超过容错需要的节点数;N可能是几十甚至几百个节点,R设置为1,这样读取到一个节点就会返回结果。系统如果关注一致性将会把更新节点数W设置为N,这可能会降低写成功的可能性。一个关心容错而不是一致性的系统通常设置W为1,获得最小的持久化开销,然后依靠周期写入技术来更新其它节点。

    如何配置N,W和R取决于常见的应用是什么,以及什么路径需要优化。R=1,N=W为读应用进行优化,W=1,R=N为了更快的写进行优化。当然在后一种情况下,当故障发生时持久化不能保证,如果W<(N+1)/2,因为写操作未重叠,可能会出现冲突写。

    (注释:如果W<(N+1)/2,两个客户端的写请求集合就有可能不重叠,如果两个客户端修改同一个对象,每个客户端的修改都是有效的,但系统中保存的结果却是冲突的。)

    弱/最终一致性在W+R<=N时就会采用,这意味着读集合与写集合没有重叠。如果不是专门配置或基于失败案例,这里并没有特别的意义将R设置为1以外的值。W+R<=N通常发生在两种十分常见的场景:前面提到的为了获得读请求的伸缩性进行大规模复制;以及对于数据访问非常复杂的情况。在简单的Key-value模型中,通过比较版本来决定写入系统的最后更新非常容易,但对于返回对象集合的系统很难决定最新的集合应该是什么。这大多数这样的系统,写集合通常小于副本节点,然后以惰性方式将更新应用到其他副本节点。所有副本节点获得更新的周期就是前面提到的不一致窗口。如果W+R<=N,系统从节点读取数据是脆弱的,因为节点可能还没有收到更新。

    是否是read-your-write, session, 以及单调一致,取决于客户端对于服务器的“粘性”,以及他们之间执行的分布式协议。如果每次访问同一个服务器,相对来讲比较容易获得read-your-writes和单调读一致性。这使得负载均衡和容错稍微难以管理,但这是一个简单的方案。使用session,具有一定粘性,让一致性非常明显,提供了一个清晰的一致性级别,客户端可进行推理。

    有时客户端实现了read-your-writes和单调读一致性。通过增加写入时版本信息,客户端可以丢弃先于最近可见版本的读取值。

    分区发生指,系统中一些节点无法连接其它节点,同时这两部分节点都可以被客户端访问。如果你用经典的多数法定人方法,有W副本节点的分区可以继续进行更新,而其他分布则不可用。这对于读集合一样。考虑读写集合的重叠,定义W,R时需要避免最小的不可用集合。分区并不频繁发生,但确实发生数据中心之间、以及数据中心内部。

    在一些应用中,任何一个分区的不可用都是不可接受的,对于需要访问分区来获得进展的客户端来说非常重要。这种情况下,两边分配一组新的存储节点来接收数据,分区愈合时执行合并操作。例如,在Amazon的购物车中,用户使用一个write-always系统;当分区发生时,客户能继续将物品放入购物车中,即使原来的购物车在其它分区。一旦分区愈合,购物车应用将合并购物车。

    Amazon’s Dynamo

    考虑了所有这些属性,并在一个应用架构下可显示控制这些属性的系统是Amazon的Dynamo,一个key-value存储系统,在构成Amazon电子商务平台服务的内部使用,同时也作为Amazon的一个Web服务。Dynamo的设计目标之一就是,让在Dynamo(通常会跨多个数据中心)上创建存储实例的应用服务拥有者,能在一个合理的成本点上获得一致性、持久化、可用性以及性能的一个平衡。

    总结

    在大规模可靠地分布式系统中,出于两个原因数据不一致必须被接收:在高并发环境下优化读写性能;尽管节点启动并在运行,但分区问题仍是一个主要的模型,对系统不可用负有一定的责任。不一致性是否能被接收依赖于客户端的应用。在任何情况下,开发人员必须清楚存储系统提供的一致性保证,在开发应用时必须将一致性考虑进来。

    这有大量方法来改善最终一致性模型,比如session级的一致性和单调读,这对于开发人员来说提供了更好的工具。很多时候,应用使用提供最终一致性的存储系统没有任何问题。在web应用中有一个非常流行的例子,我们都知道用户可接受的一致性。在这个场景下,不一致窗口一定要小于用户对返回下一个页面的期望时间。这是下一次读请求前,更新传播到整个系统的时间。

    本文的目标是提高对工程系统复杂性的认识。这样的系统需要在全球范围运行,需要仔细的调优来保证他们能提供上层应用需要的持久化、可用性、以及性能。系统设计人员可用的一个工具是不一致窗口的长度,在这个过程中,系统的客户端可能被暴露给真实的大系统工程。

    展开全文
  • 有关一致性,实践中又可以分为:强一致性、单调一致性、最终一致性。 CAP中的C默认就是指:在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)。 1、强一致性...

    我们都了解分布式CAP原则,其中的C就是一致性。有关一致性,实践中又可以分为:强一致性、单调一致性、最终一致性。

    CAP中的C默认就是指:在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)。

    1、强一致性(Strong Consistency)

    在任何时刻所有的用户或者进程查询到的都是最近一次成功更新的数据。强一致性是程度最高一致性要求,也是最难实现的。关系型数据库更新操作就是这个案例。

    2, 单调一致性(Monotonic Consistency)

    单调一致性会从读写两个角度有各自的定义。

    单调读一致性

    如果进程已经看到过数据对象的某个值,那么任何后续访问都不会返回该值之前的值。(“If a process has seen a particular value for the object any subsequent accesses will never return any previous values”)

    单调写一致性

    系统保证来自同一个进程的写操作顺序执行。(Write operations that must precede other writes are executed before those other writes.)

    3、最终一致性(Eventual Consistency)

    和强一致性相对,在某一时刻用户或者进程查询到的数据可能都不同,但是最终成功更新的数据都会被所有用户或者进程查询到。当前主流的nosql数据库都是采用这种一致性策略。

    额外内容:

    zookeeper的一致性

    我们以官方文档为准:(2019-11-17摘录的)

    ZooKeeper is a high performance, scalable service. Both reads and write operations are designed to be fast, though reads are faster than writes. The reason for this is that in the case of reads, ZooKeeper can serve older data, which in turn is due to ZooKeeper's consistency guarantees:
    
    Sequential Consistency : Updates from a client will be applied in the order that they were sent.
    
    Atomicity : Updates either succeed or fail -- there are no partial results.
    
    Single System Image : A client will see the same view of the service regardless of the server that it connects to.
    
    Reliability : Once an update has been applied, it will persist from that time forward until a client overwrites the update. This guarantee has two corollaries:
    
    If a client gets a successful return code, the update will have been applied. On some failures (communication errors, timeouts, etc) the client will not know if the update has applied or not. We take steps to minimize the failures, but the guarantee is only present with successful return codes. (This is called the monotonicity condition in Paxos.)
    Any updates that are seen by the client, through a read request or successful update, will never be rolled back when recovering from server failures.
    Timeliness : The clients view of the system is guaranteed to be up-to-date within a certain time bound (on the order of tens of seconds). Either system changes will be seen by a client within this bound, or the client will detect a service outage.
    
    Using these consistency guarantees it is easy to build higher level functions such as leader election, barriers, queues, and read/write revocable locks solely at the ZooKeeper client (no additions needed to ZooKeeper). See Recipes and Solutions for more details.
    

    简单总结:zk提供的是单调一致性,最终一致性,不是强一致性。 zk的文档清楚强调了ZooKeeper does not guarantee that at every instance in time, two different clients will have identical views of ZooKeeper data.

    原文链接:https://zookeeper.apache.org/doc/current/zookeeperProgrammers.html#ch_zkGuarantees

    mongoDB的一致性

    原文链接:https://docs.mongodb.com/manual/core/read-isolation-consistency-recency/

    mongodb提供单调写一致性。
    Monotonic Writes
    MongoDB provides monotonic write guarantees, by default, for standalone mongod instances and replica set.

    For monotonic writes and sharded clusters, see Causal Consistency.
    Write operations that must precede other writes are executed before those other writes.

    后记:我们实际开发业务分布式系统,必须在强一致性和最终一致性中间进行tradeoff。 根据业务要求,进行取舍。强一致性会增加延时(所有实例和副本进行数据同步)和降低可用性(只要有节点无法完成同步数据, 可用性就有问题)。
    现在很多软件直接提供可配置的一致性,用户可以根据业务要求进行配置。 例如微软的cosmos-db。

    参考:
    1, https://hellokangning.github.io/en/post/consistency-in-distributed-system/
    2,https://docs.microsoft.com/en-us/azure/cosmos-db/consistency-levels
    3, https://docs.mongodb.com/manual/core/read-isolation-consistency-recency/

    展开全文
  • 通俗易懂 强一致性、弱一致性、最终一致性、读写一致性、单调读、因果一致性 的区别与联系什么是一致性一致性的种类导致一致性出现的原因强一致性 与 弱一致性强一致性两个要求弱一致性强一致性和弱一致性举例顺序...

    什么是一致性

    在分布式系统中,一致性(Consistency)是指多副本(Replications)问题中的数据一致性。

    一致性的种类

    • 事务一致性
    • 数据一致性

    本文主要讨论数据一致性(事务一致性指ACID)

    导致一致性出现的原因

    • 数据的分布式存储是导致出现一致性的唯一原因

    强一致性 与 弱一致性

    数据一致性的种类

    • 强一致性(线性一致性):即复制是同步的
    • 弱一致性:即复制是异步的

    强一致性两个要求

    • 任何一次读都能读到某个数据的最近一次写的数据。
    • 系统中的所有进程,看到的操作顺序,都和全局时钟下的顺序一致。

    简言之,在任意时刻,所有节点中的数据是一样的。

    弱一致性

    数据更新后,如果能容忍后续的访问只能访问到部分或者全部访问不到,则是弱一致性。

    最终一致性就属于弱一致性。

    强一致性和弱一致性举例

    例如,对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性
    用户更新网站头像,在某个时间点,用户向主库发送更新请求,不久之后主库就收到了请求。在某个时刻,主库又会将数据变更转发给自己的从库。最后,主库通知用户更新成功。

    如果在返回“更新成功”并使新头像对其他用户可见之前,主库需要等待从库的确认,确保从库已经收到写入操作,那么复制是同步的,即强一致性。如果主库写入成功后,不等待从库的响应,直接返回“更新成功”,则复制是异步的,即弱一致性。

    强一致性可以保证从库有与主库一致的数据。如果主库突然宕机,我们仍可以保证数据完整。但如果从库宕机或网络阻塞,主库就无法完成写入操作。

    在实践中,我们通常使一个从库是同步的,而其他的则是异步的。如果这个同步的从库出现问题,则使另一个异步从库同步。这可以确保永远有两个节点拥有完整数据:主库和同步从库。 这种配置称为半同步。

    顺序一致性

    两个要求:

    • 任何一次读都能读到某个数据的最近一次写的数据。
    • 系统的所有进程的顺序一致,而且是合理的。即不需要和全局时钟下的顺序一致,错的话一起错,对的话一起对。(强一致性的要求比顺序一致性更严格)

    顺序一致性参考

    最终一致性

    不保证在任意时刻任意节点上的同一份数据都是相同的,但是随着时间的迁移,不同节点上的同一份数据总是在向趋同的方向变化。

    最终两个字用得很微妙,因为从写入主库到反映至从库之间的延迟,可能仅仅是几分之一秒,也可能是几个小时

    • 简单说,就是在一段时间后,节点间的数据会最终达到一致状态。

    最终一致性的种类

    最终一致性根据更新数据后各进程访问到数据的时间和方式的不同,又可以区分为:

    • 因果一致性(Casual Consistency)。如果进程A通知进程B它已更新了一个数据项,那么进程B的后续访问将返回更新后的值,且一次写入将保证取代前一次写入。与进程A无因果关系的进程C的访问,遵守一般的最终一致性规则。
    • “读己之所写(read-your-writes)”一致性。当进程A自己更新一个数据项之后,它总是访问到更新过的值,绝不会看到旧值。这是因果一致性模型的一个特例。
    • 会话(Session)一致性。这是上一个模型的实用版本,它把访问存储系统的进程放到会话的上下文中。只要会话还存在,系统就保证“读己之所写”一致性。如果由于某些失败情形令会话终止,就要建立新的会话,而且系统的保证不会延续到新的会话。
    • 单调(Monotonic)读一致性。如果进程已经看到过数据对象的某个值,那么任何后续访问都不会返回在那个值之前的值。
    • 单调写一致性。系统保证来自同一个进程的写操作顺序执行。要是系统不能保证这种程度的一致性,就非常难以编程了。
    展开全文
  • 随着微服务的越来越多,一致性问题也越来越被重视。纠结是怎样才能ACID呢?...而本地消息表、可靠消息最终一致性方案、最大努力通知方案都是不错的解决方案。 目录 一致性问题 解决一致性问题的模式和思路 A...

    随着微服务的越来越多,一致性问题也越来越被重视。纠结是怎样才能ACID呢?CAP还是Base呢?其实强一致性的方案也特别多,比如net的msdtc、java的atomikos...等。但他们这类基于2pc(两阶段提交协议)实现,基本上性能太差,根本不适合高并发的系统。而本地消息表、可靠消息最终一致性方案、最大努力通知方案都是不错的解决方案。

    目录

    一致性问题

    解决一致性问题的模式和思路

    ACID

    CAP

    BASE

    分布式一致性协议

    两阶段提交协议

    三阶段提交协议

    TCC

    最终一致性的解决方案

    1.查询模式

    2.补偿模式

    3.异步确保模式

    4. 定期校对模式

    5.可靠消息模式

    1.本地消息

    2. 可靠事务消息事务

    3.消息处理器的幂等性


    一致性问题

    1. 下订单和扣库存,即下订单和扣库存如何保持一致。如果先下订单,扣库存失败,那么将会导致超卖;如果下订单不成功,扣库存成功,那么会导致少卖。这两种情况都会导致运营成本增加,在严重情况下需要赔付。
    2. 同步调用超时,系统A 同步调用系统B 超时,系统A 可以明确得到超时反馈,但是无法确定系统B 是否已经完成了预设的功能
    3. 异步回调超时,和上一个同步超时的案例类似
    4. 掉单,如果一个系统中存在一个请求(通常指订单),另外一个系统不存在,则会导致掉单
    5. 系统间状态不一致,不同的是两个系统间都存在请求,但是请求的状态不一致
    6. 缓存和数据库不一致,服务于交易的数据库难以抗住大规模的读流量,通常需要在数据库前增加一层缓存,那么缓存和数据库之间的数据如何保持一致性?是要保持强一致性还是弱一致性呢?
    7. 本地缓存节点间不一致,本地缓存的有些数据是静态的、不变的,就永远不会有问题,但是如果经常被更新的,则被更新时各个节点的更新是有先后顺序的,在更新的瞬间,在某个时间窗口内各个节点的数据是不一致的

    解决一致性问题的模式和思路

    ACID

    关系型数据库天生用于解决具有复杂事务场景的问题,完全满足ACID 的特性。

    • A: Atomicity ,原子性
    • C : Consistency , 一致性
    • I: Isolation ,隔离性
    • D: Durability ,持久性

    由于业务规则的限制,我们无法将相关数据分到同一个数据库分片,这时就需要实现最终一致性。

    CAP

    由于对系统或者数据进行了拆分,我们的系统不再是单机系统,而是分布式系统!

    • C: Consistency , 一致性。在分布式系统中的所有数据备份,在同一时刻具有同样的值,所有节点在同一时刻读取的数据都是最新的数据副本
    • A: Availability ,可用性,好的响应性能。完全的可用性指的是在任何故障模型下,服务都会在有限的时间内处理完成井进行响应
    • P: Partition tolerance ,分区容忍性。尽管网络上有部分消息丢失,但系统仍然可继续工作

    CAP 原理证明,任何分布式系统只可同时满足以上两点,无法三者兼顾。由于关系型数据库是单节点无复制的,因此不具有分区容忍性,但是具有一致性和可用性,而分布式的服务化系统都需要满足分区容忍性,那么我们必须在一致性和可用性之间进行权衡。

    BASE

    BASE 思想解决了CAP 提出的分布式系统的一致性和可用性不可兼得的问题,如果想全面地学习BASE思想!BASE 思想与ACID 原理截然不同,它满足CAP 原理,通过牺牲强一致性获得可用性,一般应用于服务化系统的应用层或者大数据处理系统中,通过达到最终一致性来尽量满足业务的绝大多数需求。

    • BA: Basically Available ,基本可用。
    • S: Soft State ,软状态,状态可以在一段时间内不同步。
    • E: Eventually Consistent ,最终一致,在一定的时间窗口内, 最终数据达成一致即可。

    有了BASE 思想作为基础,我们对复杂的分布式事务进行拆解,对其中的每个步骤都记录其状态,有问题时可以根据记录的状态来继续执行任务,达到最终一致。

    分布式一致性协议

    两阶段提交协议

    JEE 的XA 协议就是根据两阶段提交来保证事务的完整性,并实现分布式服务化的强一致性。两阶段提交协议把分布式事务分为两个阶段, 一个是准备阶段,另一个是提交阶段。准备阶段和提交阶段都是由事务管理器发起的, 为了接下来讲解方便,我们将事务管理器称为协调者, 将资源管理器称为参与者。

    • 准备阶段: 协调者向参与者发起指令,参与者评估自己的状态,如果参与者评估指令可以完成,则会写redo 或者undo 日志( Write-Ahead Log 的一种),然后锁定资源,执行操作,但是并不提交
    • 提交阶段: 如果每个参与者明确返回准备成功,则协调者向参与者发起提交指令,参与者提交事务,释放锁定的资源。如果任何一个参与者明确返回准备失败,则协调者向参与者发起中止指令(取消事务),执行undo 日志,释放锁定的资源。

    两阶段提交协议在准备阶段锁定资源,这是一个重量级的操作, 能保证强一致性!但是实现起来复杂、成本较高、不够灵活,更重要的是它有如下致命的问题。

    • 阻塞:从上面的描述来看,对于任何一次指令都必须收到明确的响应,才会继续进行下一步,否则处于阻塞状态,占用的资源被一直锁定,不会被释放。
    • 单点故障:如果协调者宕机,参与者没有协调者指挥,则会一直阻塞,尽管可以通过选举新的协调者替代原有协调者,但是如果协调者在发送一个提交指令后宕机,而提交指令仅仅被一个参与者接收,并且参与者接收后也宕机,则新上任的协调者无法处理这种情况。
    • 脑裂:协调者发送提交指令,有的参与者接收到并执行了事务,有的参与者没有接收到事务就没有执行事务,多个参与者之间是不一致的。

    上面的所有问题虽然很少发生,但都需要人工干预处理,没有自动化的解决方案,因此两阶段提交协议在正常情况下能保证系统的强一致性,但是在出现异常的情况下,当前处理的操作处于错误状态,需要管理员人工干预解决, 因此可用性不够好,这也符合CAP 协议的一致性和可用性不能兼得的原理。

    三阶段提交协议

    三阶段提交协议是两阶段提交协议的改进版本。它通过超时机制解决了阻塞的问题, 井且把两个阶段增加为以下三个阶段。

    • 询问阶段:协调者询问参与者是否可以完成指令,协调者只需要回答是或不是,而不需要做真正的操作,若超时会导致中止。
    • 准备阶段: 如果在询问阶段所有参与者都返回可以执行操作,则协调者向参与者发送预执行请求,然后参与者写redo 和undo 日志,执行操作但是不提交操作。如果在询问阶段任意参与者返回不能执行操作的结果,则协调者向参与者发送中止请求,与两阶段提交协议的准备阶段是相似的。
    • 提交阶段:如果每个参与者在准备阶段返回准备成功,则协调者向参与者发起提交指令,参与者提交事务,释放锁定的资源。如果任何参与者返回准备失败,则协调者向参与者发起中止指令(取消事务),执行undo 日志,释放锁定的资源,与两阶段提交协议的提交阶段一致。

    三阶段提交协议与两阶段提交协议主要有以下两个不同点:

    • 增加了一个询问阶段,询问阶段可以确保尽可能早地发现无法执行操作而需要中止的行为,但是它并不能发现所有这种行为,只会减少这种情况的发生。
    • 在准备阶段以后,协调者和参与者执行的任务中都增加了超时,一旦超时,则协调者和参与者都会继续提交事务,默认为成功,这也是根据概率统计超时后默认为成功的正确性最大。

    三阶段提交协议与两阶段提交协议相比,具有如上优点,但是一旦发生超时,系统仍然会发生不一致,只不过这种情况很少见,好处是至少不会阻塞和永远锁定资源。

    TCC

    两阶段及三阶段方案中都包含多个参与者、多个阶段实现一个事务,实现复杂,性能也是一个很大的问题,因此,在互联网的高并发系统中,鲜有使用两阶段提交和三阶段提交协议的场景。

    TCC 协议将一个任务拆分成Try 、Confirm 、Cancel 三个步骤,正常的流程会先执行T可,如果执行没有问题,则再执行Confirm ,如果执行过程中出了问题,则执行操作的逆操作Cancel 。从正常的流程上讲,这仍然是一个两阶段提交协议,但是在执行出现问题时有一定的自我修复能力,如果任何参与者出现了问题,则协调者通过执行操作的逆操作来Cancel 之前的操作,达到最终的一致状态。

    从时序上来说,如果遇到极端情况,则TCC 会有很多问题,例如,如果在取消时一些参与者收到指令,而另一些参与者没有收到指令,则整个系统仍然是不一致的。对于这种复杂的情况,系统首先会通过补偿的方式尝试自动修复,如果系统无法修复,则必须由人工参与解决。

    从TCC 的逻辑上看,可以说TCC 是简化版的三阶段提交协议,解决了两阶段提交协议的阻塞问题,但是没有解决极端情况下会出现不一致和脑裂的问题。然而, TCC 通过自动化补偿手段,将需要人工处理的不一致情况降到最少,也是一种非常有用的解决方案。某著名的互联网公司在内部的一些中间件上实现了TCC 模式。

    最终一致性的解决方案

    现实系统的底线是仅仅需要达到最终一致性,而不需要实现专业的、复杂的一致性协议。

    1.查询模式

    任何服务操作都需要提供一个查询接口,用来向外部输出操作执行的状态。

    2.补偿模式

    对于服务化系统中同步调用的操作,若业务操作发起方还没有收到业务操作执行方的明确返回或者调用超时,有了上面的查询模式,我们便可以对处于不正常的状态进行修正操作(要么重新执行子操作,要么取消子操作),则可以通过补偿模式。

    3.异步确保模式

    异步确保模式是补偿模式的一个典型案例,经常应用到使用方对响应时间要求不太高的场景中,通常把这类操作从主流程中摘除,充分利用离线处理能力,通过异步的方式进行处理,处理后把结果通过通知系统通知给使用方。这个方案的最大好处是能够对高并发流量进行消峰。

    最大努力通知方案也属于此类

    1. 系统 A 本地事务执行完之后,发送个消息到 MQ;
    2. 这里会有个专门消费 MQ 的最大努力通知服务,这个服务会消费 MQ 然后写入数据库中记录下来,或者是放入个内存队列也可以,接着调用系统 B 的接口;
    3. 要是系统 B 执行成功就 ok 了;要是系统 B 执行失败了,那么最大努力通知服务就定时尝试重新调用系统 B,反复 N 次,最后还是不行就放弃。

    4. 定期校对模式

    在操作主流程中的系统间执行校对操作,可以在事后异步地批量校对操作的状态,如果发现不一致的操作,则进行补偿,补偿操作与补偿模式中的补偿操作是一致的。

    定期校对模式多应用于金融系统中。金融系统由于涉及资金安全, 需要保证准确性, 所以需要多重的一致性保证机制,包括商户交易对账、系统间的一致性对账、现金对账、账务对账、手续费对账等,这些都属于定期校对模式。顺便说一下,金融系统与社交应用在技术上的本质区别为: 社交应用在于量大, 而金融系统在于数据的准确性。

    5.可靠消息模式

    对于主流程中优先级比较低的操作,大多采用异步的方式执行,也就是前面提到的异步确保模型,为了让异步操作的调用方和被调用方充分解耦。我们通常通过消息队列实现异步化。

    消息的可靠发送又分两种

    1.本地消息

    在发送消息之前将消息持久到数据库,状态标记为待发送, 然后发送消息,如果发送成功,则将消息改为发送成功。定时任务定时从数据库捞取在一定时间内未发送的消息并将消息发送。

    本地消息表其实是国外的 ebay 搞出来的这么一套思想,它主要是利用本地消息表来保障可靠保存凭证(消息)。这个方案说实话最大的问题就在于严重依赖于数据库的消息表来管理事务啥的,如果是高并发场景咋办呢?咋扩展呢?所以一般确实很少用。

     

    2. 可靠事务消息事务

    不同的是持久消息的数据库是独立的, 并不藕合在业务系统中。发送消息前,先发送一个预消息给某个第三方的消息管理器,消息管理器将其持久到数据库,并标记状态为待发送,在发送成功后,标记消息为发送成功。

    阿里的 RocketMQ 就支持消息事务,解放了本地消息的局限性。这个还是比较合适的,目前国内互联网公司大都是这么玩儿的。

    1. A 系统先发送一个 prepared 消息到 mq,如果这个 prepared 消息发送失败那么就直接取消操作别执行了;
    2. 如果这个消息发送成功过了,那么接着执行本地事务,如果成功就告诉 mq 发送确认消息,如果失败就告诉 mq 回滚消息;
    3. 如果发送了确认消息,那么此时 B 系统会接收到确认消息,然后执行本地的事务;
    4. mq 会自动定时轮询所有 prepared 消息回调你的接口,问你,这个消息是不是本地事务处理失败了,所有没发送确认的消息,是继续重试还是回滚?一般来说这里你就可以查下数据库看之前本地事务是否执行,如果回滚了,那么这里也回滚吧。这个就是避免可能本地事务执行成功了,而确认消息却发送失败了。
    5. 这个方案里,要是系统 B 的事务失败了咋办?重试咯,自动不断重试直到成功,如果实在是不行,要么就是针对重要的资金类业务进行回滚,比如 B 系统本地回滚后,想办法通知系统 A 也回滚;或者是发送报警由人工来手工回滚和补偿。
    6. 这个还是比较合适的,目前国内互联网公司大都是这么玩儿的,要不你举用 RocketMQ 支持的,要不你就自己基于类似 ActiveMQ?RabbitMQ?自己封装一套类似的逻辑出来,总之思路就是这样子的。

     

    3.消息处理器的幂等性

    • 使用数据库表的唯一键进行滤重
    • 使用分布式表对请求进行滤重。
    • 使用状态流转的方向性来滤重,通常使用数据库的行级锁来实现。
    • 根据业务的特点,操作本身就是幕等的, 例如: 删除一个资源、增加一个资源、获得一个资源等。

    在分布式系统中,保证一致性的解决方案非常多,要针对场景而定,在另一篇中将针对微服务同步 & 异步 & 超时 & 补偿 & 快速失败进行分析。

    展开全文
  • 使用RabbitMQ+延迟队列实现分布式事务的最终一致性方案,demo以典型的订单+库存系统为例
  • 一致性(Consistency) 是指多副本(Replications)问题中的数据一致性。可以分为强一致性、顺序一致性与弱一致性。 强一致性(Strict Consistency) 系统中的某个数据被成功更新后,后续任何对该数据的读取操作...
  • 强一致性、弱一致性、最终一致性

    千次阅读 2012-09-11 19:36:04
    强一致性:系统中的某个数据被成功更新后,后续任何对该数据的读取操作都将得到更新后的值;...最终一致性:是弱一致性的特殊形式,存储系统保证在没有新的更新的条件下,最终所有的访问都是最后更新的值。
  • 不要千言万语,一组漫画让你秒懂最终一致性

    千次阅读 多人点赞 2019-06-14 18:02:37
    你要是不知道什么是最终一致性你可以看看下面的权威定义,当然了网上关于什么是最终一致性的帖子铺天盖地,也许你已经很明白了,即使这样你是不是依然为此图欢呼? 最终一致性是分布式理论中的重要,定义如下: ...
  • 强一致性 弱一致性 最终一致性

    千次阅读 2019-10-02 17:58:48
    在足球比赛里,一个球员在一场比赛中进三个球,称之...一致性(Consistency) 可用性(Availability) 分区容忍性(Partition tolerance) CAP原理指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。因此在进行分...
  • rt。mongodb中分片技术的一致性是强一致性还是最终一致性?底层是用什么算法实现的?
  • 提到分布式系统,就一定绕不开“一致性”,这次我们说说:最终一致性最终一致性是现在大部分高可用的分布式系统的核心思路。 估计有人对最终一致性不太熟,先来个简单介绍: 最终一致性指的是系统中的所有分散在...
  • ServiceComb中的数据最终一致性方案

    万次阅读 2017-10-30 15:23:37
    本文由华为微服务引擎技术团队&&ServiceComb社区授权发布。 数据一致性是构建业务系统需要考虑的重要问题 , 以往我们是依靠...我们最近发起的ServiceComb-Saga项目来解决分布式环境下的数据最终一致性问题。本文将向大
  • 保证最终一致性的模式

    千次阅读 2016-04-07 09:26:28
    在大规模、高并发服务化系统中,一个功能被拆分成多个具有单一功能的子功能,一个流程会有多个单一功能的服务组合实现,如果使用两阶段提交协议和三阶段提交协议,则确实...实现最终一致性有一些非常有效、简单的模式,
  • 分布式事务方案 - 最终一致性

    千次阅读 2019-05-17 11:44:29
    在分布式时代,分库分表是很常见的,微服务系统中,各个系统通常使用独立的数据库,所以,事务很难靠数据库本身保证,...下面我们分析下最终一致性的实现方案,最终一致性通常都是使用消息中间件来实现的,系统结构...
  • RabbitMQ消息最终一致性解决方案

    千次阅读 2019-09-29 10:50:38
    RabbitMQ消息最终一致性解决方案 随着分布式服务架构的流行与普及,原来在单体应用中执行的多个逻辑操作,现在被拆分成了多个服务之间的远程调用。虽然服务化为我们的系统带来了水平伸缩的能力,然而随之而来挑战...
  • 在足球比赛里,一个球员在一场比赛中进三个球,称之...一致性(Consistency) 可用性(Availability) 分区容忍性(Partition tolerance) CAP原理指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。因此在进行...
  • 介绍内容转载自:http://www.blogjava.net/hello-yun/archive/2012/04/27/376744.html https://blog.csdn.net/c289054531/article/details/15337575CAP原理中,有三个要素:一致性(Consistency)可用性(Availability...
  • 分布式事务四_基于可靠消息的最终一致性

    万次阅读 多人点赞 2018-02-10 16:19:57
    分布式事务四_基于可靠消息的最终一致性更多干货分布式事务处理一分布式事务二分布式事务处理三分布式事务四_基于可靠消息的最终一致性分布式事务五_基于可靠消息的最终一致性_异常流程分布式事务六_常规MQ队列...
  • TCC 分布式事物最终一致性

    万次阅读 2017-11-01 10:05:47
    最终一致性(一) TCC 简介 TCC是由支付宝架构师提供的一种柔性解决分布式事务解决方案,主要包括三个步骤: TCC流程 TCC的关键流程如下图(以下单和扣减库存为例子) Q: 预生成订单失败了,为什么要通过TCC执行预处理...
  • 分布式事务八_可靠消息最终一致性方案更多干货分布式事务处理一分布式事务二分布式事务处理三分布式事务四_基于可靠消息的最终一致性分布式事务五_基于可靠消息的最终一致性_异常流程分布式事务六_常规MQ队列分布式...
  • RabbitMQ遵循了AMQP规范,用消息确认机制来保证:只要消息发送,就能确保被消费者消费来做到了消息最终一致性。而且开源,文档还异常丰富,貌似是实现分布式事务的良好载体 6.1 RabbitMQ消息确认机制 rabbitmq的...
  • Redis的数据模型和最终一致性

    千次阅读 2013-12-14 16:31:56
    最近我注意到Amazon Dynamo的设计和它的原稿,可以说是数据库领域的最有趣的事情之一,Redis的最终一致性从来没有特别讨论过。 Redis的集群实例,系统更偏向一致性而非可用性。 Redis的哨兵(Sentinel)本身是具有...
  • ZooKeeper能保证任何时刻读到的数据绝对一致吗? Zookeeper的特点就是,分布式,高可用,...也就是说可用性和一致性是Zookeeper的关键特性,作为一个消息的中间商,做了一个可靠的信息传递和存储的角色。 但是了解下ZooKeep
  • 博客最后也总结到:由于其性能上的缺陷,对于高并发系统并不适用,所以一般采用柔性事务解决方案,本篇博客要介绍的就是柔性事务方案之一:可靠消息最终一致性方案。【产生背景】 使用两阶段或三阶段提交协议完成...
  • 分布式事务九_基于可靠消息的最终一致性代码

    千次阅读 热门讨论 2018-02-11 22:25:29
    分布式事务九_基于可靠消息的最终一致性代码更多干货分布式事务处理一分布式事务二分布式事务处理三分布式事务四_基于可靠消息的最终一致性分布式事务五_基于可靠消息的最终一致性_异常流程分布式事务六_常规MQ队列...
  • 在分布式系统中会涉及到CAP原理,来保证数据的一致性, 1.什么是CAP: 一致性(Consistency) 可用性(Availability) 分区容忍性(Partition tolerance) CAP原理是说这三个要素最多只能同时满足两点,不可能...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 539,333
精华内容 215,733
关键字:

最终一致性