一致性协议

/ 分布式

由来

BASE理论我们知道,要解决分布式系统事务问题,重点就是解决数据一致性问题。为了解决这个问题,人们提出许多有关一致性的协议和算法,其中最有代表性的如:2PC3PCPasos算法ZAB算法...

在分布式系统中,各主机节点仅知道自己的事务操作结果,但不知道其他节点的事务状态。因此,为了协调集群的事务处理,协议中都引入了以下几种角色。

2PC

2PC:二阶段提交(Two-Phase Commit)。

协议简述

image

image

阶段一:准备阶段(提交事务请求)

1. 事务询问
    协调者向参与者发送事务内容,询问是否可以执行,本身进入等待参与者响应
    
2. 执行事务
    参与者执行事务操作,并将Undo和Redo信息记入日志
    
3. 参与者向协调者反馈事务询问的响应
    参与者成功执行事务则反馈Yes。执行失败反馈No。

阶段二:提交阶段(执行事务提交)

这里会有两种情况,一个是正常的事务提交,另一种是事务执行失败,进入事务中断流程。

如果准备阶段的所有参与者都反馈Yes,则进入事务提交阶段。

1. 发送提交事务
    协调者向参与者发送Commit请求。
    
2. 事务提交
    参与者执行事务提交,并释放事务执行期间所占资源。
    
3. 反馈事务提交结果
    参与者成功提交事务后,向协调者发送Ack信息。
    
4. 完成事务
    协调者收到所有参与者反馈的Ack信息后,完成事务。

如果准备阶段的任一参与者反馈No,或者响应超时后,则进入事务中断。

1. 发送回滚请求
    协调者向参与者发送Rollback请求。
    
2. 事务回滚
    参与者根据Undo信息进行事务回滚,并释放事务执行期间所占资源。
    
3. 反馈事务回滚结果
    参与者完成回滚事务后,向协调者发送Ack信息。
    
4. 事务中断
    协调者收到所有参与者反馈的Ack信息后,完成事务中断。

2PC是一个强一致性算法,本质其实就是采用先试后做的方式进行事务提交。虽然简单易实现,但是也有很明显的缺陷。

2PC不足

3PC

为解决2PC的诸多劣势,在2PC基础上进行改进,就得到了3PC。

3PC:三阶段提交(Three-Phase Commit)。事务分为canCommitpreCommitdoCommit

协议简述 image

image

阶段一:CanCommit

1. 事务询问
    协调者向参与者发送包含事务内容的canCommit请求,询问是否可以执行,本身进入阻塞等待参与者响应
    
2. 参与者向协调者反馈事务询问的响应
    参与者接受到canCommit请求后,认为自己可以执行事务,则反馈Yes,反之No。

阶段二:PreCommit

这里会有两种情况,一种为正常情况下进入事务预提交阶段,另一种事务不能进行,进入事务中断。

如果准备阶段的所有参与者都反馈Yes,则进入事务预提交阶段。

1. 发送预提交事务请求
    协调者向参与者发送perCommit请求。
    
2. 事务预提交
    参与者执行事务操作,并将Undo和Redo信息记录到事务日志中。
    
3. 参与者向协调者反馈事务执行响应
    参与者成功的执行事务操作后,向协调者发送Ack信息。如果失败,则响应No。同时等待最终指令(commit/abort)。

如果canCommit阶段的任一参与者反馈No,或者响应超时后,则进入事务中断。

1. 发送中断请求
    协调者向参与者发送abort请求。
    
2. 事务中断
    参与者无论是收到协调者的abort请求,还是等待协调者超时都会自行中断事务。

阶段三:doCommit

这里也会出现两种情况。

协调者处于正常工作状态,且收到了所有参与者的Ack响应,则进入提交状态。

1. 发送预提交事务请求
    协调者向参与者发送doCommit请求。
    
2. 事务提交
    参与者执行事务提交操作,完成后释放所占事务资源。
    
3. 反馈事务提交结果
    向协调者发送Ack消息。

4. 完成事务
    协调者接受到所有参与者Ack信息后,完成事务。

协调者处于正常工作状态,且有经过预提交阶段后,有任一参与者发送了No响应。或者等待参与者超时,就会中断事务

1. 发送中断请求
    协调者向参与者发送abort请求。
    
2. 事务中断
    参与者无论是收到协调者的abort请求,参与者利用Undo日志信息完成回滚操作,并释放事务资源。
    
3. 反馈回滚结果
    参与者完成回滚后,向协调者发送Ack消息。
    
4. 中断事务
    协调者收到所有参与者反馈Ack消息后,中断事务。

进入第三阶段,当出现以下情况时:

  • 协调者出现问题
  • 协调者与参与者之间出现网络故障

导致参与者无法收到最终命令(abort/commit),参与者在等待超时后,继续提交事务。

由上可知,3PC可以降低参与者同步阻塞的范围,而且对于协调者单点问题,参与者在超时后,会继续提交事务。但是,显然依然会出现脑裂现象。

其他一致性协议

2PC、3PC都是一致性协议的经典协议,虽然,实现简单但是在性能和容错性方面有所欠缺。目前公认的一致性协议完美解决方案就是Paxos算法。但由于其实现过程困难,目前的实现工程都是基于Paxos算法的变种实现,至今,没有一个完美实现的项目工程。

Paxos算法

Paxos算法:基于消息传递且具有高度容错性的一致性算法。

由于Paxos算法晦涩难懂,所以想要具体了解的同学可以直接查看由Paxos算法提出者Lamport大师本人写的一篇Paxos说明文章《Paxos Made Simple》。下面这句话就是本论的摘要部分。

The Paxos algorithm, when presented in plain English, is very simple.
-- Leslie Lamport 《Paxos Made Simple》# Abstract

感受大师的激励了么? so , 这么简单我们就不说了。

Paxos算法的工程实现

ZAB协议

zookeeper的核心一致性协议。

ZAB协议:原子消息广播协议(ZAB,Zookeeper Atomic Broadcast)。崩溃可恢复的原子消息广播算法。

其他协议

...