网络不可能一直处于正常情况,因为Leader或者某个Follower有可能会崩溃,从而导致日志不能一直保持一致。因此存在以下三种情况:

(1)Follower缺失当前Leader上存在的日志条目。
(2)Follower存在当前Leader不存在的日志条目。(比如旧的Leader仅仅将AppendEntries RPC消息发送到一部分Follower就崩溃掉,然后新当选Leader的服务器恰好是没有收到该AppendEntries RPC消息的服务器)
(3)Follower即缺失当前Leader上存在的日志条目,也存在当前Leader不存在的日志条目

图中最上方是日志的索引号(1-12),每个方块代表一条日志信息,方块内数字代表该日志所处的任期号。

图中当前Leader(图中最上方一行日志代表当前Leader日志)处于任期号为8的时刻。以此图说明以上三种情况存在的原因:

Follower a、b(Follower崩溃没有接收到Leader发送的AppendEntries RPC消息)满足以上说明的第一种情况。
Follower c在任期为6的时刻,Followerd在任期为7的时刻为Leader,但没有完全完成日志的发送便崩溃了,满足以上说明的第三种情况。
Follower e在任期为4的时刻,Followerf在任期为2、3的时刻为Leader,但没有完全完成日志的发送便崩溃了,同时在其他服务器当选Leader时刻也没有接收到新的Leader发送的AppendEntries RPC消息,满足第三种情况。

日志不一致的解决方案

Leader通过强迫Follower的日志重复自己的日志来处理不一致之处。这意味着Follower日志中的冲突日志将被Leader日志中的条目覆盖。因此Leader必须找到与Follower最开始日志发生冲突的位置,然后删除掉Follower上所有与Leader发生冲突的日志,最后将自己的日志发送给Follower以解决冲突。

Leader不会删除或覆盖自己本地的日志条目

这些步骤从之前说到的日志的一致性检查开始。

当发生日志冲突时,Follower将会拒绝由Leader发送的AppendEntries RPC消息,并返回一个响应消息告知Leader日志发生了冲突。
Leader为每一个Follower维护一个nextIndex值。该值用于确定需要发送给该Follower的下一条日志的位置索引。(该值在当前服务器成功当选Leader后会重置为本地日志的最后一条索引号+1)
当Leader了解到日志发生冲突之后,便递减nextIndex值。并重新发送AppendEntries RPC到该Follower。并不断重复这个过程,一直到Follower接受该消息。
一旦Follower接受了AppendEntries RPC消息,Leader则根据nextIndex值可以确定发生冲突的位置,从而强迫Follower的日志重复自己的日志以解决冲突问题。

情况a:如上图,服务器S1在任期为2的时刻仅将日志<index:2,term:2>发送到了服务器S2便崩溃掉。

情况b:服务器S5在任期为3的时刻当选Leader(S5的计时器率先超时,递增任期号为3,高于服务器S3和S4,因此可以当选Leader),但没来得及发送日志便崩溃掉。

情况c:服务器S1在任期为4的时刻再次当选Leader(S1重启时,任期仍然为2,收到新的LeaderS5发送的心跳信息后更新任期为3,而在LeaderS5崩溃后,服务器S1为第一个计时器超时的,因此发起投票,任期更新为4,大于网络中其他服务器任期,成功当选Leader),同时将日志<index:2,term:2>发送到了服务器S2和S3,但还没有通知服务器对日志进行提交便崩溃掉。

情况d:情况(a->d)如果在任期为2时服务器S1作为Leader崩溃掉,S5在任期为3的时刻当选Leader,由于日志<index:2,term:2>还没有被复制到大部分服务器上,并没有被提交,所以S5可以通过自己的日志<index:2,term:3>覆盖掉日志<index:2,term:2>。

情况e:情况(a->e)如果在任期为2时服务器S1作为Leader,并将<index:2,term:2>发送到S2和S3,成功复制到大多数成员服务器上。并且成功提交了该日志,那么即便S1崩溃掉,S5也无法成功当选Leader,因为S5不具备网络中最新的已被提交的日志条目。

