paxos算法_分布式共识算法:Paxos的泛化与优化扩展小结

78d4763296afdeec6cc22e4b34eed34f.png

注意1: 知乎上已经有很多Paxos基本算法的介绍了, 这里不在赘述; 但是本文要引用Paxos的定义的一些术语, 比如1a, 1b, 2a, 2b信息, proposer, acceptor... 所以阅读本文前, 读者需要至少理解Paxos的经典算法实现; (也欢迎收藏, 以后理解了paxos基本算法再来阅读)

注意2: 本文的主要内容来自于题图的这篇150多页的论文Distributed consensus revised, 是来自剑桥大学计算机实验室的Heidi Howard的博士论文; 文章写的很清晰, 流畅, 层层递进, 便于理解, 可能是我读过的最好理解的分布式系统论文之一了,强烈建议阅读

注意3: 其实这篇论文中的Quorum优化讨论的部分和Vertical Paxos里的Read Quorum/Write Quorum的讨论本质上几乎是一样, 所以顺便在最后介绍一下Vertical Paxos; 这两篇论文建议可以一起食用。

注意4: 本文作者只简述算法实现和点出算法为什么这样设计的关键点, 目的是为了自己半年一年后全忘记之后, 扫一眼就可以记忆回来; 所以对详细证明感兴趣的同学请下载论文原文阅读;


Paxos经典算法的问题

Paxos经典算法主要问题在于不管任何情况都最少需要两个来回的通信才能达成consensus, 而Multi-Paxos虽然在正常情况下只需要一个来回的通信就可以达成consensus, 但是需要一个稳定的leader来处理所有其他process的信息, 从而使得leader成为机群性能瓶颈; 而机群机器越多, 对leader和leader的网络压力越大, 所以系统有scalability的限制(一般3/5/7个成员); 而所有client的请求都要转发给leader而不能在机群的任意机器上处理, 这也增加了service的latency;


基础拓展

所有的拓展基于:

  1. 系统只设计proposer和Acceptor 两种角色, 没有Reader/Follower
  2. Proposer不属于Acceptor
  3. Classic Paxos的2b信息只发给Proposer, 而不是群发给所有人.

NACK信息

Acceptor收到1a或者1b消息时, 如果已经加入高轮次的epoch了, 返回NACK来告知发1a/1b的proposer; 而不是让proposer等待超时.

利用NACK加速重试: NACK附带acceptor最新加入的epoch号, 比如是f, 这样proposer可以跳过所有小于f的epoch号, 用f+1作为新epoch来重试propose; 而不必挨个试.

跳过2a,2b

如果1b, 有>N/2的acceptor返回一样的值, 可以直接返回

如何增加几率:

  • 凑够>N/2回复, 但是缺一两个一样的值来直接返回跳过2a/2b, 那么可以多等一会儿, 万一能凑够N/2 个一样的值呢.
  • 2a和等更多的1b一起进行, 一旦凑够>N/2个一样的1b, 可以提早结束2阶段(2a/2b)
  • 可以重用上一个epoch的同值1b来凑数这“>N/2个一样的1b信息”
  • NACK里包含1b的v(acceptor当前的v), 也可以用来凑数

已决定通知

Proposer凑够>N/2的2b消息后, 通知所有acceptor(这个额外的通知轮次又叫做Phrase-3), 这样任意acceptor以后再收到别的proposer发出的任意1a, 2a, 可以直接告之其值已经选好了;

由于决定的值已经至少存了>N/2份了, 所以Phrase-3通知不需要包含v(如果v很大, 可以节省带宽), 而只通知哪个epoch-x已经达成决定即可, 代表的意思是"你x轮accept的val已经作为最终consensus值被接受"

    1. 但是这样有一个问题, 有可能不是所有acceptor都有这个consensus值, 所以这些acceptor(和它们直接告知“值已选好”的其他后来的proposer只知道"值已经决定了"), 那么这时这些proposer需要一个1a/1b轮次来找到这个已经决定的值.

