在分布式系统中,为了保证数据的高可用,一般会将数据保留多个副本(replica),这些个副本会放在不一样的物理机上,为了对用户提供正确的数据,咱们须要保证这些放在不一样物理机上的副本是一致的。为了解决这种分布式一致性问题,提出了不少经典的协议和算法,比较著名的是 两阶段提交协议和三阶段提交协议。算法
两阶段提交协议把分布式事务分为两个阶段,一个是准备阶段,一个是提交阶段。准备阶段和提交阶段都是由事务管理器发起的,两阶段提交协议的流程以下:架构
一、准备阶段:事务管理器向资源管理器发起指令,资源管理器评估本身的状态,若是资源管理器评估指令能够完成。则会写redo或者undo日志,而后锁定资源,执行操做,可是并不会提交并发
二、提交阶段:若是每一个资源管理器明确返回准备成功,事务管理器向资源管理器发起提交指令,资源管理器提交资源变动的事务,释放锁定的资源;若是任何一个资源管理明确返回准备失败,则事务管理器向资源管理器发起停止指令,资源管理器取消已经变动的事务,执行undo日志。释放锁定的资源。分布式
(两阶段提交协议的成功场景图)高并发
咱们从上图中能够看到,两阶段提交协议在准备阶段锁定资源,这是一个重量级的操做,能保证强一致性,可是实现起来复杂、成本大、不够灵活。还有如下缺点:性能
(1)、阻塞:对于任何一次指令都必须收到明确的响应,才会继续进行下一步,不然处于阻塞状态,占用的资源一直被锁定,不会释放spa
(2)、单点故障:若是事务管理器(协调者)挂了(宕机),资源管理器(参与者)没有事务管理器(协调者)指挥,则会一直阻塞,尽管能够经过选举新的协调者替代原有的协调者,可是参与者接收后也宕机,则新上任的协调者没法处理这种状况设计
(3)、脑裂:协调者发送提交指令,有的参与者接收到并执行了事务,有的参与者没有接收到事务就没有执行事务,多个参与者之间是不一致的。3d
上面的问题虽然不多发生,但每次发生都须要人工参与,没有自动化解决方案,所以两阶段提交协议在正常状况下能保证系统的强一致性,但在出现异常的状况下,须要人工干预解决,所以可用性不够好,其实这也符合CAP协议的一致性和可用性不能兼得的原理。日志
三阶段提交协议是两阶段提交协议的改进版本,它经过超时机制解决了阻塞的问题,而且把两个阶段增长为三个阶段。
一、询问阶段:事务管理器(协调者)询问参与者(资源管理器)是否能够完成指令,参与者只须要回答是或者否,而不须要作真正的操做,这个阶段超时会致使停止。
二、准备阶段:若是在询问阶段全部参与者都返回能够执行操做,则协调者向参与者发送预执行请求,而后参与者写 redo 和 undo 日志,执行操做但不提交操做;若是在询问阶段任何一个参与者返回不能执行操做的结果,则协调者向参与者发送停止请求,这里的逻辑和两阶段提交协议的准备阶段是类似的。
三、提交阶段:若是每一个参与者在准备阶段返回准备成功,则协调者向参与者发送提交指令,参与者提交资源变动的事务,释放锁定的资源;若是任何一个参与者返回准备失败,则协调者向参与者发送停止指令,参与者本身取消已经变动的事务,执行 undo 日志,释放锁定的资源。这里的逻辑和两阶段提交协议的提交阶段一致。
(三阶段提交协议的成功场景图)
三阶段提交协议与两阶段提交协议主要有如下不一样点:
(1)、增长了一个询问阶段,询问阶段能够确保尽量早地发现没法执行操做而须要停止的行为,可是它并不能发现全部的这种行为,只会减小这种状况的发生。
(2)、在准备阶段之后,协调者和参与者执行的任务中都增长了超时,一旦超时,则协调者和参与者都会继续提交事务,默认为成功。
三阶段提交协议与两阶段提交协议相比,具备以上的优势,可是一旦发生超时,系统仍然会发生不一致,只不过这种状况不多见。好处是不会阻塞和永远锁定资源。
两阶段和三阶段提交协议,在遇到极端状况时,系统会产生阻塞或者不一致的问题,须要人干预解决。两阶段及三阶段方案中都包含多个参与者、多个阶段实现一个事务。实现事务,性能也是一个很大的问题。所以在互联网的高并发系统中,不多有使用两阶段提交和三阶段提交协议的场景。
后来有人提出了TCC协议,TCC协议将一个任务分红 Try、Confirm、Cancel 三个步骤。正常的流程会先执行 Try,若是执行没有问题,则再执行 Confirm,若是执行过程当中出现了异常。则执行操做的逆操做 Cancel。从正常的流程上讲。这仍是一个两阶段提交协议,但在执行出现异常后有必定的自我修复能力,若是任何参与者出现了问题,则协调者经过执行操做的逆操做来 Cancel 以前的操做。达到最终一致性状态。
能够看出,从时序上讲,若是遇到机端状况,则TCC会有不少问题,如:若是在取消时一些参与者收到指令,而另外一些参与者没有收到指令,则整个系统任然是不一致的,对于这种复杂的状况,系统首先会经过补偿的方式尝试自我修复,若是系统没法修复。仍是须要人工干预解决。
从 TCC 的逻辑上来看,它是简化版的三阶段提交协议,解决了两阶段提交协议的阻塞问题,但仍是没有解决极端状况下出现的问题(不一致和脑裂问题)。然而,TCC 经过自动化补偿手段,将须要人工处理的不一致问题降到最低,也是一种颇有用的解决方案。
(TCC 协议的使用场景)
说明:
一、参考书籍:《分布式服务架构:原理、设计与实战》
二、若有不合适的地方请反馈。综合后更改。