Paxos作用:取值一致性
Paxos应用:分布式多副本的更新操作序列[opration1,opration2,opration3]需要相同,用Paxos确定操作序列。Google的Chubby、Megastore和Spanner都采用了Paxos来对数据副本的更新序列达成一致。
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,当前请求失效。
议案编号的作用:获取访问权限、避免死锁
活锁:延时,Leader(唯一的proposer)
获取提案
方案一:半数以上的Acceptor向每个Learner发送结果,m*n
方案二:半数以上的Acceptor向一个作为Leader的Learner发送结果,该Learner再同步到其它的Learners,m+1,单点故障
方案三:半数以上的Acceptor向一个Learner集合发送结果,learner集合的容量越大,可靠性越好,网络通信复杂度更高
NWR,操作序列不一致
事务a,set0
事务b, set5
结果:db1 --> set5, set0 --> 0
db2 --> set5, set0 --> 0
db3 --> set0, set5 --> 5
https://raft.github.io/