分布式⼀致性协议
⼀致性模型
⼀致性(Consistency)是指多副本(Replications)问题中的数据⼀致性。关于分布式系统的⼀致性模型有以下⼏种:
强⼀致性
当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值,直到这个数据被其他数据更新为⽌。
但是这种实现对性能影响较⼤,因为这意味着,只要上次的操作没有处理完,就不能让⽤户读取数据。
弱⼀致性
虾米怎么做好吃
系统并不保证进程或者线程的访问都会返回最新更新过的值。系统在数据写⼊成功之后,不承诺⽴即可以读到最新写⼊的值,也不会具体的承诺多久之后可以读到。甚⾄不能保证可以访问到。
最终⼀致性
最终⼀致性也是弱⼀致性的⼀种,它⽆法保证数据更新后,所有后续的访问都能看到最新数值,⽽是需要⼀个时间,在这个时间之后可以保证这⼀点(就是在⼀段时间后,节点间的数据会最终达到⼀致状态),⽽在这个时间内,数据也许是不⼀致的,这个系统⽆法保证强⼀致性的时间⽚段被称为「不⼀致窗⼝」。不⼀致窗⼝的时间长短取决于很多因素,⽐如备份数据的个数、⽹络传输延迟速度、系统负载等。
最终⼀致性在实际应⽤中⼜有多种变种:
七夕是几月几日类型说明
因果⼀致性如果 A 进程在更新之后向 B 进程通知更新的完成,那么 B 的访问操作将会返回更新的值。⽽没有因果关系的 C 进程将会遵循最终⼀致性的规则(C 在不⼀致窗⼝内还是看到是旧值)。
读你所写⼀致性因果⼀致性的特定形式。⼀个进程进⾏数据更新后,会给⾃⼰发送⼀条通知,该进程后续的操作都会以最新值作为基础,⽽其他的进程还是只能在不⼀致窗⼝之后才能看到最新值。
会话⼀致性读你所写⼀致性的特定形式。进程在访问存储系统同⼀个会话内,系统保证该进程可以读取到最新之,但如果会话终⽌,重新连接后,如果此时还在不⼀致窗⼝内,还是可嫩读取到旧值。
单调读⼀致
性
如果⼀个进程已经读取到⼀个特定值,那么该进程不会读取到该值以前的任何值。
单调写⼀致
性建设工程管理
系统保证对同⼀个进程的写操作串⾏化。
⼀致性模型
⼀致性协议
为了解决分布式系统的⼀致性问题,在长期的研究探索过程中,业内涌现出了⼀⼤批经典的⼀致性协议和算法,其中⽐较著名的有⼆阶段提交协议(2PC),三阶段提交协议(3PC)和 Paxos 算法。
Google 2009年 在 的分享中,对⼀致性协议在业内的实践做了⼀简单的总结,如下图所⽰,这是 CAP 理论在⼯业界应⽤的实践经验。
其中,第⼀⾏表头代表了分布式系统中通⽤的⼀致性⽅案,包括冷备、Master/Slave、Master/Master、两阶段提交以及基于 Paxos 算法的解决⽅案,第⼀列表头代表了分布式系统⼤家所关⼼的各项指标,包括⼀致性、事务⽀持程度、数据延迟、系统吞吐量、数据丢失可能性、故障⾃动恢复⽅式。
分布式事务
分布式事务是指会涉及到操作多个数据库的事务。其实就是将对同⼀库事务的概念扩⼤到了对多个库的事务。⽬的是为了保证分布式系统中的数据⼀致性。分布式事务处理的关键是必须有⼀种⽅法可以知道事务在任何地⽅所做的所有动作,提交或回滚事务的决定必须产⽣统⼀的结果(全部提交或全部
回滚)
在分布式系统中,各个节点之间在物理上相互独⽴,通过⽹络进⾏沟通和协调。由于存在事务机制,可以保证每个独⽴节点上的数据操作可以满⾜ACID。但是,相互独⽴的节点之间⽆法准确的知道其他节点中的事务执⾏情况。所以从理论上讲,两台机器理论上⽆法达到⼀致的状态。如果想让分布式部署的多台机器中的数据保持⼀致性,那么就要保证在所有节点的数据写操作,要不全部都执⾏,要么全部的都不执⾏。但是,⼀台机器在执⾏本地事务的时候⽆法知道其他机器中的本地事务的执⾏结果。所以他也就不知道本次事务到底应该commit还是 roolback。所以,常规的解决办法就是引⼊⼀个“协调者”的组件来统⼀调度所有分布式节点的执⾏。
XA规范
X/Open 组织(即现在的 Open Group )定义了分布式事务处理模型。 X/Open DTP 模型( 1994 )包括应⽤程序( AP )、事务管理器( TM )、资源管理器( RM )、通信资源管理器( CRM )四部分。⼀般,常见的事务管理器( TM )是交易中间件,常见的资源管理器( RM )是数据库,常见的通信资源管理器( CRM )是消息中间件。
通常把⼀个数据库内部的事务处理,如对多个表的操作,作为本地事务看待。数据库的事务处理对象是本地事务,⽽分布式事务处理的对象是全局事务。 所谓全局事务,是指分布式事务处理环境中,
多个数据库可能需要共同完成⼀个⼯作,这个⼯作即是⼀个全局事务,例如,⼀个事务中可能更新⼏个不同的数据库。对数据库的操作发⽣在系统的各处但必须全部被提交或回滚。此时⼀个数据库对⾃⼰内部所做操作的提交不仅依赖本⾝操作是否成功,还要依赖与全局事务相关的其它数据库的操作是否成功,如果任⼀数据库的任⼀操作失败,则参与此事务的所有数据库所做的所有操作都必须回滚。
⼀般情况下,某⼀数据库⽆法知道其它数据库在做什么,因此,在⼀个 DTP 环境中,交易中间件是必需的,由它通知和协调相关数据库的提交或回滚。⽽⼀个数据库只将其⾃⼰所做的操作(可恢复)影射到全局事务中。
XA 就是 X/Open DTP 定义的交易中间件与数据库之间的接⼝规范(即接⼝函数),交易中间件⽤它来通知数据库事务的开始、结束以及提交、回滚等。 XA 接⼝函数由数据库⼚商提供。
⼆阶提交协议和三阶提交协议就是根据这⼀思想衍⽣出来的。可以说⼆阶段提交其实就是实现XA分布式事务的关键(确切地说:两阶段提交主要保证了分布式事务的原⼦性:即所有结点要么全做要么全不做)
西门子英文2PC
它可以保证在分布式事务中,要么所有参与进程都提交事务,要么都取消事务,即实现 ACID 的原⼦性(A)。
在数据⼀致性中,它的含义是:要么所有副本(备份数据)同时修改某个数值,要么都不更改,以此来保证数据的强⼀致性。
2PC 过程
2PC分为2个阶段:
表决阶段:
1、事务询问
Coordinator (协调者)向所有的参与者发送⼀个 vote request
2、执⾏事务
表格里面怎么换行
各个参与者节点执⾏事务操作,并讲Undo和Redo信息记⼊事务⽇志中
3、各参与者向协调者反馈事务询问的响应.
如果参与者成功执⾏了事务操作,那么就反馈给协调者vote_commit响应,表⽰事务可以执⾏,如果没有参与者成功执⾏事务,那么就反馈给协调者vote_abort响应,表⽰事务不可以执⾏.
提交阶段:
Coordinator 收到所有参与者的表决信息,如果所有参与者⼀致认为可以提交事务,那么 Coordinator 就会发送
GLOBAL_COMMIT 消息,否则发送 GLOBAL_ABORT 消息;对于参与者⽽⾔,如果收到 GLOBAL_
COMMIT 消息,就会提交本地事务,否则就会取消本地事务。
2PC⼀致性问题
2PC 在执⾏过程中可能发⽣ Coordinator 或者参与者突然宕机的情况,在不同时期宕机可能有不同的现象。
情况分析及解决⽅案
Coordinator 挂了,参与者没挂这种情况其实⽐较好解决,只要找⼀个 Coordinator 的替代者。当他成为新的 Coordinator 的时候,询问所有参与者的最后那条事务的执⾏情况,他就可以知道是应该做什么样的操作了。所以,这种情况不会导致数据不⼀致。
参与者挂了(⽆法恢
复),Coordinator 没
挂
如果挂了之后没有恢复,那么是不会导致数据⼀致性问题。
参与者挂了(后来恢复),Coordinator 没挂恢复后参与者如果发现有未执⾏完的事务操作,直接取消,然后再询问 Coordinator ⽬前我应该怎么做,协调者就会⽐对⾃⼰的事务执⾏记录和该参与者的事务执⾏记录,告诉他应该怎么做来保持数据的⼀致性。
情况分析及解决⽅案
还有⼀种情况是:参与者挂了,Coordinator 也挂了,需要再细分为⼏种类型来讨论:情况分析及解决⽅案
Coordinator 和参与者在第⼀阶段挂了由于这时还没有执⾏ commit 操作,新选出来的 Coordinator 可以询问各个参与者的情况,再决定是进⾏ commit 还是roolback。因为还没有 commit,所以不会导致数据⼀致性问题。
Coordinator 和参与者在第⼆阶段挂了,但是挂的这个参与者在挂之前还没有做相关操作这种情况下,当新的 Coordinator 被选出来之后,他同样是询问所有参与者的情况。只要有机器执⾏了 abort(roolback)操作或者第⼀阶段返回的信息是 No 的话,那就直接执⾏ roolback 操作。如果没有⼈执⾏ abort 操作,但是有机器执⾏了commit 操作,那么就直接执⾏ commit 操作。这样,当挂掉的参与者恢复之后,只要按照 Coordinator 的指⽰进⾏事务的commit 还是 roolback 操作就可以了。因为挂掉的机器并没有做 commit 或者 roolback 操作,⽽没有挂掉的机器们和新的Coordinator ⼜执⾏了同
样的操作,那么这种情况不会导致数据不⼀致现象。
Coordinator 和参与者在第⼆阶段挂了,挂的这个参与者在挂之前已经执⾏了操作。但是由于他挂了,没有⼈知道他执⾏了什么操作。这种情况下,新的 Coordinator 被选出来之后,如果他想负起 Coordinator 的责任的话他就只能按照之前那种情况来执⾏commit 或者 roolback 操作。这样新的 Coordinator 和所有没挂掉的参与者就保持了数据的⼀致性,我们假定他们执⾏了commit。但是,这个时候,那个挂掉的参与者恢复了怎么办,因为他已经执⾏完了之前的事务,如果他执⾏的是 commit 那还好,和其他的机器保持⼀致了,万⼀他执⾏的是 roolback 操作呢?这不就导致数据的不⼀致性了么?虽然这个时候可以再通过⼿段让他和 Coordinator 通信,再想办法把数据搞成⼀致的,但是,这段时间内他的数据状态已经是不⼀致的了!
2PC优缺点
简单总结⼀下 2PC 的优缺点:
优点:原理简洁清晰、实现⽅便;
缺点:同步阻塞、单点问题、某些情况可能导致数据不⼀致。
关于这⼏个缺点,在实际应⽤中,都是对2PC 做了相应的改造:
1. 同步阻塞:2PC 有⼏个过程(⽐如 Coordinator 等待所有参与者表决的过程中)都是同步阻塞的,所有参与该事务操作的逻辑都处
于阻塞状态,各个参与者在等待其他参与者响应的过程中,将⽆法进⾏其他任何操作。在实际的应⽤中,这个问题是通过超时判断机制来解决的,但并不能完全解决同步阻塞问题;
2. Coordinator 单点问题:实际⽣产应⽤中,Coordinator 都会有相应的备选节点;
3. 数据不⼀致:这个在前⾯已经讲述过了,如果在第⼆阶段,Coordinator 和参与者都出现挂掉的情况下,是有可能导致数据不⼀致
的。
3PC
三阶段提交协议(Three-Pha Commit, 3PC)最关键要解决的就是 Coordinator 和参与者同时挂掉导致数据不⼀致的问题,所以
3PC 把在 2PC 中⼜添加⼀个阶段,这样三阶段提交就有:CanCommit、PreCommit 和 DoCommit 三个阶段。
3PC 过程
CanCommit
1.事务询问协调者向参与者发送CanCommit请求。询问是否可以执⾏事务提交操作。然后开始等待参与者的响应。
2.响应反馈参与者接到CanCommit请求之后,正常情况下,如果其⾃⾝认为可以顺利执⾏事务,则返回Yes响应,并进⼊预备状态。否则反馈No
PreCommit
执⾏事务预提交:如果 Coordinator 接收到各参与者反馈都是Yes,那么执⾏事务预提交:
1. 发送预提交请求:Coordinator 向各参与者发送 preCommit 请求,并进⼊ prepared 阶段;
2. 事务预提交:参与者接收到 preCommit 请求后,会执⾏事务操作,并将 Undo 和 Redo 信息记录到事务⽇记中;
3. 各参与者向 Coordinator 反馈事务执⾏的响应:如果各参与者都成功执⾏了事务操作,那么反馈给协调者 ACK 响应,同时等待最终
指令,提交 commit 或者终⽌ abort,结束流程;
面包烘焙中断事务:如果任何⼀个参与者向 Coordinator 反馈了 No 响应,或者在等待超时后,Coordinator ⽆法接收到所有参与者的反馈,那么就会中断事务。
1. 发送中断请求:Coordinator 向所有参与者发送 abort 请求;
2. 中断事务:⽆论是收到来⾃ Coordinator 的 abort 请求,还是等待超时,参与者都中断事务
doCommit
>我的诊所>rialnumber