分布式事物:两阶段提交

两阶段提交是指,为了使基于分布式系统架构下的所有节点进行事务提交时保持一致性而设计的一种算法,通常也叫做两阶段提交协议。在分布式系统中,通常一个事务会跨越很多个节点,但是每个节点只能知悉自己的操作是否成功,对于其他节点操作的成功与否无法知晓。所以,为了保持分布式事务提交的ACID特性,需要引入一个组件来统一管理各个节点的操作结果,并最终决定是否要把这些节点的操作结果进行提交。–维基百科

两阶段提交主要包括一个协调者和数个参与者,在第一阶段中,任何一个参与者可以单方面的终止事务,在第一阶段的末期,所有的参与者都不能单方面的终止事务。
具体的步骤如下:

  • 提交请求阶段:也称投票阶段,协调者向所有参与者发起询问,参与者如果已经就绪,就回复”ready”,否则就回复”not ready”。后一种情况多发生在并发事务有冲突或者请求超时上。这个阶段,各个参与者并不会真正的提交,而是会将提交的操作写入日志。
  • 提交阶段:
    • 当所有的参与者都回复”ready”,并且协调者收到消息后,将会对所有的参与者发送”commit”指令,所有的参与者执行事务,并回送”commit ACK”给协调者,协调者收到后,结束事务。
    • 当有任何一个参与者回复”not ready”,并且协调者收到消息后,将会对所有的参与者发送”abort commit”指令,参与者终止事务并回送”abort ACK”,协调者收到后,结束事务。

缺陷

  • 对节点的容错处理非常脆弱,尤其是协调者出现了错误。
  • 会产生阻塞的情形。虽然2PC追求一致性,但是并不完美。如果锁没有被释放,将会导致数据不可以被访问。
  • 有一个不确定期,无法准确的确定参与者在那一个时间段能够单方面的做决定。
  • 耗时,耗费很多时间在投票表决阶段。

使用2PC保证正对所有资源的更新要么都操作要么都不操作,同时也带来了额外的开销,协调操作会对可扩展性,性能以及延迟造成不利影响,当增加依赖的资源和用户基数变大时,这种不利影响会呈几何级扩大。可用性也依赖所有依赖的资源的可用性。

参考文献