一、二阶段提交
使用场景:分布式事务
特点:强一致性、中心化的原子提交协议
过程:准备阶段、提交阶段
角色:协调者、参与者
缺点:同步阻塞:参与者事务资源被占用,协调者宕机没有发出提交指令;协调者需
要等待所有参与者响应;
数据不一致问题:部分参与者提交成功,部分失败;
单点问题:协调者单点
脑裂问题:多个协调者操作参与者造成数据不一致问题;
性能问题:所有参与者都要提交成功才提交;
二、三阶段提交
使用场景:分布式事务
特点:强一致性、中心化的原子提交协议
角色:协调者、参与者
超时机制:
参与者在等待协调者超时后,允许执行默认操作;
协调者在等待参与者超时后,允许执行默认操作;
降低了事务资源锁定范围:
增加了CanCommit阶段,不会像2PC一样从一开始就锁定所有事务资源,3PC在排除点个别不具备事务处理能力的参与者的前提下,在进入第二个阶段锁定资源;
优缺点:减少了事务资源锁定范围、降低了同步阻塞、增加了复杂度、数据依然可能不一致;
三、Paxos共识算法
1 基本概念:
基本保证:已达成共识的提案不会因为任何变故而概念
提案编号
多数派:超过集群一半成员组成集合(n/2+1)
2 角色
Proposer:用于推进协商进程
Acceptor:用于抉择天
learner:用于学习已经达成共识的天,并执行状态转移(记录);
3 阶段
4、Paxos算法的缺点
两个阶段协商,多个Proposer互相影响(如 Proposer1 提出的提案编号为1的请求,Proposer2提出提案编号为2的prepare请求,为2的请求结束后,为1的请求再进入accept的过程是会被拒绝, Proposer1会继续增加编号继续发起请求(这种情况也被成为活锁));
四、Multi Paxos
引入Leader角色(可以有多个leader)
只能由leader发起提案,减少了活锁的概率;
优化Prepare阶段
在没有天冲突的情况下,优化Prepare阶段,优化成一阶段;
流程对比:
过程:
五、ZAB算法
1、 为什么不使用Paxos算法?
Paxos的算法的问题:消息交互次数多,活锁问题,实现难度大(缺少细节实现);必要实现的缺失(少数没有响应的acceptor如何实现日志的堆砌,成员变更,数据的快照,服务崩溃恢复)
2、集群角色
Leader:强一致性,只有一个leader
Follower:提案的协商
Observer:被动接收提案(扩展读请求)
3、成员状态
Election:无集群leader所有节点的状态
Following:Follower角色的状态
Leading:leader角色的状态
Observing:observer角色的状态
4、运行阶段
选举阶段 成员发现 数据同步 消息广播
5、事务表示符(zxid)
SID:机器id
epoch:任期编号
counter:索引序号(每增加一直值索引序号增加1)
zid:事务id(epoch+counter)
6、选举过程
节点角色
Leader:通过选举确定一台机器,为客户端提供读写功能
Follower:提供读功能,参与选举
Observer:提供读功能,不参与选举,也不参与过半成功策略。因此observer是在不影响写性能下,提升集群的读性能
选举规则:优先比较zid,在比较SID(zid>SID)
选举过程
初始化状态(集群初始化):
1 节点启动时,epoch以及counter相同,依据SID进行判断,自身节点最大时,想自己投一票并向其它节点拉票;
2 当获得票数超过节点数一半时成为leader;
3 leader将资深epoch节点+1同步给其它节点;并向其它节点发送心跳
4 新加入的节点加入后即使发现自身SID较大,但已经有leader了,会以follower的身份加入
7、数据同步(广播阶段)
每个节点都是队列维护日志数据;
1、leader接收数据,保存日志为未提交状态,并将日志同步到follower;
2、follower接收请求后保存日志(未提交状态),并告诉leader保存成功;
3、半数以上follower节点保存成功,leader节点把日志提交,发出提交命令;
8、崩溃恢复(数据同步)
a、Diff同步:跟随者不同的数据进行同步(如某些跟随者的提案id小于跟随者的提案id,leader会要求跟随者与自己保持同步)
b、快照同步:当不同步差异较大时使用快照同步
c、上一任leader以跟随者身份加入时,之前未提交的提案,新人leader会要求其删除该提案;
六、Raft算法
1、基本概念
任期(term):类似于zab中的epoch;
成员状态:leader Condidate(leader宕机后Follower节点发现leder宕机,将自己转换为改状态) Follower
2、运行阶段
Leader选举
日志复制
3、RPC消息类型
RequestVote:请求投票消息,用于选举Leader
AppendEntries:追加条目消息
用于Leader向Follower执行日志复制
于Leader与Follower之间的心跳检测。用于Leader与Follower之间的日志对齐
4、leader选举
超时机制:Follower等待心跳的超时机制
等待选举投票时的超时机制
5、投票规则
term大的成员拒绝给term小的成员;
最后一条日志的编号大(包含未提交的)的拒绝给小的投票;
每个成员一届任期内只投一票,先到先得;(ZAB中会重新广播选票结果)
6、选举过程
第一步 启动成为默认角色:刚启动时所有节点默认为follower角色;
第二步 发起投票:follower节点与leader节点的心跳超时时间不同,率先超时者先转为candidate角色,自身term+1,并向自己投一票,发起拉票;
第三步 投票:其它follwer节点接收到率先发起拉票节点请求判断请求节点大于自身term,接收请求投票给它;
第四步 转为leader:一轮选举后产生票数超过半数票数节点成为leader,并向其它节点发送心跳,其它节点全部转为follower角色;并与leader保持同步;结束;
第五步 新一轮选举:若没有选出则进行新一轮选举;若leader宕机也会产生新一轮的投票选举;重复上述步骤;
投票分裂问题:若出现心跳同时超时情况,term同时+1,同时进行拉票请求;两个节点所获得的的票数形同;由于raft算法的集群多数都是单数集群,这种情况多半存在于有个节点宕机的情况;此时只有宕机的节点没有应当,两个节点会继续发送请求拉票;此时会有别的机器也心跳超时,term会在另外两台机器的基础上+1,此时这台机器term最大,成为leader;
7、日志复制
日志只能由Leader流入Follower
日志复制,全局唯一且连续的整数编号;
日志复制转为一阶段复制,下次复制日志时提交上次日志(与ZAB的区别)
七、ZAB和Raft算法的区别
1、共同点
强Leader算法,都是由leader节点进行写请求;
多数派算法;
2、不同点
阶段
协商阶段:Raft算法一阶段提交,在下次同步日志或心跳时,根据日志索引提交之前的日志;
日志流向:Raft中日志只能从Leader流向Follower,ZAB中leader晋升是需要手机所有的Follower的数据来生成新的数据集;
历史日志处理:Raft新的leader会让Follower与其保持一致;ZAB中会将上一任Leader中不明确的日志都认为已提交的状态并复制到其它成员中;
选举过程:选举冲突 raft中引入了随机超时机制,降低了选举冲突;ZAB中通过成员id解决选举冲突;Raft每个成员只能投一票,ZAB中可以头多票;
八、Gossip算法(复制算法,非共识算法)
使用场景:不参与提案抉择的节点进行数据复制(只复制已经通过提案的数据),例如Redis中的集群算法将数据广播到Follower节点中;
复制方式
直接邮寄:同步复制
反熵:每个节点周期性的随机选择其它节点(生产中一般有顺序的复制),然后互相交换自己的所有数据来消除两者之间的差异,直到整个网络节点中数据一致;
谣言传播:采用一传十,十传百的方式;各节点周期性的向随机一组节点广播更新数据;为了使谣言传播停止,增加了Removed状态;当节点收到谣言且该谣言出去Removed时,该节点不会继续传播;
优势:
可扩展、容错:由于各节点之间对等性,允许节点之间任意的增加和减少。
天然的去中心化
传播速度适用于非常庞大的集群
劣势:
达成最终一致性的时间不确定性
消息延迟,只能实现最终一致性,传播过程中,数据不一致
广播rpc消息量大,对网络压力
拜占庭将军问题,不允许存在恶意节点