分布式环境的各种问题
从集中式向分布式演变的过程中,必然引入了网络因素,但网络本身具有不可靠性,因此消息丢失和消息延迟变得很普通
2.网络分区
当网络发生异常情况,导致分布式系统中部分节点之间的网络延时不断增大,最终只有部分节点之间能够进行正常通信,而另一些节点不能,这种现象称为网络分区,俗称脑裂
3.三态
请求与响应,存在特有的“三态”概念,即成功,失败与超时。发送消息丢失和响应消息丢失
4.节点故障
服务器出现宕机或者“僵死”现象
事务问题:
ACID事务四个基本要素:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)
CAP理论
1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标。Consistency 一致性,Availability 可用性,Partition tolerance 分区容错性,简称CAP
从CAP定理中我们可以看出,一个分布式系统不可能同时满足三个,可是对于分布式系统分区容错性可以说是最基本的要求,主要在C和A之间找平衡。
BASE理论
BA 是 Basically Available (基本可用):基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性。 比如:响应时间的损失,响应时间变长;功能的损失,购物高峰,部分消费者被引导到降级页面。
S 是Soft state(软状态):允许部分节点的数据存在一定的延时,这个延时不影响可用性。
E 是Eventually consistent(最终一致性):最终一致性很好理解,软状态允许有一定延时,所以这个最终一致含义就是在一定的延时过去之后,所有节点的数据必须保持一致。 相比的假如在更新的同时,所有节点都必须查询到最新的数据,这样的话是一种 强一致性 。 在更新的同时,可以容忍节点查询到的数据不是最新的那么是一种 弱一致性。
为了解决分布式一致性问题,在长期的探索研究过程中,出现了很多一致性协议和算法,最著名的就是二阶段提交协议和三阶段提交协议和Paxos算法。
2PC(二阶段提交)
阶段一:提交事务请求
首先开始事务询问,协调者向所有的参与者发送事务内容,询问是否可以提交事务提交操作,并开始等待各参与者的响应。各参与者执行事务操作,并将Undo和Redo信息计入事务日志中,执行事务操作成功那么返回YES,否则返回No,表示事务不可以执行,此时事务并没有提交。也被称为“投票阶段“。
阶段二:执行事务提交
根据参与者的反馈,分为两种情况
执行事务提交
假如参与者的反馈都是yes,协调者向所有参与者发出Commit请求,参与者收到请求后,会执行事务提交操作,并释放事务资源,向协调者发送Ack消息,协调者收到消息完成事务。
中段事务提交
假如有任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就中断事务,发送Rollback请求,参与者收到后,利用阶段一中记录的Undo信息来执行事务回滚操作,并回滚后释放在整个事务执行期间占用过的资源,完成后滚后,向协调者发送Ack信息。协调者收到后,完成事务中断。
下图展示二阶段提交过程中”事务提交“和”事务中断“两种场景下的交互流程。
缺点:
1.同步阻塞问题:执行过程中,所有参与节点都是事务阻塞型的。
2.单点故障:由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。
3.数据不一致:在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据部一致性的现象。
4.太过保守
如果协调者询问参与者事务提交的过程中,参与者出现故障导致无法获取所有参与者的响应信息的话,这时协调者只能依靠其自身的超市机制来判断是否中断事务,任何一个节点的失败都会导致整个事务的失败。
3PC(三阶段提交)
1.CanCommit阶段 3PC的CanCommit阶段其实和2PC的准备阶段很像。协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。
2.PreCommit阶段 协调者根据参与者的反应情况来决定是否可以继续事务的PreCommit操作。 执行事务预提交 假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会进行事务的预执行,发送预提交请求协调者向参与者发送PreCommit请求,并进入Prepared阶段,参与者接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中,如果参与者成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令:提交或中止。
中断事务
假如有任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就中断事务,发送中断请求。协调者向所有参与者发送abort请求,参与者收到来自协调者的abort请求之后(或超时之后,仍未收到参与者的请求),执行事务的中断。
3.DoCommit阶段
该阶段进行真正的事务提交,也可以分为以下两种情况:
提交事务
发送提交请求。协调者接收到参与者发送的ACK响应,那么他将从预提交状态进入到提交状态,并向所有参与者发送doCommit请求,参与者接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源,事务提交完之后,向协调者发送ACK响应。
中断事务
协调者没有接收到参与者发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。
优点:相较于二阶段提交协议,三阶段提交一些最大的优点就是降低了参与者的阻塞范围,并且能够在出现单点故障后继续达成一致。
缺点:如果进入PreCommit后,协调者发出的是abort请求,假设只有一个参与者收到并进行了abort操作,而其他对于系统状态未知的参与者(网络分区)会根据3PC选择继续Commit,此时系统状态还是会发生不一致性。
三阶段提交协议和两阶段提交协议的不同:
协调者(Coordinator)和参与者(Cohort)都设置了超时机制(在2PC中,只有协调者拥有超时机制,即如果在一定时间内没有收到参与者的消息则默认失败),2PC的准备阶段和提交阶段之间,插入预提交阶段,使3PC拥有CanCommit、PreCommit、DoCommit三个阶段。
本文参考内容来源:《从Paxos到Zookeeper 分布式一致性原理与实践 》