分布式一致性算法2PC和3PC

  为了解决分布式一致性问题,产生了不少经典的分布式一致性算法,本文将介绍其中的2PC和3PC。2PC即Two-Phase Commit,译为二阶段提交协议。3PC即Three-Phase Commit,译为三阶段提交协议。

分布式系统和分布式一致性问题

  分布式系统,即运行在多台不同的网络计算机上的软硬件系统,并且仅通过消息传递来进行通信和协调。
  分布式一致性问题,即相互独立的节点之间如何就一项决议达成一致的问题。

2PC

  2PC,二阶段提交协议,即将事务的提交过程分为两个阶段来进行处理:准备阶段 和 提交阶段事务的发起者称协调者, 事务的执行者称参与者
 
  阶段1:准备阶段

  1、协调者向所有参与者发送事务内容询问是否可以提交事务并等待所有参与者答复
  2、各参与者, 先锁住资源,然后执行事务操作将Undo和Redo信息记入事务日志中(但不提交事务)。// 就是说 执行sql, 但是不执行 commit 
  3、如参与者执行成功,给协调者反馈YES,即可以提交;如执行失败 ,给协调者反馈NO (或反馈超时) ,即不可提交。
 
  阶段2:提交阶段
  此阶段分两种情况:所有参与者均反馈YES、或任何一个参与者反馈NO。
  所有参与者均反馈YES时,即提交事务。
  任何一个参与者反馈NO时,即中断事务。
 
  提交事务:(所有参与者均反馈YES)
  1、协调者向所有参与者发出正式提交事务的请求(即Commit请求)。// 就是发通知说 准备执行 commit 吧
  2、参与者执行Commit请求,并释放整个事务期间占用的资源。// 就是正式的 执行 commit , 提交之后要释放 资源, 因为锁已经释放。
  3、各参与者向协调者反馈Ack完成的消息。 // ack 也是不能不忘记的
  4、协调者收到所有参与者反馈的Ack消息后,即完成事务提交。

  中断事务:(任何一个参与者反馈NO)
  1、协调者向所有参与者发出回滚请求(即Rollback请求)。
  2、参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。// 就是正式的 执行 rollback,回滚 之后也会 释放 资源, 因为锁已经释放。
  3、各参与者向协调者反馈Ack完成的消息。
  4、协调者收到所有参与者反馈的Ack消息后,即完成事务中断。

小结:

2pc中,参与者没有超时机制, 所以, 如果协调者没有或 没有正确 发生指令过来, 那么 会 一直占用资源。

协调者会等待 参与者的响应, —— 这是2pc 中 唯一的一个超时 时间

提交事务或  中断 事务 的时候, 协调者 都需要 等待 所有 参与者的 ack,  这个过程可能 参与者、协调者、网络 发生故障,如果 协调者正常且 只收到 部分 ack, 怎么办? 事务是否要 继续 完成? 还是记为 待 完成状态?  比较郁闷的是,找了很多的 博客, 没有看到 对这个问题有进行说明的。。   我感觉是 先会记录为待 完成, 然后 要么协调者 停止工作; 要么 发出 error 警告后 继续工作。

2PC的缺陷

  1、同步阻塞:最大的问题即同步阻塞,即:所有参与事务的逻辑均处于阻塞状态。
  2、单点:协调者存在单点问题,如果协调者出现故障,参与者将一直处于锁定状态。
  3、脑裂:在阶段2中,如果只有部分参与者接收并执行了Commit请求,会导致节点数据不一致。// 就是“提交事务”的时候, 协调者只有收到部分的ack.
 
  由于2PC存在如上同步阻塞、单点、脑裂问题,因此又出现了2PC的改进方案,即3PC。
 

3PC

  3PC,三阶段提交协议,是2PC的改进版本,即将事务的提交过程分为CanCommit、PreCommit、do Commit三个阶段来进行处理。
 
  阶段1:CanCommit
  1、协调者向所有参与者 发出包含事务内容的CanCommit请求,询问是否可以提交事务,并等待所有参与者答复。—— 这里的 等待 肯定有 超时机制
  2、参与者收到CanCommit请求后,如果认为可以执行事务操作,则反馈YES并进入预备状态(某个参与者进入预备状态之后, 它会等待 协调者的响应, 这里也有超时机制, 如果超时了, 那么直接 abort ! ),否则反馈NO。 —— 参与者 需要负责 检测资源是否足够, 然后 “预留” 资源。 但是, 这一步骤, 参与者 不会锁住资源。。 预留 不是锁。

  阶段2:PreCommit
  此阶段分两种情况:
  1、所有参与者均反馈YES,即执行事务预提交。
  2、任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务。
 
  事务预提交:(所有参与者均反馈YES时)
  1、协调者向所有参与者发出PreCommit请求,进入准备阶段。
  2、参与者收到PreCommit请求后,执行事务操作,将Undo和Redo信息记入事务日志中(但不提交事务)。—— 锁住资源, 执行事务, 参与者向协调者反馈Ack响应或No响应,并等待最终指令。然后 进入 等待状态, 超时后就直接提交, 为什么呢? 因为进入了 这一步骤, 那么一定是 CanCommit 阶段所有的参与者都是返回yes—— 如果这个时候 协调者又发送了 abort 命令呢? 。
   
 
  中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈时)
  1、协调者向所有参与者发出 abort 请求。
  2、无论收到协调者发出的abort请求,或者在等待协调者请求过程中出现超时,参与者均会中断事务。
 
  阶段3:do Commit
  此阶段也存在两种情况:
  1、所有参与者均反馈Ack响应,即执行真正的事务提交。
  2、任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务。
 
  提交事务:(所有参与者均反馈Ack响应时)
  1、如果协调者处于工作状态,则向所有参与者发出do Commit请求。
  2、参与者收到do Commit请求后,会正式执行事务提交,并释放整个事务期间占用的资源。并且, 各参与者向协调者反馈Ack完成的消息。
  3、协调者收到所有参与者反馈的Ack消息后,即完成事务提交。(  无论如何, 都得完成 这个事务 )
 
  中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈时)
  1、如果协调者处于工作状态,向所有参与者发出abort请求。 //  如果 协调者处于非工作状态, ??
  2、参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。并且, 各参与者向协调者反馈Ack完成的消息。
  3、协调者收到所有参与者反馈的Ack消息后,即完成事务中断。 
 
  注意:进入阶段三后,无论协调者出现问题,或者协调者与参与者网络出现问题,都会导致参与者无法接收到协调者发出的do Commit请求或abort请求。此时,参与者都会在等待超时之后,继续执行事务提交。

