Part 06:Raft论文翻译-《CONSENSUS BRIDGING THEORY AND PRACTICE》(基础Raft-Log副本机制)

Part 06:Raft论文翻译-《CONSENSUS BRIDGING THEORY AND PRACTICE》(基础Raft-Log副本机制)

3.5 Log Replication(日志副本)

一旦选出了一个Leader,它就开始为客户的请求提供服务。每个客户端请求都包含一个要由已复制的状态机执行的命令。引导将命令作为新的log entry附加到日志中,然后与其他服务器并行发布AppendEntries rpc消息/请求以复制该log entry。当log entry被安全复制后(如下所述,也就是大多数的Follower已经复制了这个log entry,这是这个log entry已经处于commited的状态了),Leader就在本地的状态机上apply这个log entry然后回复客户端执行结果。如果Follower崩溃或运行缓慢,或者网络数据包丢失,Leader将重新尝试AppendEntries RPC(即使在它响应了客户端之后),直到所有Follower最终存储所有log entry。(这里有几个问题,如果Leader apply这个log entry失败怎么办?它怎么回复客户端?然后就是这个apply失败的log entry怎么处理?) (理论上,已经commit的log entry最终一定会被apply,但是Leader是等确认apply成功后返回?还是apply失败一次后就回复客户端?如果是等待apply成功的再回复的话,是不是响应时间过长?如果失败就回复失败,那么这个已经commit的log entry就需要撤销,但是Leadr应该不会删除自己的log entry的,没记错的话,而且这相当于回滚,会增加算法复杂度。个人估计还是第一种策略可能性大,看看后面的文章内容有没有这块的描述)

image.png

Log的组织方式如图3.5所示。当Leader收到一个客户端的command时,Leader将在相应的log entry里存储这个command和对应的term。log entry中的term用于检测log之间的不一致,并确保图3.2中的一些属性。每个log entry也有一个整数索引index,标识其在日志中的位置。

Leader判断何时在状态机apply这个log entry是安全的(这里安全的意思就是这个log entry已经被commit,而某个log entry是否被commit的是通过其被复制的状态来决定的,即如果集群中超过半数的服务器在相应的位置复制了这个log entry,那么这个log entry就处于了“已提交状态”(commited),这时候,Leader在其状态机上apply这个log entry就是安全的)。Raft保证已提交的log entry是持久化存储的,一旦某个log entry被commit了,那么在这个log entry之前的所有log entry都将处于commited状态,包括前任Leader创建的log entry。第3.6节讨论了在Leader变更后应用此规则时的一些微妙之处,它也表明了该承诺的定义是安全的。Leader将跟踪它知道要commit的最高的log entry的index,并在未来的AppendEntries RPC(包括心跳)中包括该index,以便其他服务器最终发现。一旦Follower得知某个log entry已经被commit,Follower将该log entry apply于其本地状态机(按日志顺序)。(这里一个Follower如何指导现在那个log entry被commit了?Leader知道哪个log entry需要commit,所以也知道哪些log entry已经被commit了,如前面说的,Leader在AppendEntries RPC中会携带需要Follower复制的log entry的index,这个RPC过程中,Leader会和Follower沟通以确定Follower中合法的已经commit的最新的log entry的index。这就保证了Follower确定自己已经commit的log entry,那么这个log entry以及之前的log entry都可以被apply至Follower的状态机了。但是Follower怎么知道从那个log entry的index开始apply呢?前面说到的,每个服务器会保存本地信息有一个lastApplied变量,这个变量就存储了这个服务器已经apply的最新的log entry的index,这样起始位置都确定了,Follower可以将起始及之间的log entry apply到自己的状态机了。)

我们设计了Raft的日志机制来保持不同服务器上的日志之间的高度一致性。这不仅简化了系统的行为,使其更可预测,而且它是确保安全的一个重要组成部分。Raft维护了以下属性,它们共同构成了图3.2中的日志匹配属性:

image.png

(1)如果两个服务器上的两个log entry具有相同的term和log entry index,那么这两个log entry里面存储的command是一样的;

(2)如果两个服务器上的两个log entry具有相同的term和log entry index,那么这两个log entry之前的所有log entry一定是一样的。

第一个属性,因为在某个term内Leader每次只会产生一个log entry,而且log entry不会在log中改变位置。

第二个属性,由AppendEntries RPC的沟通机制来保证。

