现在的位置: 首页 > 综合 > 正文

两阶段提交协议

2013年08月30日 ⁄ 综合 ⁄ 共 1800字 ⁄ 字号 评论关闭
文章目录

本文以CS服务模式为例,对两阶段提交协议的背景、流程、存在的问题及解决办法等进行了讨论,最后进行了简要总结。

0. 背景

在CS服务模式中,服务器集群提供服务,客户端消费服务。当服务器数据发生变更时,需要保证服务器集群中的单台状态一致,并能够对外提供可用的服务。所谓状态一致,指的是每个单台服务器在完成变更后要数据要一致,比如在一次插入操作中,要么全部插入成功、要么全部插入失败。

客户端较少时,服务器可以为单机,如图1所示。这时,只要变更信息写入服务器并保存到本地磁盘,本次变更就成功了——这时,不存在一致性问题,但存在安全问题。

 

客户端增多时,需要采用服务器集群的方式对外提供服务,如图2所示。服务器1和2的内容完全一样,组成一个服务器集群;客户端1、2和3认为服务器集群是一个服务提供商,他们感受到的、由集群提供的服务是一样的。当产生变更时,变更信息被直接发送给不同的单台服务器,然后由单台服务器完成数据更新。假设在更新过程中,服务器1成功、服务器2失败,这时在客户端看来,服务器集群对外提供了不一致的服务——客户端1和2感受到了更新、客户端3没有感受到变更。两阶段提交协议,是为了解决这个问题而被提出的。

 

1. 协议流程

如图3所示,在两阶段提交协议中,引入了协调者。相比直接更新而言,在两阶段提交中,变更信息首先被发送给了协调者,然后由协调者去控制服务器集群的变更。

两阶段协议的流程如图4所示,描述如下:

准备阶段(prepare)

①协调者向各单台服务器发送prepare消息,询问对方是否具备变更条件;开启prepare询问超时机制

②各单台服务器收到prepare消息后,回复协调者:如果具备条件,回复yes,并挂起自身等待协调者的进一步通知;反之,回复no但不进入挂起状态

 

提交阶段(commit)

③协调者整理各单机的prepare反馈消息。如果全部单台服务器均准时回复yes,则协调者认为此次变更可以推行,于是向各单台服务器发送提交消息commit;如果存在回复no或者超时的服务器,则协调者认为此次变更不可以推行,于是向各单台服务器发送放弃消息abort。在协调者发送完commit或abrot后,其陷入等待状态,直到收到所有单台服务器的回执

④如果收到commit,则单台服务器执行本次更新,更新完毕后回执协调者c_ack(commit_ack);如果收到abort,则单台服务器解除本地资源锁,然后回执协调者a_ack(abort_ack)

 

2. 协议存在的问题及解决思路

由协议流程的描述,可以看出很明显的问题。问题1称为“死等”,协调者在第③步会挂起,直到收到所有单台服务器的回执,如果某台服务器宕机,则协调者将永远挂起;同时,单台服务器也可能会因为等待协调者的进一步指令而挂起;此时,服务器集群将不能对外提供服务。问题2是,如果步骤③协调者发送commit给服务器1成功,在发送给2时发送了宕机,这样,服务器1进行了更新,而服务器2没有收到commit消息而不能进行更新,这样服务器1和服务器2的内容就不一致了(“脑裂”)。

对于问题1,可以采用三阶段提交的方式解决。问题2,可以采用添加观察者的方式解决。本文只讨论问题1的解决方法。三阶段提交的流程如图5所示,其中步骤①和②与两阶段提交协议相同,放弃提交的流程业余两阶段相同。

当协调者认为可以提交变更时,

③协调者首先会向各个单台服务器发送一个pre_commit消息,然后自己进入超市机制;

④如果单台服务器能够正常提交更新,则回复yes同时进入超市机制等待协调者的进一步通知,反之回复no;

⑤协调者收集各单台服务器的pre_commit回执,只有在全部服务器回复了yes的情况下,协调者发送commit给各服务器,然后终止工作;否则,发送abort消息给各服务器,然后停止工作。单台服务器执行commit或abort消息,执行完毕后停止工作。

 

由上述分析可知,两阶段提交中的挂起状态,被三阶段提交改进称为超时机制,从而解决了“死等”的问题;但不能解决“脑裂”问题。

 

3. 总结

有上述分析,两阶段提交协议很大程度上解决了分布式环境下的一致性问题,但仍然存在“死等”和“脑裂”问题;三阶段提交协议解决了“死等”问题,但不能解决“脑裂”问题,还增加了网络通信的开销。实际使用过程中,三阶段提交协议很少使用。两阶段提交不能直接使用,但其变体使用很广泛。

抱歉!评论已关闭.