Distinguished Proposer

由于Paxos的latency很大程度取决于有没有多个proposer同时发1a/2a信息, 那么预定义一个知名Distinguished Proposer, 大家都把msg发给它让他单独propose, 这样就减少了冲突, 提高了稳定性; 而其他process如果怀疑这个proposer挂了(比如heartbeat timeout), 则自己可以变为proposer;

预跑1a/1b

1a, 1b不需要client消息触发, 可以预先跑, 这样msg来了只需要跑2a, 2b; (这是因为1a主要是用来保证自己占用住1a所在的epoch, 而1b用来收集之前可能已经决定了的值, 这都和自己准备propose的值无关)

Multi-Paxos

只有Leader可以充当proposer, 而1a, 1b只在换leader时跑一次(比如其他process怀疑leader挂了), epoch只在此时增加; 同时有多个Leader的话只是重现了有多个proposer的情况, 所以这里的Leader不需要consensus来选, 所以任何随机选Leader的算法都不会破坏算法的Safety; 这样proposer收到client提交的请求之后可以直接跑2a, 2b, 用相同的epoch+seqNum来区分不同的consensus instance;

所以Multi-Paxos可以在平稳状态下用一个来回的消息传递达成consensus;

更多角色

    • Reader(直接从acceptor读最后的值),
    • Recovery proposer(所有的1b没值则退出, 只用来恢复没有decision的Consensus Instance)
    • Learner: 只接受decision, 可以由proposer在2b成功结束后告知, 也可以由acceptor的>N/2个2b信息告知

多种Epoch选法

  • 把pid加入到epoch的Id里,并定义pid之间的顺序, 就可以让所有process共享epoch; (classic Paxos需要预定义epoch空间使得每个process绝对使用不同的epochid来)
  • 如果epoch定义为(sid, pid), 那么sid必须存disk, 然后才开始用, 但是这样每一次发1a信息前都要写硬盘;
  • 如果epoch定义为(sid, pid, vid), vid存disk但是只有restart之后才更改(+1), sid在内存每次发1a前+1; 这样同样可以保证epoch的不重复性和只增性;
  • 1a/1b的收发可以和写epoch id到disk同时跑,只要都在2a开始前完成即可,没写完就挂了只会用老的epochid重发1a/1b, 这就好像msg丢失重发一样, 不影响算法正确性。

重要的是, 只能有一个process在某epoch propose, 对一个epochid,acceptor只能回复1b给一个proposer; =>其实更重要的是一个epoch只能有一个v => 除非使用最后介绍的Conflict Recovery算法(允许任意process直接跳过1a/1b, 这样第一个epoch, epoch-min可能有带不同值的2a被不同的acceptor接受)

Proposal copying

任何acceptor有了2a之后, 都可以群发这个2a(保持epoch不变), 这其实相当于2b群发

    • 快速NACK recovery: 老proposer, 收到NACK之后快速传播新epoch和v
    • 快速co-locate recovery: 如果有phrase-3, 那么acceptor可以在发出2b后, 等待proposer的最终决定超时的时候, 帮忙重发2a, (restart recovery proposer using proposal copying)

只发最少数量的信息

因为只需要>N/2的信息交互, proposer可以分段发1a/2a信息, 一开始只给>N/2个process 发1a, 减少网络负载.

Virtual Sequence

一个consensus instance的"决定值"可以是多个application层的value, 而多个consensus instance的value不必在app level是严格顺序的, 总是可以被app顺序重拍. (We can improve this by deciding at each index a sequence of values instead of a single value. This batching of values into decisions reduces decision latency and need not be exposed externally as values can be re-assigned consequence (virtual) indexes.)


Quorum intersection的修订

Classic Paxos要求必须收到> N/2的1b和2b信息, 这个条件并不是必须的, 它只是更“本质”要求的一种实现而已; 这一节总结一下这个更"本质"的要求和我们怎么合理利用它来让Paxos的1b和2b收集条件更加的灵活以适用不同的场景/需求;

