Paxos算法
Paxos作用:取值一致性
Paxos应用:
分布式多副本的更新操作序列[opration1,opration2,opration3]需要相同,用Paxos确定操作序列。Google的Chubby、Megastore和Spanner都采用了Paxos来对数据副本的更新序列达成一致。
Google文件系统GFS中使用Chubby锁服务来实现对GFS Master服务器的选举;在BigTable中,Chubby同样被用于Master 选举。
Paxos组成:系统内由多个Acceptor组成,负责存储和管理变量var;外部有多个Proposer任意并发调用API,向系统提交不同的var值;learner记录最终确定的值。
Paxos容错性:可以容忍任意Proposer故障;可以容忍半数以下的Acceptor故障。
Paxos一致性:如果var的值没有确定,则为null;一旦确定,则不可更改,后者认同前者。
Paxos算法详解:
实现一(锁方式)
实现:
Proposer向Accpetor申请互斥访问权,一旦Acceptor接收了某个Proposer的值,则var确定,其它proposer不可更改此值。
如果一个proposer获取到了Acceptor的访问权,且Acceptor的值不为null,此proposer不可修改此值并应用此值。
缺点:
一个Proposer首先获取到一个Acceptor的互斥锁,接着在这个proposer释放此锁之前自己挂掉了,因为它的锁还没有释放,所以其它的Proposer都永远不能获取到锁,出现了死锁问题。
实现二(并发抢占式)
为了避免方式一的死锁问题,Paxos采用并发的抢占式的,发送议案编号的方式避免死锁。每个议案编号全局唯一,递增。
阶段一:
Proposer调用Acceptor::prepared(议案编号);
Proposer向Acceptor发送议案编号以申请访问权限;Acceptor采用喜新厌旧的方式处理这一阶段的请求,当新编号大于旧编号时,把新编号赋值给maxN,并返回var的值,此时旧访问权失效,不再接受旧提交,只接受新提交;当新编号不大于旧编号时,Acceptor忽略此次请求,此次请求失效。
阶段二:
Proposer调用Acceptor::accept(议案编号,议案内容);
Proposer向Acceptor发送提案请求批准;Acceptor接受到提案后,首先验证,当Proposer的编号 == maxN,设置值;当Proposer的编号 < maxN,当前请求失效,当Proposer的编号不可能大于maxN。
议案编号的作用:获取访问权限、避免死锁
获取提案
方案一:半数以上的Acceptor向每个Learner发送结果,m*n
方案二:半数以上的Acceptor向一个作为Leader的Learner发送结果,该Learner再同步到其它的Learners,m+1,单点故障
方案三:半数以上的Acceptor向一个Learner集合发送结果,learner集合的容量越大,可靠性越好,网络通信复杂度更高
活锁解决方案:
1、延时;
2、Leader(唯一的proposer)
Multi Paxos
上文提到的是Basic Paxos 算法,活锁、效率低(每次都要经过2轮RPC)、难实现
Multi Paxos改进:
1、唯一的proposer(Leader),解决了活锁的问题
2、且不需要2轮RPC
Multi Paxos过程:
1、通过传统的Paxos选主。
2、之后只要1轮RPC就可以,所有的请求都由Leader来处理
强一致性算法:Paxos、 Raft(Multi paxos)、ZAB(Multi paxos)
Raft
https://raft.github.io/
选主,每个节点都有一个随机的时钟,每个节点的时钟都不一样,最先超时的节点向其它的节点发送请求,要求把自己设为主,半数通过,成为主。
更新,主节点广播,半数通过,提交(心跳包携带数据)。
ZAB,原子广播协议
故障恢复,选主,当leader出现故障后,集群进入选主阶段,一般是集群中拥有最大事务ID的节点会成为新的主节点。
原子广播过程(和Raft一样,也类似于二阶段提交协议):
1、leader从客户端接收一个请求
2、leader生成一个新事务,并为此事务生成一个事务ID,接着把事务通知给其它follower;follower接收到此请求后,把事务ID加入一个队列里,并执行事务,最后响应leader
5、leader收到半数确定,发送提交请求;follower在提交此事务前,会判断此事务ID是不是比队列中所有的事务ID都小,如果是则提交;如果不是,等待更小的事务的提交命令。
ZAB除了事务ID,还在一个LeaderID。
弱一致性算法(最终一致性):DNS、Gossip(Cassandra的通信协议)
一致性算法还有一种多数派的方式NWR,一半以上写入成功就成功
操作序列不一致,事务a和事务b并发
事务a,set0
事务b, set5
结果:db1 --> set5, set0 --> 0
db2 --> set5, set0 --> 0
db3 --> set0, set5 --> 5