当发送AppendEntries RPC时,Leader将在RPC消息中携带需要同步的log entry(也可能是一组,为了提升性能)以及这个(或这些)log entry前面那个log entry的index,如果Follower在自己的log中没有找到这个index,那么就说明Follower的最新的日志还在这个index之前,并且Follower会拒绝这个RPC请求指导这个index比较成果,Follower回复同意请求。Raft算法中初始状态的log全部为空,以及后面每次AppendEntries RPC的匹配检测保证了日志一致性。也就是说只要AppendEntries RPC收到成功的回复,那么Leader就知道这个Follower在这个index之前的log entry是与自己的是一样的(包括这个index所在的log entry)。

在正常操作过程中,Leader和Follower的日志保持一致,因此AppendEntries RPC我一致性检查永远不会失败。但是,Leader崩溃可能会导致日志不一致(旧的Leader可能没有完全复制其日志中的所有log entry)。这些不一致可能会在一系列的Leader和Follower的碰撞中发生叠加。图3.6说明了Follower日志与新Leader日志的不同方式。Follower可能缺少Leader存在的log entry,它可能拥有Leader上没有的log entry,或者两者都有可能。日志中缺少和无关的条目可能跨越多个term。

image.png

在Raft中,Leader通过强迫Follower复制自己的日志来处理不一致。这意味着Follower日志中的冲突log entry将被Leader日志中的相应的log entry所覆盖。第3.6节将表明,如果再加上限制选举,这一点是安全的。(这里选举的一些限制就限制了新Leader日志的合法性,保证了算法的安全性,后面内容会叙述这些限制。)

要使Follower的日志与自己的日志保持一致,Leader必须找到两个日志一致的最新的那个log entry的index,删除Follower日志中这个index之后的所有其它log entry,并在此之后将此index之后的所有log entry同步给给Follower。所有这些操作都是为了满足AppendEntries RPC执行的一致性检查。Leader为每个Follower维护一个nextIndex,这个nextIndex就是Leader将要在下一次AppendEntries RPC中发送给Follower的log entry的index。当某个Leader刚刚胜选成为新Leader时,Leader将每个Follower的nextIndex设置成为自己的最新的log entry后面那个log entry的index(在图3.6中,这个nextIndex=11)。然后,Leader通过AppendEntries RPC与其它的Follower来同步这个nextIndex并更新自己的nextIndex的值。然后Leader和Follower之间就通过AppendEntries RPC同步log entry并在以后就按照这个方案继续同步(这里就不在赘述AppendEntries RPC的逻辑过程了,前面已经讲过了)。

在Leader发现它和Follower的日志匹配的位置之前,Leader可以发送没有log entry的AppendEntries RPC(如心跳)来节省带宽。然后,一旦发现matchIndex在nextIndex之前,Leader应该开始发送log entry。

    如果需要,可以优化协议,以减少被拒绝的AppendEntries RPC的次数。例如,当拒绝AppendEntries RPC请求时,Follower可以在回复中携带这个冲突的log entry的term。有了这些信息,Leader可以减少AppendEntries RPC请求,以绕过该term中的所有冲突log entry;每个有冲突的log entry的term将需要一个AppendEntries RPC,而不是每个log entry需要一个AppendEntries RPC。或者,Leader可以使用二进制搜索方法来查找Follower日志不同的第一个log entry;这有更好的最坏情况行为。在实践中,我们怀疑这些优化是否必要,因为失败很少发生,也不太可能有许多不一致的log entry。**(这是对log日志匹配的一种性能优化手段)**

    使用这种机制,Leader在通电时不需要采取任何特殊操作来恢复日志一致性。它刚刚开始正常操作,日志会随着AppendEntries RPC的一致性检查的失败而自动收敛。Leader永远不会覆盖或删除自己日志中的log entry(图3.2中的Leader具有“仅追加”log entry的属性)。

    此日志复制机制显示了第2.1节中描述的理想一致属性:只要大多数服务器启动,Raft就可以accept、replicate和apply新log entry;在正常情况下,新log entry可以通过单轮AppendEntries RPC复制到大多数集群;一个慢的Follower不会影响性能。日志复制算法也很实用,因为AppendEntries RPC请求的大小是可管理的(Leader从来不需要在一个AppendEntries RPC请求中发送多个log entry)。其他一些共识算法被描述为通过网络发送整个日志;这给实现者带来了开发实际实现所需的优化的负担。

<< 上一章:Raft算法-Leader选举
下一章:Raft算法-安全性 >>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容