注意以下几个术语在本文意思一样

  • 需要的1b信息 == Phrase-I Quorum == Read Quorum
  • 需要的2b信息 == Phrase-II Quorum == Write Quorum
  • Revision-A: 只需要Phrase-I Quorum和Phrase-II Quorum有交集即可
    • Phrase-I之间有交集只是为了保证single proposer value at one epoch (利用Phrase-I Quorum有交集来保证只有一个v成为某epoch的唯一有值选择, 又叫做vote for uniqueness)
  • Revision-B: 只需要当前epoch的Phrase-I Quorum和之前的所有epoch的Phrase-II Quorum有交集即可
  • Revision-C: 如果某之前epoch-x的收集到的1b消息有值(并非全None), 那么epoch-x之前的epoch的信息都无所谓; 只需要(当前轮)的Phrase-I Quorum和(当前轮)之前但并发生在所有epoch-x之后的Phrase-II Quorum有交集即可; (epoch-x也不需要Quorum, 因为一个epoch只能有一个v)

Revision-A和B都只是C的特殊化, 所以只需要理解为什么Revision-C可以保证算法正确即可, 推理如下:

    1. 之前的某epoch-c有最终consensus决定的前提条件是: epoch-c有WQuorum都支持这个值(有WQuorum的acceptor都发回了2b信息), 所以和epoch-c的WQuorum有交集的任意RQuorum(比如当前epoch的RQuorum)必定可以读到这个值而不是None;
    2. 那么只要有从epoch-c读到RQuorum个都是None, 那么就可以判断epoch-c轮次没有决定(否则RQuorum至少读到一个非None的val)
    3. 所以才一定需要查c-1轮, 因为决定没有在c轮达成, 并不能确定c-1轮是否达成决定
    4. 但如果一旦用RQuorum读到某epoch-c有非None值x了, 那么epoch-c轮之前不可能有任何epoch已经达成了非x的“最终决定”, 这是classic paxos的基本特性,不再过多讨论;
    5. 以此类推, 所以一旦某c轮的1b有值x, 那么就不用往前查了, x可能已经被作为最终决定被接受, 或者还没有, 但是系统不可能有其他值被选择, 所以用x作为本轮的2a选择是不会出错的;

换句话说:我们的当前轮epoch-e的RQuorum只要保证, 和任意之前轮次的WQuorum有交集, 这样的话保证任意轮次一旦有"最终决定",当前轮一定可以读到, 且我们只需从当前轮往前一轮一轮的找, 只要一轮凑够RQuorum的None我们就知道此轮必定没有“最终决定”, 那么往前迭代一轮继续找, 直到在某轮找到一个v, 那么我们就可以选择这个v作为当前轮的2a决定; 如果找完了全都是None, 则肯定还没任何值达成consensus, 那么当前轮次可以propose任意值;

注意1: Revision-C 和Vertical Paxos的第一个算法Vertical Paxos-I的回找原则是几乎一摸一样的; 只不过Vertical Paxos由于允许reconfig, acceptor成员可能发生变化, 所以需要一个额外的consensus cluster来记住"上一个完成查询"的epoch值.

注意2: 我们可以看到一个重要的2选一

  • 简单固定的value查找: 所有epoch的RQuorum和WQuorum都不变,那么随意组成的RQuorum中, 选epoch最大的val即可, 或者RQuorum中所有的1b值都是None, 那么本epoch的proposer可以选任意值; (因为WQuorum不变, RQuorum和上一轮的WQuorum有交集则保证之前所有WQuorum如果可能达成决定, 则RQuorum一定可以读到)
  • 灵活的Quorum设置: 允许不同epoch拥有可变的Quorum设置 (比如Quorum成员数的改变), 此时RQuorum的查询条件会比较复杂, 要考虑之前每一个epoch的WQuorum可能都不一样, 选值逻辑需要保证选中之前有值WQuorum里epoch最大的, 只有查过之前所有的WQuorum都没值, 本epoch的proposer才可以选任意值;