3PC的优点和缺陷

  优点:降低了阻塞范围,在等待超时后协调者或参与者会中断事务。避免了协调者单点问题,阶段3中协调者出现问题时,参与者会继续提交事务。 ??? 
 
  缺陷:脑裂问题依然存在,即在参与者收到PreCommit请求后等待最终指令,如果此时协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。
 

后记

  无论2PC或3PC,均无法彻底解决分布式一致性问题。
  解决一致性问题,唯有Paxos,后续将单独总结。

  3pc 其实 相对于 2pc 就是多了一个CanConmmit 阶段, 这个阶段的作用呢? 我想 就是 保证各个 参与者与 协调者 的网络是ok 的,避免 “参与者 立即 执行事务操作” !

       但是不管是2PC还是3PC都存在数据一致性的问题:
2PC:比如协调者在只给部分参与者发送了Commit请求,那就会出现部分参与者执行了Commit,部分没有提交 ( 会一直阻塞 等待!),出现不一致问题。
3PC:在第三阶段,一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit。而不会一直持有事务资源并处于阻塞状态,但是这种机制也会导致数据一致性问题—— 万一 协调者需要的是 abort 呢? 因为 可能协调者 执行延迟发送数据而已。。

还有想要说的是, 2pc 或 3pc 也好, 有没有明确的限定 阶段 的操作?  我认为是有的, 首先要区分是协调者还是参与者, 然后再看具体情况: 

对于 2pc:

协调者一开始处于准备阶段, 发送事务及 询问 后, 然后等待反馈。 但参与者还没有,协调者虽然发送出去了, 但是参与者还没有立即收到, 有一定的网络延迟。 参与者收到了之后, 参与者就算正式进入了 准备阶段。  然后参与者 进行sql操作(并不提交),然后 反馈Yes 或者 No。 这个时候, 反馈已经完毕, 参与者就算了 准备完成了。

参与者等待反馈超时,进入中断流程,完了准备阶段 结束, 但是没有进入提交阶段。

然后,协调者收到了各个参与者的反馈, 然后,

如果有一个是No,然后进入中断流程,完了准备阶段 结束, 但是没有进入提交阶段。

如果都是Yes,然后协调者就算是进入了提交阶段,协调者向各个参与者发送Commit命令,完了就等待响应。

 

参与者并不知道 协调者会发送什么命令过来, 会一直 一直等待。 如果收到了Commit命令,那么就算是进入了提交阶段, 然后正式的 commit, 然后反馈ack(Y 还是N ?这个时候 有可能反馈N 吗?), 然后完成 提交阶段。这个时候参与者是完成了提交阶段, 但是协调者还没有。

协调者如果收到了所有的node 反馈ack, 那么就结束 提交阶段。 (如果不呢?)

注意,各个阶段直接是没有 其他多余的操作的, 也就是没有其他阶段了!

简单说 2pc是这样的,其一,协调者在第一次发送之后 进入阶段一,要么超时时间内收到反馈, 然后处理,然后结束第一阶段; 要么超时后处理,然后结束第一阶段。 发生在这个阶段内的 中断处理也算是 第一阶段的内容。   其二, 协调者在第二次发送之 后进入阶段二,只有一个选择,全部提交,然后收集所有反馈, 没有超时机制(原因待查)。

简单说 3pc是这样的, 它有4个超时时间, 第一阶段,协调者等待 参与者(记为T1),参与者响应后等待协调者(记为T2),第二阶段,协调者等待 参与者(记为T3),参与者响应后等待协调者(记为T4),出现其中任何的一个,那么中断。

90% 转载: 

http://blog.51cto.com/11821908/2058651

https://www.cnblogs.com/shangxiaofei/p/5196260.html

猜你喜欢

转载自www.cnblogs.com/FlyAway2013/p/10111407.html