本文是对 Raft Paper 核心部分的意译,不包括原文中的如下章节:<3 Paxos 的优缺点论述>、<4 Raft 的易理解性介绍>、<9 Raft 算法的易理解性调研与性能评估>、<10 其它类似算法>、<12 致谢> 等,并且省略了多处学术论文的例行套话,力求言简意骇,突出重点。
  为求简明,本文中提到的“日志”均指“可复制日志”,“状态机”均指“可复制状态机”。
  原文链接:https://raft.github.io/raft.pdf

概要

  Raft 是一种用于管理日志的一致性算法。它的用途与 (multi-)Paxos 算法一样,运行效率与之相当,但它的结构与 Paxos 不同;这使得 Raft 比 Paxos 更容易理解,同时也为构建实际的系统打下了更好的基础。
  为增强可理解性,Raft 对共识算法的核心要素进行了拆分,例如领导者选举、日志复制及安全性保证等;为减少系统可能处于的状态总数量,Raft 强制执行一种更严苛的一致性策略。
  Raft 还包含了一种用于改变集群成员关系的新算法,它通过“联合多数”策略以保证安全性。

1. 引言

  共识算法的用途,是允许多台机器组成的集群,就像一个单点实体一样运行,其中的部分机器出现故障,不影响整个集群的可用性;它们是构建大规模、高可用的软件系统的核心要素之一。
  Paxos 算法的难以理解与实现困难,促使了 Raft 的诞生。我们的目标不止是算法的正确性,而且要更清楚地展示它为什么能工作。
  Raft 与现存的共识算法具有很多的相似性,但它有如下几个新特征:
  - 强化的领导者角色:相比其它共识算法,Raft 使用了一种强化的领导关系。例如,日志条目只能从领导者单向复制到其它机器;这简化了日志复制的逻辑,并使得 Raft 易于理解。
  - 领导者选举:Raft 使用随机计时器触发选举。这使得选举冲突的解决简单而高效,而代价仅仅是在所有共识算法都必需的心跳机制之上,增加了少许的逻辑。
  - 集群成员变更:Raft 使用了一种叫做“联合一致性”的方法来执行成员变更。在变更过程中,任何操作都必须同时得到两套成员配置(<新,新|旧> OR <新|旧,新>)中的多数成员的支持,方能生效;这使得集群在变更期间仍能对外提供正常的服务。
  本文的剩余部分,将依次介绍状态机问题(原文第 2 部分)、Raft 共识算法细节(原文第 5 至 8 部分)。

2. 状态机


  对共识算法的研究,通常无法脱离状态机的范畴。集群中的每台机器的状态机,通过执行相同的日志序列,将运算得到一致的最终状态;同时,即使其中的部分机器宕机,集群仍能正常运行。
  状态机用于解决分布式系统中的各种容错问题,通常使用日志来实现,如 Figure 1 所示。集群中的每台机器都有一份存储指令的日志,供其状态机按序执行。由于所有机器的日志都完全相同,因此状态机的执行结果是确定的,它们将运算出一致的最终状态,并得到相同的输出序列。
  共识算法的职责,就是保证所有日志的一致性。
  一台机器上的共识模块,负责接收客户端的指令,并将其追加到自己的日志中;之后,它与集群中的其它机器的共识模块通信,确保所有机器最终都得到了完全相同的日志(即使其中某些机器中途宕机);日志复制完成之后,每台机器的状态机将按序执行接收到的指令;最后将结果返回给客户端。如此,整个集群就表现为一个浑然一体的、高可用的状态机。
  实际系统中的共识算法,通常具有如下特性:
  - 除了“拜点庭将军问题”外,任何场景下都不会返回错误的结果,例如网络分区、延迟、丢包、重复、乱序等。
  - 当集群中半数以上的机器可用,且互相之间及与客户端之间通信正常时,整个集群处于完全可用状态;当故障机器恢复时,可重新加入集群。
  - 不依靠计时机制保证日志的一致性,因为错误的时钟或极端的延迟会带来问题。
  - 在大多数场景下,一旦对集群中的大多数机器的 RPC 调用成功返回,即可判定本次指令执行成功;少数的慢速机器不影响整个集群的效率。

5. Raft 共识算法



  Raft 是一种用于管理日志的算法,Figure 2 对其作了概括性的展示,Figure 3 则列出了它的核心特性,这些内容将在之后的章节中逐一介绍。
  Raft 实现一致性的方式是:首先选举出一个集群领导者,然后让它全权管理日志。领导者从客户端接收日志条目(也就是客户端请求执行的指令),之后将其复制到其他机器上,之后通知其它机器在各自的状态机中执行该日志。强化的领导者角色大大简化了日志的管理,由于日志的单向流动原则,领导者可以独自决定新的日志条目放在什么位置而不需要和其他机器协商。领导者若宕机或断网,一个新的很快就会被选举出来。
  通过使用强化的领导者角色,Raft 将共识问题分解成了三个相对独立的子问题,将分别在之后的子章节中介绍:
  - 领导者选举:第 5.2 部分。
  - 日志复制:第 5.3 部分。
  - 安全性:第 5.4 部分,另外,在 5.2 部分中提到了一个在选举时需要遵循的额外限制条件。

  在介绍完共识算法之后,本章节还会涉及到系统可用性以及时序在其中扮演的角色等话题。

  发现一篇翻译质量尚可的既存文章,后续部分请点击此处查看;待日后时间充裕,再精修本文。