All aboard paxos: 对Quorum intersection的修订的利用

  • epoch =0到k
    • Wquorum = N
    • Rquorum = 1
  • epoch = k+1
    • Rquorum = 1
    • Wquorum = (N/2)+1
  • epoch = k+1到永远
    • W/Q quorum = (N/2)+1

这样设置使得从0到k的epoch的proposer都可以跳过1a/1b阶段, 因为要求WQuorum为N, 那么failover时, 新的Leader需要找出之前可能有过的“最终决定“, 那么自己读自己就可以拿到这个值, 那么如果自己的值是None, 那么说明之前绝对没有达成过consensus, 则自己可以propose任意值;

但是这个设定的问题在于有任何机器挂了, WQuorum永远无法达成, 那么没关系, 等到连续k轮都timeout, 到达k+1轮之后, WQuorum就会改为(N/2)+1, 使得WQuorum可以更容易达到, 但是之后的轮次要进行正常的1a/1b来正确读取之前epoch的"可能决定"

对multi-Paxos的影响

  1. 我们可以减少W quorum的数量(但是2a还是要发给所有acceptor), 但是只等待发回2b最快的W quorum就可以返回了, 这样在没有failure的时候可以减少consensus的latency;
  2. 只对减少了的W Quorum发2a, 这样降低了网络压力.

这两个选择的共同影响是, 换leader时需要query更多的nodes. (由于WQuorum减小, RQuorum增大)

或者让leader只用“small fixed quorum of acceptor”作为WQuorum, 其他acceptor只是待机; 这样只要这个固定WQuorum里有一台机器没挂, 我们都可以继续consensus的运算(在之后的epoch使用(N/2)+1作为WQuorum);

或者一个固定的小WQuorum负责一段instance区间, 出现failure时才利用其他acceptor来做failover.

总而言之, 灵活的RQuorum和WQuorum让我们获得了更多的选择空间;


Value selection的修订

论文里的新Value Selection的选择比较复杂, 但是换来的只是"Proposer在某些情况下并不需要继承之前epoch的值, 而可以随意选值", 个人觉得这个复杂度交换来的好处并不是很实用, 这里就不多讨论了;


Epochs选择的修订

对于epoch选择的问题, 到目前为止有两种方法:

  • Pre allocate epoch (Distinguished Proposer在没有failure发生的情况下总是可以跳过1a/1b)
  • Vote for uniqueness (没有Distinguished Proposer, 总是需要1a/1b来决定epoch的owner)

由于epoch-min(最小的epoch值, 比如0)的proposer可以跳过1a/1b阶段, 所以怎么利用这一点是加速consensus达成的关键

  • Epoch from Allocator: 使用一个allocator process来分配epoch, 先到先得
    • allocator可以记住第一个propose的value, 然后其他人申请的时候要求其他proposer必须propose这个值; 这样所有proposer都可以跳过1a/1b; (那么allocator死了怎么办?)
    • allocator死了, 就回退到用pre-allocate的epoch(除了epoch-min之外的epoch预定义好, 比如processId顺序)或者vote for uniqueness
  • Epoch by value mapping: 由于1a/1b的关键是使得一个epoch只有一个v, 那么其实一个epoch就算有多个proposer, 如果大家propose的值一样, consensus也可以无冲突的达成; 那么我们如果用有一个value到epoch的1:1 mapping, 那么获得epochmin的v总是不需要1a/1b;
    • 但是因为选择的值会影响epoch, 所以用自己要propose的v算出的epoch 1a信息所对应的1b如果有拿回不同的值, 要用这个拿回的值重算epoch, 再次进行1a/1b;

Epoch by Recovery

由于epoch-min的proposer可以跳过1a/1b, 如果固定让一个proposer来propose值, 那么没有failure就可以一直跳过1a/1b, 这是multi-paxos的关键, 但是这样这个distinguished proposer的负载会太高; 那么如果可以让所有机群里的process想propose value都可以使用epoch-min就好了; 如果没有冲突的话, 不但负载均衡,且总是可以跳过1a/1b, 用一次通信达成consensus;