Raft算法系列教程4:日志不一致的解决的更多相关文章

  1. Raft算法系列教程1:Leader选举

    1.服务器的三种角色 Raft算法中服务器主要分为三种角色:Leader.Follower.Candidate,并且三种角色相互独立,也就是服务器在同一时间内只可能扮演其中一种角色. Leader:用 ...

  2. Raft算法系列教程3:日志复制

    1.日志复制的过程 Leader选出后,就开始接收客户端的请求.Leader把请求作为日志条目(Log entries)加入到它的日志中,然后并行的向其他服务器发起 AppendEntries RPC ...

  3. Raft算法系列教程2:状态机复制 (State Machine Replication)

    分区容错如何保证? 在分布式系统设计中,需要遵循CAP理论,如果我们要让一个服务具有容错能力,那么最常用最直接的办法就是让一个服务的多个副本同时运行在不同的节点上.但是,当一个服务的多个副本都在运行的 ...

  4. 手绘raft算法

    手绘raft算法 互联网技术窝 2019-04-07 12:06:05 在现实的分布式系统中,不能可能保证集群中的每一台机器都是100%可用可靠的,集群中的任何机器都可能发生宕机.网络连接等问题导致集 ...

  5. Fastify 系列教程一(路由和日志)

    介绍 Fastify是一个高度专注于以最少开销和强大的插件架构,为开发人员提供最佳体验的Web框架. 它受到了 Hapi 和 Express 的启发,是目前最快的 Node 框架之一. Fastify ...

  6. Fastify 系列教程一 (路由和日志)

    Fastify 系列教程: Fastify 系列教程一 (路由和日志) Fastify 系列教程二 (中间件.钩子函数和装饰器) Fastify 系列教程三 (验证.序列化和生命周期) Fastify ...

  7. 数据挖掘入门系列教程(二)之分类问题OneR算法

    数据挖掘入门系列教程(二)之分类问题OneR算法 数据挖掘入门系列博客:https://www.cnblogs.com/xiaohuiduan/category/1661541.html 项目地址:G ...

  8. 数据挖掘入门系列教程(三)之scikit-learn框架基本使用(以K近邻算法为例)

    数据挖掘入门系列教程(三)之scikit-learn框架基本使用(以K近邻算法为例) 简介 scikit-learn 估计器 加载数据集 进行fit训练 设置参数 预处理 流水线 结尾 数据挖掘入门系 ...

  9. 数据挖掘入门系列教程(四点五)之Apriori算法

    目录 数据挖掘入门系列教程(四点五)之Apriori算法 频繁(项集)数据的评判标准 Apriori 算法流程 结尾 数据挖掘入门系列教程(四点五)之Apriori算法 Apriori(先验)算法关联 ...

随机推荐

  1. CPU实现原子操作的原理

    586之前的CPU, 会通过LOCK锁总线的形式来实现原子操作. 686开始则提供了存储一致性(Cache coherence),  这是多处理的基础, 也是原子操作的基础. 1. 存储的粒度 存储的 ...

  2. Hadoop完全分布式模式安装部署

    在Linux上搭建Hadoop系列:1.Hadoop环境搭建流程图2.搭建Hadoop单机模式3.搭建Hadoop伪分布式模式4.搭建Hadoop完全分布式模式 注:此教程皆是以范例讲述的,当然你可以 ...

  3. day7(vue发送短信)

    1.vue发送短信逻辑 前端函数如下,js方法代码无需更改,前端代码逻辑在components\common\lab_header.vue 只需要修改components\axios_api\http ...

  4. 洛谷P3901 数列找不同(莫队水题)

    重温下手感,判断区间是否全是不同的数字有两种做法,一个长度为len的区间不同的数字,参见HH的项链,一种是区间众数,参见蒲公英,是水题没错了.明天搞数据库,然后继续自己的gre和训练计划 #inclu ...

  5. 区块链学习5:智能合约Smart contract原理及发展历程科普知识

    ☞ ░ 前往老猿Python博文目录 ░ 一.智能合约的定义 通俗来说,智能合约就是一种在计算机系统上,当一定条件满足的情况下可被自动执行的合约,智能合约体现为一段代码及其运行环境.例如银行信用卡的自 ...

  6. moviepy音视频剪辑:headblur函数遇到的TypeError: integer argument expected, got float错误的解决方案

    运行环境如下: python版本:3.7 opencv-python版本:4.2.0.34 numpy版本:1.19.0 错误信息: 在调用moviepy1.03版本的headblur函数执行人脸跟踪 ...

  7. PyQt(Python+Qt)学习随笔:信号签名(signature of the signal)是什么?

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 1.概念解释 函数签名:由函数的参数个数与其类型组成.函数在重载时,利用函数签名的不同即参数个数与类 ...

  8. 安装pyspider出现的问题

    本文来自微信公众号:coder_xiaobu,欢迎关注 一.安装pyspider pip install pyspider 二.启动 pyspider all 三.安装中出现的问题处理 安装的时候出现 ...

  9. Error.name 六种值对应的信息

    1 EvalErroe:eval()  的使用与定义不一致 2 RangrError: 数值越界 3 ReferenceError:非法或不能识别的引用数值 4 SyntaxError:发生语法解析错 ...

  10. js内存泄漏的问题?

    内存泄漏指任何对象在您不再拥有或需要它之后仍然存在. 垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量.如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环 ...