分布式协议与算法实战
韩健
腾讯资深工程师
23193 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 31 讲
分布式协议与算法实战
15
15
1.0x
00:00/00:00
登录|注册

08 | Raft算法(二):如何复制日志?

思考
实现日志一致
复制日志
日志
Raft算法

该思维导图由 AI 生成,仅供参考

你好,我是韩健。
通过上一讲的学习,你应该知道 Raft 除了能实现一系列值的共识之外,还能实现各节点日志的一致,不过你也许会有这样的疑惑:“什么是日志呢?它和我的业务数据有什么关系呢?”
想象一下,一个木筏(Raft)是由多根整齐一致的原木(Log)组成的,而原木又是由木质材料组成,所以你可以认为日志是由多条日志项(Log entry)组成的,如果把日志比喻成原木,那么日志项就是木质材料。
在 Raft 算法中,副本数据是以日志的形式存在的,领导者接收到来自客户端写请求后,处理写请求的过程就是一个复制和应用(Apply)日志项到状态机的过程。
那 Raft 是如何复制日志的呢?又如何实现日志的一致的呢?这些内容是 Raft 中非常核心的内容,也是我今天讲解的重点,我希望你不懂就问,多在留言区提出你的想法。首先,咱们先来理解日志,这是你掌握如何复制日志、实现日志一致的基础。

如何理解日志?