那么如果允许所有在收到client的请求时, 无论哪个process都可以一开始就使用epoch-min来propose值, 会出现什么问题呢?

    • W Quorum不重合就完蛋 => 可以顺利出现多个consensus值
      • 所以W Quorum必须有交集
    • Liveness问题 (收到>N/2个1b可能是不够的)
      • 首先如果多个process 同时用epoch-min propose了多个不一样的v, 谁都无法凑成W quorum
      • 之后epoch的proposer在1a/1b阶段会看到多个值, 而无法判断哪个值可能在之前的轮次已经作为consensus的最终决定了;

对liveness问题的详细说明: 比如5个节点, WQuorum设为3,2个节点拿到A, 2个节点拿到B, 第五个节点挂了, 就算我们的R Quorum设为4,且我们拿到了所有4个节点的值, 我们还是无法判断以下那种情况发生了:

  • 第五个节点拿到的是A, 最终consensus值为A
  • 第五个节点拿到的是B, 最终consensus值为B
  • 第五个节点拿到的是None, 并没有任何consensus值, proposer可以任意选择

可以看到W Quorum设的太小, 让Consensus太容易达成, 会在conflict发生时, 让我们没有足够的数据来判断哪个值可能被选了;

在看另外一种情况, 如果我们R Quorum拿到了2个A, 一个B, 我们无法判断到底A可能被选了(剩下2个节点至少有一个是A),还是B可能被选了(剩下2个节点都是B), 还是没有consensus值; 而如果我们再拿到一个节点的值是None, 我们就知道要么A被选了(最后的节点是A), 或者没有consensus值(最后的节点是None), 而B绝对不可能被选为consensus值, 那么我们propose A就是安全的;

而如果我们一开始就收到了2个A和1个none, 那么我们根本不需要剩下2个节点的值就可以判断propose A是安全的;

可以看出,

  • RQuorum拿到的不同值的票数差距越大, 我们就越能消除"少数票"的那个值可能被之前的consensus选中的几率; (最差的情况是2个值的票数总是55开,)
  • RQuorum拿到的值越多, 我们就有机会消除更多的可能性;

利用这个原则设计的Paxos就是“Counting quorum for epochs by recovery”

Counting quorum for epochs by recovery

这种设计根据W Quorum的不同, 需要1b消息收集到的票数的不同而有不同的R Quorum, 计算如下表

  • k=Write Quorum
  • QP = Read Quorum
  • n −k+1≤|QP|≤2n −2k+1

3ed6765a255aedfdcdf04b73a411a401.png

我们以N=7, WQuorum=4来举例:

如果epoch-min选consensus值失败了, 那么下一个epoch的proposer如果1b消息总是看到55开的票数的2个值(每个值都是3票), 那么就一定需要看完所有acceptor的票(1b)信息, 才能找到安全值; 即R Quorum是7;

而如果这个proposer连续看到4个A,或者3个A一个None, 或者两个A两个None... 等; 我们都可以知道A是安全值, 即R Quorum是4;

一个更加泛化的要求

由于利用数量来定义Quorum只是设计Quorum的一种方式, 更加一般化(泛化)的从conflict中可以recovery的要求为:

  • R quorum必须和所有之前W quorum的intersection有交集 (比如R里必须有一个acceptor-a, 它在所有之前的W quorum里, 显然后轮的proposer选它的值就行了, 因为如果之前的轮次有consensus值, 这个值一定在acceptor-a里)

而对于All aboard Paxos来说, R Quorum = 1, W Quorum = all, 如果后轮的proposer自己有任何值, 这个值就是可能被选的, 用它就行了。


Hybrid epoch allocation

Multi-path Paxos using allocator

    • allocator死了, 或者epoch-min已经被分配了, 就用pre-allocate的epoch或者vote for epoch

