Raft算法系列教程4:日志不一致的解决
网络不可能一直处于正常情况,因为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:日志不一致的解决的更多相关文章
- Raft算法系列教程1:Leader选举
1.服务器的三种角色 Raft算法中服务器主要分为三种角色:Leader.Follower.Candidate,并且三种角色相互独立,也就是服务器在同一时间内只可能扮演其中一种角色. Leader:用 ...
- Raft算法系列教程3:日志复制
1.日志复制的过程 Leader选出后,就开始接收客户端的请求.Leader把请求作为日志条目(Log entries)加入到它的日志中,然后并行的向其他服务器发起 AppendEntries RPC ...
- Raft算法系列教程2:状态机复制 (State Machine Replication)
分区容错如何保证? 在分布式系统设计中,需要遵循CAP理论,如果我们要让一个服务具有容错能力,那么最常用最直接的办法就是让一个服务的多个副本同时运行在不同的节点上.但是,当一个服务的多个副本都在运行的 ...
- 手绘raft算法
手绘raft算法 互联网技术窝 2019-04-07 12:06:05 在现实的分布式系统中,不能可能保证集群中的每一台机器都是100%可用可靠的,集群中的任何机器都可能发生宕机.网络连接等问题导致集 ...
- Fastify 系列教程一(路由和日志)
介绍 Fastify是一个高度专注于以最少开销和强大的插件架构,为开发人员提供最佳体验的Web框架. 它受到了 Hapi 和 Express 的启发,是目前最快的 Node 框架之一. Fastify ...
- Fastify 系列教程一 (路由和日志)
Fastify 系列教程: Fastify 系列教程一 (路由和日志) Fastify 系列教程二 (中间件.钩子函数和装饰器) Fastify 系列教程三 (验证.序列化和生命周期) Fastify ...
- 数据挖掘入门系列教程(二)之分类问题OneR算法
数据挖掘入门系列教程(二)之分类问题OneR算法 数据挖掘入门系列博客:https://www.cnblogs.com/xiaohuiduan/category/1661541.html 项目地址:G ...
- 数据挖掘入门系列教程(三)之scikit-learn框架基本使用(以K近邻算法为例)
数据挖掘入门系列教程(三)之scikit-learn框架基本使用(以K近邻算法为例) 简介 scikit-learn 估计器 加载数据集 进行fit训练 设置参数 预处理 流水线 结尾 数据挖掘入门系 ...
- 数据挖掘入门系列教程(四点五)之Apriori算法
目录 数据挖掘入门系列教程(四点五)之Apriori算法 频繁(项集)数据的评判标准 Apriori 算法流程 结尾 数据挖掘入门系列教程(四点五)之Apriori算法 Apriori(先验)算法关联 ...
随机推荐
- Beta冲刺随笔——Day_Five
这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 Beta 冲刺 这个作业的目标 团队进行Beta冲刺 作业正文 正文 其他参考文献 无 今日事今日毕 林涛: ...
- ④SpringCloud 实战:引入Hystrix组件,分布式系统容错
这是SpringCloud实战系列中第4篇文章,了解前面第两篇文章更有助于更好理解本文内容: ①SpringCloud 实战:引入Eureka组件,完善服务治理 ②SpringCloud 实战:引入F ...
- Robot Framework接口自动化案例分享⑦——Jenkins持续集成
一.RobotFramework插件安装 1.Jenkins首页->系统管理->插件管理->可选插件-> 2.搜索robot,点击直接安装 二.任务参数配置 1.新建任务 Je ...
- 异步任务-----django-celery
异步任务 ---- django-celery 大家的知道celery的使用,网上也有很多的教程.因为最近在使用django来完成项目,无意间发现发现有个东西叫django-celery,比cel ...
- Python类知识学习时的部分问题
Python的富比较方法__eq__和__ne__之间的关联关系分析 Python的富比较方法__le__.ge__之间的关联关系分析 Python的富比较方法__lt.__gt__之间的关联关系分析 ...
- OA公文流转系统(未完成)
基本页面比较多,所以就不贴出来了,具体的页面可以自行浏览. 点我进入OA系统浏览界面(未做响应式布局,需电脑端打开) 账号密码: 部门:bumen------bumen 办公室:bangongshi- ...
- JAVA课堂题目--递归来判断回数
package class20190923; import java.util.Scanner; public class Classtext { private static int n=0; pr ...
- sails框架结合mocha的测试环境搭建
一.环境结构 1.首先最底层是操作系统 2.其次在操作系统之上是Node.js的运行环境,和Database 3.再之上就是sail和mocha框架 二.环境搭建 1.首先需要Node.js的运行环境 ...
- javascript是面向对象的,怎么体现javascript的继承关系?
一个简单的例子: var A =function(){ } A.prototype = { v : 5, tmp : 76, echo : function(){console.log(this.tm ...
- css3实现立体魔方效果
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...