1、问题提出
-
集群中有 N 个节点,如果一个节点写入后要求同步到剩余 N-1 个节点后再向客户端返回 ok,虽然看起来最保险,但其中任意一个节点同步失败,势必造成整个集群不可用,能否在此基础上稍微提高可用性呢?
-
答案是 (写)多数派,集群节点设置为奇数,同步超过集群中 N/2 个节点成功,则向客户端返回 ok,但存在顺序性问题,如 3 描述
-
多数派写操作成功后的读一致性暂不考虑,思考下图中的两项操作,都满足了多数派通过,但 S3 这台服务器并没有与 S1,S2 达成一致,要达到多数派内部一致性
2、Paxos
Paxos 是一种共识算法,目的是解决之前提到的写多数派时的顺序性问题
Paxos 角色划分:集群中的每个节点都可以充当
-
Proposer:负责生成提案
-
注意:Paxos 算法允许有多个 Proposer 同时提案,但可能会引起活锁问题
-
-
Acceptor:负责批准提案
-
Acceptor 如果只有一个的话,存在单点问题,因此应当有多个
-
-
Learner:负责获取提案,Acceptor 批准提案后,会将提案发送给所有 Learner
执行一个修改操作,不是一上来就能执行,分成两个阶段:
-
准备阶段:Proposer负责接收 client 请求并产生提案,必须由多数派 Acceptor 批准通过提案
-
接受阶段:提案通过后,再将要执行的修改操作广播给 Acceptor,这次仍然多数派通过,此修改才能生效,可以返回响应给客户端
3、算法要点:
-
整个算法分成两个阶段:预备阶段,前两个箭头,接受阶段,后两个箭头。
-
预备阶段的目的是:第一拦截掉旧的提案,第二找到最新的 acceptValue
-
-
对于 Proposer
-
预备阶段只发送
提案号
,接受阶段发送提案号 + 值
-
提案号
n 唯一且全局递增,大的提案号
有更高优先级 -
如果见到最新
已接受值
,就会替换掉 Proposer 自己原来的值,保证一致性
-
-
对于 Acceptor 会持久化以下信息
-
minN(最小提案号),会在预备阶段和接受阶段被更新为更大提案号,会用来决定 Proposer 是否能选中提案
-
acceptN(已接受提案号)和 acceptValue(已接受值),会在接受阶段被更新,如果 minN > n 则不会更新
-
4、例1
-
P 广播提案号 1
-
有 3 个 A 接到提案,此时满足 n > minN,将 minN 更新为 1
-
3个 A 成功返回,P 收到的应答过半,但没有遇到更大的 acceptNo 和 acceptValue,因此使用自己的 value X
-
P 广播提案号和值 1:X
-
3 个 A 接到提案号和值,更新状态,返回 minN 值 1 给 P
-
P 收到过半应答,并检查发现没有出现 minN > 1,便选中提案值 X
5、例2
-
S1 广播提案号 1,想把值更新为 X
-
S5 广播提案号 2,想把值更新为 Y
-
S1、S2、S3 已经经历了 Accept 阶段并选中值 X
-
关键点,S3 也接到了 S5 的prepare 提案,这时是否会有不一致的情况呢?
-
此时 S3 状态已将 acceptN 和 acceptValue 分别更新为 1:X;再返回 S5 的 ack 时就会将 1:X 返回给 S5
-
S5 用返回的 X 替换掉了自己原有的值 Y,并执行后续流程,后续都会同步为 X
6、例3
-
S1 广播提案号 1,想把值更新为 X
-
S5 广播提案号 2,想把值更新为 Y
-
S1、S2、S3 已经经历了 Accept 阶段,与例2 不同的是,值 X 还未选中
-
关键点,S3 也接到了 S5 的prepare 提案,这时是否会有不一致的情况呢?
-
此时 S3 状态将 acceptN 和 acceptValue 分别更新为 1:X;再返回 S5 的 ack 时就会将 1:X 返回给 S5
-
S5 用返回的 X 替换掉了自己原有的值 Y,并执行后续流程,后续都会同步为 X
7、例4
-
S1 广播提案号 1,想把值更新为 X
-
S5 广播提案号 2,想把值更新为 Y
-
关键点,S3 还未经历 Accept 阶段时,就拿到了 S5 的 prepare 提案,这时是否会有不一致的情况呢?
-
S3 在接到 S1 的 accept 请求时,n>=minN 条件不成立,因此没有更新 acceptN 和 acceptValue,并且返回的 minN 是 2
-
对 S1 来说,S3 返回的 minN 大于 n,选中失败;想更新 X 需要发起新一轮提案
-
对 S5 来说,accept 阶段发送的是它自己的 2:Y,后续会把值同步为 Y
8、例5
回顾最早提到的顺序性问题,看 Paxos 能否解决它
下图演示了 Paxos 是如何解决顺序性问题的,分析步骤参考例3
9、Paxos 缺点
-
效率较低,两轮操作只能选中一个值
-
难于理解
-
活锁问题
-
Paxos 是允许多个 Proposer 的,因此如果按上图所示运行,则后一个提案总会让前面提案选中失败,显然死循环
参考资料
-
https://www.youtube.com/watch?v=JEpsBg0AO6o&t=41s Raft 作者讲解 Paxos