Multi-path Paxos using recovery

这个算法允许所有process来处理client的request并立刻propose任意值, 在没有冲突的时候, 总能跳过1a/1b, 用一轮通信达成consensus;

    • epochmin 可以被所有proposer使用, 之后的epoch可以用pre-defined, (或者vote)
    • 用对第一个epochmin 使用W quorum = 3N/4, 对其他epoch, 使用正常R Quorum=W Quorum = (N/2) +1
      • 3/4的原因,最多1/4个不一样的其他值(可以混淆下一轮proposer的决定), 那么如果本轮(epochmin)能达成决定,则本轮一定能收集到3N/4个一样的值, 那么即使最差情况挂了N/2的host, 我们也可以通过有没有v能够收集到>1/4的1b信息来判断什么值是安全可选的; (如果有在epochmin达成consensus, 那么我们在之后用RQuorum=(N/2)+1时, 一定可以收集到(1/4)+1个一样的v)
    • 速跳Phrase-II, 如果本epoch不是epochmin 的下一个epoch, 由revision C得, 如果任意1b的报告一个上轮的v(非空值), 那么可以直接跳Phrase-II; 如果本epoch是epochmin 的下一个epoch(即上轮epoch是epochmin), 则需要拿到1/4个一样的msg才可以速跳Phrase-II,(因为只有此时我们可以断定在epochmin不可能有别的值decide, 而如果一直没有收到(n/4)+1个一样的vote, 则需要等n/2 + 1个vote)

没有冲突则一步提交

不管是用allocator还是value based epoch, 还是conflict recovery的方法, 如果多个proposer提交的是一个值, 那么都可以没有冲突一个轮次的通信达成consensus


Vertical Paxos

  • Vertical Paxos利用一个额外的consensus cluster(又叫作master)来做主cluster的config Service, 这个config service只储存一些metadata; 而主cluster则利用Vertical Paxos来做数据的replication;
  • Vertical Paxos的Read/Write Quorum是由master根据系统变化来计算出来的; 比如发现某台机器挂了, 把它移出主cluster的成员列表并重算R/W Quorum; 或者增加机器进入机群...
In Vertical Paxos, the master computes the read and write b-quorums in reaction to changes in the system;
  • Vertical Paxos允许成员变化, 即WQuorum和RQuorum的灵活性, 在某种设定下(比如WQuorum=all, RQuorum=1), 可以做到用N个host容忍N-1个host挂掉的极端failure; (无法完成WQuorum没关系, 加新机器进来并reconfig WQuorum即可)
  • Primary-backup只是Vertical Paxos-II的一个例子 (WQuorum=All, RQuorum=1)
  • 而Vertical Paxos-I允许一边做数据迁移, 一边用新config接收数据.

Vertical Paxos和“Quorum intersection的修订”一节的Revision-C的本质是一样的, 只有一点不同, 由于极端情况下, Vertical Paxos的不同epoch的W Quorum可能不一样, 且旧的Config的W Quorum的所有机器可能都已经被config out了, 所以Vertical Paxos需要知道

  • 什么时候老的config里的W Quorum的机器才能被config out
  • 如果1b查到之前某epoch不可能有consensus决定(有>N/2的process的此epoch的值都为None), 就需要继续往前查; 那么回查到那个epoch为止呢?

Vertical Paxos-I和Vertical Paxos-II对于以上2个问题给出了不同的解决方案:

无论Vertical Paxos-I还是Vertical Paxos-II 都需要确定

  1. 之前都没有consensus值被选定, 或者
  2. 之前某值可能已经被选定了, 再次用这个值进行2a/2b, 并确定完成;

确定1或者2之后, 要告诉master自己所在的轮次(自己的epochid), 这样master得到"这个epoch"完成的信息后, 可以通知之后的leader; 那么你会问, 既然Master已经知道哪一轮完成了, 那么直接告诉之后的Leader来从这个完成的轮次查询有没有完成值不就好了? 并不完全可以:

