Raft算法系列教程3:日志复制
1、日志复制的过程
Leader选出后,就开始接收客户端的请求。Leader把请求作为日志条目(Log entries)加入到它的日志中,然后并行的向其他服务器发起 AppendEntries RPC 复制日志条目。当这条日志被复制到大多数服务器上,Leader将这条日志应用到它的状态机并向客户端返回执行结果。
客户端的每一个请求都包含被复制状态机执行的指令。Leader把这个指令作为一条新的日志条目添加到日志中,然后并行发起 RPC 给其他的服务器,让它们复制这条信息。假如这条日志被安全的复制,Leader就应用这条日志到自己的状态机中,并返回给客户端。如果Follower宕机或者运行缓慢或者丢包,Leader会不断的重试,直到所有的Follower最终都复制了所有的日志条目。

2、日志的组成
日志由有序编号(log index)的日志条目组成。每个日志条目包含它被创建时的任期号(term)和用于状态机执行的命令。如果一个日志条目被复制到大多数服务器上,就被认为可以提交(commit)了。

上图显示,共有 8 条日志,提交了 7 条。提交的日志都将通过状态机持久化到磁盘中,防止宕机。
3、日志复制的详细介绍
当Leader接收到由客户端发送的请求(请求中包含可以被复制状态机执行的命令)时,Leader将会把该请求作为新的内容添加到日志中(任期号为当前Leader所处的任期号,索引号为当前Leader本地存储的日志集合中的日志的最高索引号加1)。
备注:Leader在当前任期内最多只能创建一个给定索引号的日志(即不可能在一个任期内创建两个以上的具有相同索引的日志条目)
然后将该日志通过AppendEntries RPC消息发送到网络中其他的服务器(以下简称Follower),从而复制该日志。
在网络中Follower接收到该日志消息后则会返回复制成功的回复。
在Leader接收到网络中大部分的Follower的成功复制的回复之后,Leader便认为该日志可以被提交。此时Leader将会同时做三件事:
(1)将该日志应用到Leader本地的复制状态机
(2)向所有Follower发送消息通知所有接收到该日志的Follower将该日志进行提交,然后应用到各自本地的复制状态机
(3)将执行结果通知客户端
当该日志消息成功在网络中大部分Follower本地的复制状态机执行过后,则可认为该日志已被提交。在当前日志被提交的过程中,如果Leader先前的某些日志还没有被提交,则将会一同提交。
而网络中有些Follower可能由于网络状态原因反应缓慢或者崩溃,那么Leader将会无限次地尝试重复发送AppendEntries RPC消息到该Follower。直到成功为止。
4、日志的一致性检查
如上所述,Follower在接收到AppendEntries RPC消息后则会返回复制成功的回复。实际上在接收到消息后会首先进行日志的一致性检查(正常情况下Leader与Follower的日志会保持一致,所以一致性检查不会失败),一致性检查内容如下:
在Leader创建AppendEntries RPC消息时,消息中将会包含当前日志之前日志条目的任期号与索引号。
Follower在接受到AppendEntries RPC消息后,将会检查之前日志的任期号与索引号是否匹配到。如果匹配到则说明和Leader之前的日志是保持一致的,否则,如果没有匹配则会拒绝AppendEntries RPC消息。
一致性检查是一个归纳的过程。正常情况下,网络中第一条日志一定满足日志的一致性检查,然后第二条日志中包含第一条日志的任期号与索引号,所以只要Leader与Follower的第一条日志保持一致,那么第二条日志也会满足一致性检查,从而之后的每一条日志都会满足一致性检查。
从而得出了日志匹配属性:
(1)如果两个不同的日志实体具有相同的索引和任期号,那么它们存储有相同的命令。
(2)如果两个不同的日志实体具有相同的索引和任期号,则所有先前条目中的日志都相同。(由一致性检查结果得出)
Raft算法系列教程3:日志复制的更多相关文章
- Raft算法系列教程1:Leader选举
1.服务器的三种角色 Raft算法中服务器主要分为三种角色:Leader.Follower.Candidate,并且三种角色相互独立,也就是服务器在同一时间内只可能扮演其中一种角色. Leader:用 ...
- Raft算法系列教程2:状态机复制 (State Machine Replication)
分区容错如何保证? 在分布式系统设计中,需要遵循CAP理论,如果我们要让一个服务具有容错能力,那么最常用最直接的办法就是让一个服务的多个副本同时运行在不同的节点上.但是,当一个服务的多个副本都在运行的 ...
- Raft算法系列教程4:日志不一致的解决
网络不可能一直处于正常情况,因为Leader或者某个Follower有可能会崩溃,从而导致日志不能一直保持一致.因此存在以下三种情况: (1)Follower缺失当前Leader上存在的日志条目.(2 ...
- 解读Raft(二 选举和日志复制)
Leader election Raft采用心跳机制来触发Leader选举.Leader周期性的发送心跳(如果有正常的RPC的请求情况下可以不发心跳)包保持自己Leader的角色(避免集群中其他节点认 ...
- 分布式一致性算法:Raft 算法(论文翻译)
Raft 算法是可以用来替代 Paxos 算法的分布式一致性算法,而且 raft 算法比 Paxos 算法更易懂且更容易实现.本文对 raft 论文进行翻译,希望能有助于读者更方便地理解 raft 的 ...
- 【转】分布式一致性算法:Raft 算法(Raft 论文翻译)
编者按:这篇文章来自简书的一个位博主Jeffbond,读了好几遍,翻译的质量比较高,原文链接:分布式一致性算法:Raft 算法(Raft 论文翻译),版权一切归原译者. 同时,第6部分的集群成员变更读 ...
- Paxos 实现日志复制同步
Paxos 实现日志复制同步 本篇文章以 John Ousterhout(斯坦福大学教授) 和 Diego Ongaro(斯坦福大学获得博士学位,Raft算法发明人) 在 Youtube 上的讲解视频 ...
- Paxos 实现日志复制同步(Basic Paxos)
Paxos 实现日志复制同步 本篇文章以 John Ousterhout(斯坦福大学教授) 和 Diego Ongaro(斯坦福大学获得博士学位,Raft算法发明人) 在 Youtube 上的讲解视频 ...
- Raft 实现日志复制同步
Raft 实现日志复制同步 本篇文章以 John Ousterhout(斯坦福大学教授) 和 Diego Ongaro(斯坦福大学获得博士学位,Raft算法发明人) 在 Youtube 上的讲解视频及 ...
随机推荐
- Visual Studio 连接 SQL Server 关键代码
首先先把Visual Studio 上面工具打开-->连接数据库-->选择Microsoft SQL Server进入(有两种验证方式:1.windows验证方式[就是本机验证]:2.SQ ...
- Spring Cloud 学习 (四) Hystrix & Hystrix Dashboard & Turbine
在复杂的分布式系统中,可能有几十个服务相互依赖,这些服务由于某些原因,例如机房的不可靠性.网络服务商的不可靠性等,导致某个服务不可用 . 如果系统不隔离该不可用的服务,可能会导致整个系统不可用.Hys ...
- 20200322_【转载】关于C#中使用SQLite自适应Any CPU程序的说明
本文转载, 原文链接: http://luyutao.com/2016/09/14/csharp-sqlite-any-cpu.html 在C#中如果要使程序自适应32位和64位系统,只需要将项目的& ...
- 第7.8节 Python中隐秘的类封装方法
前面章节已经介绍了Python中的多态和继承,本节将介绍面向对象程序设计OOP三大特征的另一个特征--封装. 一. 概念 封装是将对象的状态信息(也就是数据.属性)隐藏在对象内部,将对象的属性和 ...
- 第三十五章、PyQt输入部件:QFontComboBox、QLineEdit、QTextEdit、QPlainText功能详解
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 输入部件量比较多,且功能很丰富,但除了用于编写编辑器.浏览器 ...
- Python正则表达式re.match(r"(..)+", "a1b2c3")匹配结果为什么是”c3”?
在才开始学习正则表达式处理时,老猿对正则表达式:re.match(r"(-)+", "a1b2c3") 返回的匹配结果为"c3"没有理解,学 ...
- LeetCode初级算法之数组:66 加一
加一 题目地址:https://leetcode-cn.com/problems/plus-one/ 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一.最高位数字存放在数组的首位, 数 ...
- v-clickoutsides
//点击目标元素外侧触发特定事件 使用 v-clickoutsides="clickHandler" import Vue from 'vue' Vue.directive('cl ...
- 一篇文章掌握Nginx核心文件结构
1 Nginx核心配置结构 2 配置模块详解 设置worker进程的用户,指的linux中的用户,会涉及到nginx操作目录或文件的一些权限,默认为nobody user root; worker进程 ...
- Vue-组件化,父组件传子组件常见传值方式
前言 我们都知道vue核心之一:组件化,vue中万物皆组件,组件化我认为应该来至于模块化的设计思想,比如在模块化开发中,一个模块就是一个实现特定功能的独立的文件,有了模块我们就更方便去阅读代码,更方便 ...