在分布式环境下,有很多不确定性因素,故障随时都回发生,也讲了CAP理论,BASE理论
我们希望达到,在分布式环境下能搭建一个高可用的,且数据高一致性的服务,目标是这样,但CAP理论告诉我们要达到这样的理想环境是不可能的。这三者最多完全满足2个。
在这个前提下,P(分区容错性)是必然要满足的,因为毕竟是分布式,不能把所有的应用全放到一个服务器里面,这样服务器是吃不消的,而且也存在单点故障问题。
所以,只能从一致性和可用性中找平衡。

怎么个平衡法?在这种环境下出现了BASE理论:
即使无法做到强一致性,但分布式系统可以根据自己的业务特点,采用适当的方式来使系统达到最终的一致性;

BASE由Basically Avaliable 基本可用、Soft state 软状态、Eventually consistent 最终一致性组成,一句话概括就是:平时系统要求是基本可用,除开成功失败,运行有可容忍的延迟状态,但是,无论如何经过一段时间的延迟后系统最终必须达成数据是一致的。


其实可能发现不管是CAP理论,还是BASE理论,他们都是理论,这些理论是需要算法来实现的,今天讲的2PC、3PC、Paxos算法,ZAB算法就是干这事情。

协调者

在分布式系统中,每一个机器节点虽然都能明确的知道自己执行的事务是成功还是失败,但是却无法知道其他分布式节点的事务执行情况。因此,当一个事务要跨越多个分布式节点的时候,为了保证该事务可以满足ACID,就要引入一个协调者(Cooradinator)。其他的节点被称为参与者(Participant)。协调者负责调度参与者的行为,并最终决定这些参与者是否要把事务进行提交。

(一)两阶段提交 two-phase commit (2PC)

一个系统操作多个数据库的时候,这个方案比较常见.
一致性协议 - 图1
首先来看下2PC,翻译过来叫两阶段提交算法,它本身是一致强一致性算法,所以很适合用作数据库的分布式事务。其实数据库的经常用到的TCC本身就是一种2PC.

两阶段提交经常会用到分布式事务里面

回想下数据库的事务,数据库不管是MySQL还是MSSql,本身都提供的很完善的事务支持。

2PC就是两阶段提交,它会把整个事务分成两个阶段,第一个阶段叫做准备阶段,事务在请求都会发一个事务管理器,由事务管理器来管理各种各样的分布式事务,你提交 资源1 的时候,会先告诉事务管理器我已经准备好了,当你提交 资源2 的时候,也会告诉事务管理器我已经准备好了.

这个是第一阶段,事务会接收到一个个资源的请求,这个资源可以是数据库,如果是分布式事务的话,这个资源1也好,资源2也好,它都是一个个的事务,资源1或者资源2 会写undo和redo事务日志(undo和redo就是回退和回滚的日志),但是资源1和资源2都不会提交.

我们数据库里面怎么判断我们的资源是应该提交还是回滚?接收到commit就会提交,否则就是回滚.

第二阶段是当事务管理器接收到所有资源(资源1和资源2)的反馈的时候,此时两个资源都没报错啥的(说明执行成功了),此时事务管理器会发送commit命令分别给资源1和资源2,让这两个资源给我一个一个的提交,这个就是第二个阶段.
如果事务管理器发现commit失败了(至少一个资源失败了),它会发送rollback命令给两个资源, 让它们全部都回滚.这就是2PC的一个逻辑.


一致性协议 - 图2

MySQL后面学分表分库的时候会讲到在innodb存储引擎,对数据库的修改都会写到undo和redo中,不只是数据库,很多需要事务支持的都会用到这个思路。

对一条数据的修改操作首先写undo日志,记录的数据原来的样子,接下来执行事务修改操作,把数据写到redo日志里面,万一捅娄子,事务失败了,可从undo里面回复数据。

不只是数据库,在很多企业里面,比如华为等提交数据库修改都回要求这样,你要新增一个字段,首先要把修改数据库的字段SQL提交给DBA(redo),这不够,还需要把删除你提交字段,把数据还原成你修改之前的语句也一并提交者叫(undo)

数据库通过undo与redo能保证数据的强一致性,要解决分布式事务的前提就是当个节点是支持事务的。

这在个前提下,2pc借鉴这失效,首先把整个分布式事务分两节点,首先第一阶段叫准备节点,事务的请求都发送给一个个的资源,这里的资源可以是数据库,也可以是其他支持事务的框架,他们会分别执行自己的事务,写日志到undo与redo,但是不提交事务。

当事务管理器收到了所以资源的反馈,事务都执行没报错后,事务管理器再发送commit指令让资源把事务提交,一旦发现任何一个资源在准备阶段没有执行成功,事务管理器会发送rollback,让所有的资源都回滚。这就是2pc,非常非常简单。

说他是强一致性的是他需要保证任何一个资源都成功,整个分布式事务才成功。

参考:
https://www.yuque.com/docs/share/cf1fefd3-815d-47e8-a25b-47e29d1b4d6a#

优缺点


优点:原理简单,实现方便
缺点:同步阻塞,单点问题,数据不一致,容错性不好

同步阻塞
在二阶段提交的过程中,所有的节点都在等待其他节点的响应(就是等待第一阶段事情都做完了才能接着执行第二阶段,否则都得等着.),无法进行其他操作。这种同步阻塞极大的限制了分布式系统的性能。

单点问题
协调者在整个二阶段提交过程中很重要,如果协调者(事务管理器)在提交阶段出现问题(比如事务管理器死机了),那么整个流程将无法运转。更重要的是,其他参与者将会处于一直锁定事务资源的状态中,而无法继续完成事务操作。

数据不一致
假设当协调者向所有的参与者发送commit请求之后,发生了局部网络异常,或者是协调者在尚未发送完所有 commit请求之前自身发生了崩溃,导致最终只有部分参与者收到了commit请求。这将导致严重的数据不一致问题。
什么是局部网络异常呢?
假如说资源A发送commit命令,资源B发送commit命令,资源C正在准备发送commit命令,忽然断电了,这个就是局部网络异常.


容错性不好
二阶段提交协议没有设计较为完善的容错机制,任意一个节点(事务管理器,多个资源都可能会失败)是失败都会导致整个事务的失败。