Raft Paper 简译的更多相关文章

  1. 【简译】JavaScript闭包导致的闭合变量问题以及解决方法

    本文是翻译此文 预先阅读此文:闭合循环变量时被认为有害的(closing over the loop variable considered harmful) JavaScript也有同样的问题.考虑 ...

  2. 【简译】jQuery对象的奥秘:基础介绍

    本文翻译自此文章 你有没有遇到过类似$(".cta").click(function(){})这样的JavaScript代码并且在想“$('#x')是什么”?如果这些对你想天书一样 ...

  3. 【简译】Windows 线程基础

    翻译一篇关于windows线程的文章,原文在此.第一次翻译,如有错误请多指教 =========================================华丽的分割线============== ...

  4. Delphi 10.1 柏林更新内容简译

    新的 SDKTransform.exe 支持转换 Object-C 或 C++ 头文件到Delphi. 修改了对话框的接口,分成了同步和异步两种: http://blog.qdac.cc/?p=380 ...

  5. 简译《Dissecting SQL Server Execution Plans》——连载总入口

    转载请注明出处 由于工作及学习需要,最近看了一下<Dissecting SQL Server Execution Plans>,这是少有的专门描述执行计划的优秀书籍,为了快速查找并供入门同 ...

  6. Raft 为什么是更易理解的分布式一致性算法

    一致性问题可以算是分布式领域的一个圣殿级问题了,关于它的研究可以回溯到几十年前. 拜占庭将军问题 Leslie Lamport 在三十多年前发表的论文<拜占庭将军问题>(参考[1]). 拜 ...

  7. 【转】Raft 为什么是更易理解的分布式一致性算法

    编者按:这是看过的Raft算法博客中比较通俗的一篇了,讲解问题的角度比较新奇,图文并茂,值得一看.原文链接:Raft 为什么是更易理解的分布式一致性算法 一致性问题可以算是分布式领域的一个圣殿级问题了 ...

  8. Raft 为什么是更易理解的分布式一致性算法(转)

    一致性问题可以算是分布式领域的一个圣殿级问题了,关于它的研究可以回溯到几十年前. 拜占庭将军问题 Leslie Lamport 在三十多年前发表的论文<拜占庭将军问题>(参考[1]). 拜 ...

  9. Raft 为什么是更易理解的分布式一致性算法——(1)Leader在时,由Leader向Follower同步日志 (2)Leader挂掉了,选一个新Leader,Leader选举算法。

    转自:http://www.cnblogs.com/mindwind/p/5231986.html Raft 协议的易理解性描述 虽然 Raft 的论文比 Paxos 简单版论文还容易读了,但论文依然 ...

随机推荐

  1. 【洛谷p1036】选数

    (一定要声明我太蒟了,这个题扣了一上午……) 算法标签: …… dfs真的不是我所擅长的qwq,这道题的思路其实很简单,就是先dfs搜索所有可能的和,然后判断是不是质数.说着好说,然鹅并不好写: 第一 ...

  2. [fw]Understanding a Kernel Oops!

    An “Oops” is what the kernel throws at us when it finds something faulty, or an exception, in the ke ...

  3. go web编程——路由与http服务

    本文主要讲解go语言web编程中的路由与http服务基本原理. 首先,使用go语言启动一个最简单的http服务: package main import ( "log" " ...

  4. #import,#include与@class的区别

    1.#include是C中用来引用文件的关键字,而#import是obj-c中用来代替include的关键字.#import可以确保同一个文件只能被导入一次,从而避免了使用#include容易引起的重 ...

  5. 使用HystrixCommand封装http请求

    1.引入依赖 要排除hystrix-core里的archaius-core,否则报错 <dependency> <groupId>com.netflix.hystrix< ...

  6. linux单机部署kafka(filebeat+elk组合)

    filebeat+elk组合之kafka单机部署 准备: kafka下载链接地址:http://kafka.apache.org/downloads.html 在这里下载kafka_2.12-2.10 ...

  7. rabbitmq 从channal获得socket

    std::string queue_name = "hello100"; AmqpClient::Channel::ptr_t channel = AmqpClient::Chan ...

  8. sqlserver 之 将查询结果变为json字符串

    GO /****** Object: StoredProcedure [dbo].[SerializeJSON] Script Date: 6/4/2019 3:58:23 PM 将查询结果变为jso ...

  9. vue中引入了sass,又引入cssnano报错

    "cssnano": { // preset: "advanced", autoprefixer: false, "postcss-zindex&qu ...

  10. Java字符串流学习

    字符串流 定义:字符串流,以一个字符为数据源,来构造一个字符流. 作用:在Web开发中,我们经常要从服务器上获取数据,数据返回的格式通过一个字符串(XML.JSON),我们需要把这个字符串构造为一个字 ...