刚刚我提到,副本数据是以日志的形式存在的,日志是由日志项组成,日志项究竟是什么样子呢?
其实,日志项是一种数据格式,它主要包含用户指定的数据,也就是指令(Command),还包含一些附加信息,比如索引值(Log index)、任期编号(Term)。那你该怎么理解这些信息呢?
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Raft算法是一种用于实现分布式系统中一致性的算法。本文深入讲解了Raft算法中的日志复制和一致性实现。文章首先介绍了日志的概念和组成,然后详细解释了Raft算法中如何复制日志,包括领导者发送日志复制RPC消息、应用日志项到状态机等过程。接着,文章阐述了在实际环境中可能遇到的日志不一致问题,以及Raft算法是如何处理不一致日志,实现日志的一致性的。最后,文章通过具体的步骤演示了领导者通过日志复制RPC一致性检查,找到跟随者节点上与自己相同日志项的最大索引值,然后复制并更新覆盖该索引值之后的日志项,实现了各节点日志的一致。整体而言,本文详细解释了Raft算法中日志复制和一致性实现的具体过程,对于想深入了解分布式系统一致性算法的读者具有很高的参考价值。文章内容涵盖了Raft算法中日志的重要概念和实现细节,为读者提供了深入了解分布式系统一致性算法的重要参考资料。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《分布式协议与算法实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(91)

  • 最新
  • 精选
  • 花家舍
    置顶
    http://thesecretlivesofdata.com/raft/ 动画演示 比文章牛逼多了

    编辑回复: 这个资源好,推荐

    2020-03-13
    8
    79
  • Mars
    老师,我有个问题,在那个复制日志的五个过程里,如果第四步执行返回结果成功了,leader突然挂了,此时leader 的状态机已经更新,follower状态机没有更新,此时新选举出来的leader怎么处理这个流程来保证上一个leader的状态机更新apply到其他节点上了呢?

    作者回复: 加一颗星:),领导者选举能保证新领导者一定包含这条committed的日志项,但这条日志项在新领导者上处于未提交状态,这时新领导者,会尝试从最新日志项开始,向其他节点复制日志,如果,某条uncommitted的日志项,被发现已经成功复制到大多数节点上,这时这条日志项将处于提交状态,并被应用到状态机,通知其他节点提交这条日志。

    2020-03-11
    24
    54
  • Scott
    我有一个问题,考虑下面这种情况,假设集群有1 leader 多 follower 1. leader发出一条set x = 1,index为最新的appendEntries到所有的follower 2. 只有一台follower响应了,所以leader对client返回fail 3. 这时leader挂了,剩余机器重新进行选举,因为前面那台follower有最新的uncommited的日志,所以它会被选举为leader 这时就会有一个不一致,外部client认为set x = 1没有成功,但是实际上x = 1是成功的,这种情况合法吗?

    作者回复: 加一颗星:),合法的,如果操作具有冥等性,比如“set x = 1”,就没关系,不影响结果,而且最后日志会去重压缩处理的,如果操作不具有冥等性,需要实现客户端协议,确保只提交一次。关于客户端协议,我后面会做补充。

    2020-03-01
    33
    36
  • 葉月喵
    上一章跟随者投票时会比较日志索引号大小,用的是已提交的日志,还是已经复制的日志?

    作者回复: 复制的,uncommited的。

    2020-02-28
    2
    26
  • 阿kai(aeo
    感觉处理日志一致性问题的时候非常不efficient,如果follower落后得多了,那么来回的RPC大部分都是failure,很耗时间和带宽。follower是否可以直接返回它拥有的最新index,然后leader根据那个index开始看是否match自己的日志,如果match就直接一次性把剩余日志都给follower发过去。这样会有效率一些吧?

    作者回复: 加一颗星:),这是个工程实现层面的优化方式:)

    2020-03-16
    5
    15
  • piboye
    为什么跟随者不直接告诉领导者我从哪里缺日志,而让领导者一个一个去尝试?

    作者回复: 加一颗星:),因为存在跟随者日志和领导者日志不一致的情况,这时领导者就不能只同步跟随者缺失的日志项,而是要先做日志一致性检查,如果日志项不一致,领导者要同步并覆盖掉跟随者节点上已存在但不一致的日志项。

    2020-09-17
    2
    10
  • Geek_d40030
    老师您好,在日志更新的时候为什么有索引值了,还要判断任期呢?理论上索引值是单调递增的就能够判断跟随者的日志在什么位置吧。

    作者回复: 加一颗星:),这是因为日志项可能来自不同的领导者,比如,节点A、B的索引值4对应的日志项,它的任期编号分别为1和2,那么,这两个日志项,就是2个不同的领导者创建的,即它们是不同的日志项。

    2020-07-02
    9
  • DZ
    老师,请教下如果在指定时间内没有收到大部分follower复制成功响应,只收到少数,那么领导者如何处理这次提交?是直接不做任何处理,由心跳或者下次提交重新对齐日志?还是有重试或者rollback机制?

    作者回复: 加一颗星:),此时日志项仍处于未提交状态,领导者需要继续重试,按顺序复制日志项,只有当日志项被成功复制到大多数节点时,该日志项处于提交状态,然后被应用到状态机。

    2020-03-19
    5
    9
  • bc
    客户端并不知道谁是leader,怎么保证客户端的请求一定是由lead来处理的?

    作者回复: 加一颗星:)。一般有2种实现方式:1. 接收到写请求的跟随者充当“代理”,转发写请求给领导者;2. 跟随者返回领导者信息给客户端,客户端再发起请求,直接联系领导者。在19、20讲,有更具体的分析。

    2020-03-11
    2
    8
  • Jialin
    1.Raft 日志格式: • 指令:一条由客户端请求指定的、状态机需要执行的指令。即客户端提交的数据 • 索引值:日志项对应的整数索引值,用来标识日志项的,是一个连续的、单调递增的整数号码 • 任期编号:创建这条日志项的领导者的任期编号 2.理想的日志复制阶段: • 接收到客户端请求后,领导者基于客户端请求中的指令,创建一个新日志项,并附加到本地日志中 • 领导者通过日志复制 RPC,将新的日志项复制到其他的服务器 • 当领导者将日志项,成功复制到大多数的服务器上的时候,领导者会将这条日志项提交到它的状态机中 • 领导者将执行的结果返回给客户端 • 当跟随者接收到心跳信息,或者新的日志复制 RPC 消息后,如果跟随者发现领导者已经提交了某条日志项,而它还没提交,那么跟随者就将这条日志项提交到本地的状态机中 3.实际生产环境中,复制日志的时候遇到进程崩溃、服务器宕机等问题,这些问题会导致日志不一致。Raft 算法按照“Raft 是通过以领导者的日志为准,来实现各节点日志的一致的”原则处理不一致日志,实现日志的一致,具体如下: • 领导者通过日志复制 RPC 的一致性检查,找到跟随者节点上与自己相同日志项的最大索引值。也就是说,这个索引值之前的日志,领导者和跟随者是一致的,之后的日志是不一致的了。 • 领导者强制跟随者更新覆盖的不一致日志项,实现日志的一致 课后思考题:领导者接收到大多数的“复制成功”响应后,就会将日志提交到它自己的状态机,然后返回“成功”响应客户端。如果此时有个节点不在“大多数”中,也就是说它接收日志项失败,那么在这种情况下,Raft 会通过日志复制 RPC 的一致性检查,找到失败者节点上,与自己相同日志项的最大索引值,然后领导者强制该失败者更新覆盖的不一致日志项,实现日志的一致

    作者回复: 加一颗星:)

    2020-02-28
    7
收起评论
显示
设置
留言
91
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部