分布式系统中著名的 CAP 理论,在一个分布式系统中不可能同时满足:一致性( C onsistency)、可用性( A vailability),以及分区容错性( P artition Tolerance)。一般来说,P是前提,关键是先A还是C。
- 一致性: 在分布式系统中数据往往存在多个副本,一致性描述的是这些副本中的数据在内容和组织上的一致。
- 可用性: 描述系统对用户的服务能力,所谓可用是指在用户能够容忍的时间范围内返回用户期望的结果。
- 分区容错性: 分布式系统通常由多个节点构成,由于网络是不可靠的,所以存在分布式集群中的节点因为网络通信故障导致被孤立成一个个小集群的可能性,即网络分区,分区容错性要求在出现网络分区时系统仍然能够对外提供一致性的可用服务。
1 两段式提交(2PC)
1.1 两阶段提交过程
- 准备阶段(投票阶段):协调者将通知事务参与者准备提交或取消事务,然后进入表决过程。在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地作业执行成功)或取消(本地作业执行故障)。
- 提交阶段(执行阶段):协调者将基于第一个阶段的投票结果进行决策:提交或取消。
当且仅当所有的参与者同意提交事务协调者才通知所有的参与者提交事务,否则协调者将通知所有的参与者取消事务。
2.2 两阶段提交缺点
- 同步阻塞:执行过程中,所有参与者都是事务阻塞型的,当参与者占有公共资源时,其他第三方访问公共资源不得不处于阻塞状态。
- 单点故障:一旦协调者发生故障,参与者会一直阻塞下去,尤其是第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题。
- 数据不一致:在提交阶段,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了commit请求,而在这部分参与者接到commit请求之后就会执行commit操作,但是其他部分未接到commit请求的机器则无法执行事务提交,于是整个分布式系统便出现了数据部一致性的现象。
2 三阶段提交(3PC)
对二阶段提交方式进行改进
- 引入超时机制
- 在第一阶段和第二阶段插入一个准备阶段
2.1 三阶段提交执行
三阶段提交协议在协调者和参与者中都引入超时机制,并且把两阶段提交协议的第一个阶段拆分成了两步:询问,然后再锁资源,最后真正提交。
- CanCommit阶段:3PC的CanCommit阶段其实和2PC的准备阶段很像,协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。
- PreCommit阶段:协调者根据参与者的反应情况来决定是否可以继续事务的PreCommit操作。
- DoCommit阶段
2.2 三阶段提交缺点
- 数据不一致:如果进入PreCommit后,协调者发出的是abort请求,假设只有一个参与者收到并进行了abort操作,而其他对于系统状态未知的参与 者会根据3PC选择继续Commit,此时系统状态发生不一致性。
3 2PC和3PC异同
- 对于协调者和参与者都设置了超时机制,在2PC中,只有协调者拥有超时机制,即如果在一定时间内没有收到参与者的消息则默认失败。
- 在2PC的准备阶段和提交阶段之间,插入预提交阶段,使3PC拥有CanCommit、PreCommit、DoCommit三个阶段,PreCommit是一个缓冲,保证了在最后提交阶段之前各参与节点的状态是一致的。
- 解决了二阶段同步阻塞问题,是“非阻塞协议”。
4 分布式一致性算法基本概念
- term——一个任期的编号
- index——在一个term内的序号,一般是连续递增的
- message——分布式系统中各个server交互的单元
- log——一次操作记录,比如一条redolog日志或者binlog
- slot—— log序列中每一个log entry的全局位点
5 Paxos协议
5.1 Paxos
我们通常说的paxos是指basic paxos,它包含两个阶段
- 准备阶段
- 提交阶段
Basic Paxos达成一次决议至少需要两次网络来回,并发情况下可能需要更多,极端情况下甚至可能形成活锁,效率低下
5.2 Multi-Paxos
basic paxos 的协议更复杂,且相对效率较低。所以现在所有的和paxos有关的协议,一定是基于multi-paxos来实现的。multi paxos根据Basic Paxos的改进:整个系统只有一个Proposer,称之为Leader。同一Proposer连续提议时可以优化跳过Prepare直接进入Accept阶段。
应用代表
- Chubby
6 Raft协议
与Paxos相比,Raft强调的是易理解、易实现,Raft和Paxos一样只要保证超过半数的节点正常就能够提供服务。
paxos和raft主要异同
- 不同点——raft只允许拥有最新数据的server变成leader,而paxos没有这个限制。这是Paxos的灵活性,当然这个灵活性也带来了额外的复杂度。
- 相同点——leader都很容易成为系统的瓶颈,因为所有的请求都会经过leader。在有Leader的集群中,消息处理的时间复杂度为O(N),而在无leader的集群中,消息处理的时间复杂度为O(1)。
6.1 三个子问题
Raft使用了分而治之的思想,把算法分为三个子问题:
- 选举(Leader election)
- 日志复制(Log replication)
- 安全性(Safety)
6.2 三个状态
- Leader
- Follower
- Candidate
6.3 应用产品
- etcd
- Redis
- RocketMQ
- Google Omega
6.4 Multi-Raft
许多NewSQL数据库的数据规模上限都定位在100TB以上,为了负载均衡,都会对数据进行分片(sharding),所以就需要使用多个Raft集群(即Multi-Raft),每个Raft集群对应一个分片。在多个Raft集群间可增加协同来减少资源开销、提升性能(如:共享通信链接、合并消息等)。
multi-raft应用产品
- TiDB
- PolarDB
- CockroachDB
Parallel-Raft是PolarDB中的Multi-Raft实现,通过支持乱序日志复制(乱序确认、乱序提交、乱序应用)等手段来提升性能。
7 ZAB协议
ZAB也是对Multi Paxos算法的改进,大部分和raft相同,和raft算法的主要区别:
- 对于Leader的任期,raft叫做term,而ZAB叫做epoch
- 在状态复制的过程中,raft的心跳从Leader向Follower发送,而ZAB则相反。
7.1 协议三种状态
- Looking :系统刚启动时或者Leader崩溃后正处于选举状态
- Following :Follower节点所处的状态,Follower与Leader处于数据同步阶段
- Leading :Leader所处状态,当前集群中有一个Leader为主进程
7.2 协议四个阶段
- Election :在Looking状态中选举出Leader节点,Leader的lastZXID总是最新的
- Discovery :Follower节点向准Leader推送FOllOWERINFO,该信息中包含了上一周期的epoch,接受准Leader的NEWLEADER指令,检查newEpoch有效性,准Leader要确保Follower的epoch与ZXID小于或等于自身的
- sync :将Follower与Leader的数据进行同步,由Leader发起同步指令,最总保持集群数据的一致性
- Broadcast :Leader广播Proposal与Commit,Follower接受Proposal与Commit
- Recovery :在Election阶段选举出Leader后本阶段主要工作就是进行数据的同步,使Leader具有highestZXID,集群保持数据的一致性
7.3 应用产品
- zookeeper
8 Quorum协议
Quorum借鉴了Paxos的思想,实现上更加简洁,同样解决了在多个节点并发写入时的数据一致性问题。Quorum最初的思路来自“鸽巢原理”,同一份数据虽然在多个节点拥有多份副本,但是同一时刻这些副本只能用于读或者只能用于写。
应用代表
- kafka
参考
https://www.cnblogs.com/AndyAo/p/8228099.html
https://blog.csdn.net/westbrookliu/article/details/99713365
https://www.cnblogs.com/xybaby/p/10124083.html
https://blog.csdn.net/wangyangzhizhou/article/details/52698555