因为万一2b完成后, Leader在通知Master之前就挂了怎么办; 此时我们已经在某轮完成了consensus, 但是Master记录的轮次可能没有任何consensus值(x轮之前都没有consensus值记录在master, x+10轮最终达成consensus, 但是在记录x=x+10之前leader挂了), 那么重新开始就可能重选一个不一样的值;

VP-I的选择是把这个master记录的轮次当作最后一个要查的轮次, 但是和Revision-C一样, 还是要从当前轮一直查到"master记录的轮次", 只有都没有值时, 当前轮次的leader才能随意propose任何值; (如果你查到master记录的这轮还没有任何值, 那么的确没有任何值被选中); 所以这个epoch之前的所有config或者不在新的config里的机器都可以release了;

VP-II的选择是用Master来记住哪个epoch是有效的, 且需要master激活, 没有master的activation, VP-II是无法accept新值或者在old epoch都无值的情况下propose新值的, 且没有master激活的值无效(只限于换membership config时还没complete的instance); 这样VP-II可以精准定位从哪个epoch的member来发1a/1b信息; 代价是只有master激活的Membership config才是有效的(所以未激活前这个新的config不能接受新的request)

VP-I和II 的实现 (只有需要更改Membership config时)

  1. leader由master(另外的consensus cluster)来选, 假设是b轮(本epoch=b)
  2. Master要告知leader一些信息, 这步对应Step5, (VP-I 和VP-II不同)
    1. 上个complete 轮次(epoch)的信息, 假设是x1轮, 对应5.1 (VP-I)
    2. 上个有效轮次(epoch)的信息假设是x2轮, , 对应5.2 (VP-II)
  3. leader进行1a, 1b
    1. 从b轮开始到x1轮, 查RQuorum是不是都是None, 找到任意值就停; (VP-I)
    2. 只查第x2轮的RQuorum是不是都是None (VP-II)
  4. 如果有值, 进行2a,2b
  5. 告知master
    1. b轮complete信息 (VP-I) => 这样b轮前的config就可以release了
    2. b轮需要被master activate (VP-II)
      1. master决定是否activate b轮, 如果ok, 那么下次给leader的“上个有效轮次(epoch)”就是b了
  6. 如果step4没跑(没值), 那么还没进行2a, 2b, 那么等待client, 然后进行2a, 2b; 即leader可以选任意值;

为什么VP-I允许一边做数据迁移, 一边用新config接收数据, 而VP-II不行呢?

论文原文在算法实现部分并没有详细解释, 只是在开头模糊的解释了一下:

Algorithm Vertical Paxos II... The leader communicates only with acceptors from the new configuration and the previous active configuration. However, a number of new ballots could be started, but remain forever inactive because their leaders failed, before a new configuration becomes active and starts accepting new commands...

根据上下文, VP是用在多个concurrent个consensus instance run里的单个consensus的算法(更改config的时候), 那么我推算, 在多consensus instance的环境里, 可能是VP-II的5.2 step需要所有的instance的告知master完成才算激活这个新config, 而这个过程中新的membership config是没有激活的, 所以无法用新的config来接受新的client request;

而由于VP-I的新membership config是直接生效的, 所以从之前的instance回复, 和接受新的client request, 用新的config开始新的consensus instance是可以的; 这也是VP-I可以实现一边做数据迁移, 一边用新的membership config接受新的client request的原因;

Linearizability and Vertical Paxos


如果ReadQuorum总是1, 那么leader自己就可以决定值是什么...不需要1a 1b, 直接2a 2b...em.. (代价是write quorum很高...)
One example is the way efficient local reads can be done from the primary while maintaining linearizability. The primary obtains a lease that gives it permission to reply directly to reads from its local state. A new primary cannot be chosen until the lease expires. In a similar way, a Vertical Paxos leader can use a lease to reply immediately to commands that do not change the state. A new leader cannot be chosen until the previous leader’s lease has expired.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值