1. 复制状态机

一致性算法是在复制状态机的背景下产生的。在这种方法下,一组服务器的状态机计算相同状态的相同副本,即使某些服务器宕机,也可以继续运行。

复制状态机通常使用复制日志实现,每个服务器存储一个包含一系列命令的日志,每个日志中命令相同并且顺序也相同。因此每个状态机可以处理相同的命令序列,得到相同的状态和输出序列。

一致性算法的工作就是保证复制日志的一致性。每台服务器上的一致性模块接收来自客户端的命令,并将他们添加到日志中。一致性模块互相通信,以确保每个日志最终以相同的顺序包含相同的命令。

2. Paxos的问题

  1. 非常难以理解,描述晦涩难懂,很少有人能够成功地理解
  2. 没有为实现提供良好的基础。缺少对mutil-Paxos的细节描述。因此实际的系统可能和Paxos的区别很大。

3. Raft一致性算法

Raft首先选举一个Distinguished leader,然后由它全权负责管理复制日志来实现一致性。

Leader从客户端接收日志条目,把日志条目复制到其他服务器上,并在保证安全性的时候通知其他服务器执行日志。拥有一个leader极大地简化了对复制日志的管理,但leader可能宕机,也可能和其他服务器断开连接,这时需要选举一个新的Leader。

基于以上设定,Raft将一致性问题分解为三个相对独立的子问题:

  1. Leader选举:当一个Leader停止工作,一个新的Leader必须被选举出来
  2. 日志复制:Leader必须从客户端接收日志条目然后复制到集群的其他节点,并且必须保持一致。
  3. 安全性:如果有任何的服务器节点已经应用了一个特定的日志条目到它的状态机中,那么其他服务器节点不能在同一个日志索引位置应用一条不同的指令。

4. Raft基础

一个Raft集群包含若干个服务器节点,通常为5个,因此可以容忍两个节点的失效。

在任意时刻,每个节点都处于三个状态之一:leader, follower, candidate

在正常情况下,集群中只有一个leader,剩下的服务器均为followerfollower都是被动的,不会发送任何请求,只是简单的响应来自leadercandidate的请求。leader处理所有的客户端请求(给follower的请求会被重定向到leadere

如图为节点间状态的相互转换。Raft将时间分割成任意长度的任期,每个任期从一次选举开始,一个或多个candidate尝试成为leader。如果一个candidate赢得选举,它将在该任期剩下的时间充当leader,在某些情况下,一次选举无法选出leader,这一任期将会没有leader。Raft保证在任意一个任期内,最多只有一个leader

不同的服务器节点观察到的任期转换的次数可能不同,在某些情况下,一个服务器节点可能没有看到 leader 选举过程或者甚至整个任期全程。任期在 Raft 算法中充当逻辑时钟的作用,这使得服务器节点可以发现一些过期的信息比如过时的leader 。每一个服务器节点存储一个当前任期号,该编号随着时间单调递增。服务器之间通信的时候会交换当前任期号;如果一个服务器的当前任期号比其他的小,该服务器会将自己的任期号更新为较大的那个值。如果一个 candidate 或者 leader 发现自己的任期号过期了,它会立即回到follower状态。如果一个节点接收到一个包含过期的任期号的请求,它会直接拒绝这个请求。

Raft算法中服务器节点之间使用RPC进行通信,并且基本的一致性算法只需要两种类型的RPC:

  1. 请求投票(RequestVote)RPC由 candidate 在选举期间发起
  2. 追加条目(AppendEntries)RPC由leader发起,用来复制日志和提供心跳机制

5. Leader选举

Raft 使用一种心跳机制来触发 leader 选举。当服务器程序启动时,他们都是 follower 。一个服务器节点只要能从 leader 或 candidate 处接收到有效的 RPC 就一直保持 follower 状态。Leader 周期性地向所有 follower 发送心跳(不包含日志条目的 AppendEntries RPC)来维持自己的地位。如果一个 follower 在一段选举超时时间内没有接收到任何消息,它就假设系统中没有可用的 leader ,然后开始进行选举以选出新的leader。

要开始一次选举,follower先增加自己的当前任期号并且转换到candidate状态。然后该节点投票给自己,并且并行地向集群中的其他服务器发送RequestVote RPC,要求其他服务器节点投票给它。Cancidate 会一直保持直到以下三种情况之一发生:

  1. 它自己赢得了这次选举(收到过半的选票)
  2. 其他的服务器节点成为Leader
  3. 一段时间后没有任何获胜者

如果 candidate 赢得选举,会向其他服务器节点发送心跳信号来确定自己的地位并阻止新的选举。在等待投票期间,candidate 可能会收到另一个声称自己是 leader 的服务器节点发来的 AppendEntries RPC。如果这个 leader 的任期号不小于当前的任期号,则 candidate 承认该leader并退回到follower, 否则拒绝这次RPC并继续保持 candidate 状态。

6. 日志复制

Leader 决定什么时候把日志条目应用到状态机中是安全的;这种日志条目被称为已提交的。一旦创建该日志条目的 leader 将它复制到过半的服务器上,该日志条目就会被提交。Leader 追踪将会被提交的日志条目的最大索引,未来的所有 AppendEntries RPC 都会包含该索引,这样其他的服务器才能最终知道哪些日志条目需要被提交。Follower 一旦知道某个日志条目已经被提交就会将该日志条目应用到自己的本地状态机中。

leader 通过强制 follower 复制它的日志来解决不一致的问题。这意味着 follower 中跟 leader 冲突的日志条目会被 leader 的日志条目覆盖。Leader 从来不会覆盖或者删除自己的日志条目。

日志匹配特性:

  • 如果不同日志中的两个条目拥有相同的索引和任期号,那么他们存储了相同的指令。
  • 如果不同日志中的两个条目拥有相同的索引和任期号,那么他们之前的所有日志条目也都相同。

Leader 在特定的任期号内的一个日志索引处最多创建一个日志条目,同时日志条目在日志中的位置也从来不会改变。该点保证了上面的第一条特性。第二个特性是由 AppendEntries RPC 执行一个简单的一致性检查所保证的。在发送 AppendEntries RPC 的时候,leader 会将前一个日志条目的索引位置和任期号包含在里面。如果 follower 在它的日志中找不到包含相同索引位置和任期号的条目,那么他就会拒绝该新的日志条目。

因此,每当 AppendEntries RPC 返回成功时,leader 就知道 follower 的日志一定和自己相同(从第一个日志条目到最新条目)。

7. 安全性

7.1 选举限制

RPC 中包含了 candidate 的日志信息,如果投票者自己的日志比 candidate 的更新,它会拒绝掉该投票请求。

Raft 通过比较两份日志中最后一条日志条目的索引值和任期号来定义谁的日志比较新。如果两份日志最后条目的任期号不同,那么任期号大的日志更新。如果两份日志最后条目的任期号相同,那么日志较长的那个更新。

7.2 提交之前任期内的日志条目

Raft 永远不会通过计算副本数目的方式来提交之前任期内的日志条目。只有 leader 当前任期内的日志条目才通过计算副本数目的方式来提交;一旦当前任期的某个日志条目以这种方式被提交,那么由于日志匹配特性,之前的所有日志条目也都会被间接地提交。

也即是,即使之前任期内的日志条目超过了半数,依然不执行,必须要等到当前任期的日志条目超过半数,才可以全部进行提交。

为什么会出现这种情况?

因为raft leader选举不完备,一个节点要当选为leader有两种情况

  • 它的term >= 多数派的 term
  • 他的term == 多数派的term,它的log长度 >= 多数派

在情况a中,新leader可能缺一些多数派中存在且已经被提交的log。

参考:

8. Follower 和 candidate 崩溃

若这两者崩溃,后续发送给他们的 RequestVote 和 AppendEntries PRCs 都会失败,Raft 通过无限的重试来处理这种失败。如果崩溃的机器重启了,这些RPC就会成功的完成。由于Raft的RPC都是幂等的,因此重试不会造成任何危害。

9. 日志压缩

快照技术是日志压缩最简单的方法。在快照技术中,整个当前系统的状态都以快照的形式持久化到稳定的存储中,该时间点之前的日志全部丢弃。每个服务器独立地创建快照,快照只包括自己日志中已经被提交的条目。

对于运行缓慢的 follower 或者新加入集群的服务器,让该 follower 更新到最新的状态的方式就是 leader 通过网络把快照发送给它。

参考Raft算法(论文翻译)

Distributed | Raft的更多相关文章

  1. 分布式系统理论进阶 - Raft、Zab

    引言 <分布式系统理论进阶 - Paxos>介绍了一致性协议Paxos,今天我们来学习另外两个常见的一致性协议——Raft和Zab.通过与Paxos对比,了解Raft和Zab的核心思想.加 ...

  2. 分布式系统(Distributed System)资料

    这个资料关于分布式系统资料,作者写的太好了.拿过来以备用 网址:https://github.com/ty4z2008/Qix/blob/master/ds.md 希望转载的朋友,你可以不用联系我.但 ...

  3. 分布式学习材料Distributed System Prerequisite List

    接下的内容按几个大类来列:1. 文件系统a. GFS – The Google File Systemb. HDFS1) The Hadoop Distributed File System2) Th ...

  4. Raft

    http://thesecretlivesofdata.com/raft/ https://github.com/coreos/etcd   1 Introduction Consensus algo ...

  5. Raft、Zab

    Raft.Zab 引言 <分布式系统理论进阶 - Paxos>介绍了一致性协议Paxos,今天我们来学习另外两个常见的一致性协议--Raft和Zab.通过与Paxos对比,了解Raft和Z ...

  6. 分布式一致性算法:Raft 算法(论文翻译)

    Raft 算法是可以用来替代 Paxos 算法的分布式一致性算法,而且 raft 算法比 Paxos 算法更易懂且更容易实现.本文对 raft 论文进行翻译,希望能有助于读者更方便地理解 raft 的 ...

  7. Raft论文学习笔记

    先附上论文链接  https://pdos.csail.mit.edu/6.824/papers/raft-extended.pdf 最近在自学MIT的6.824分布式课程,找到两个比较好的githu ...

  8. 从分布式一致性到共识机制(二)Raft算法

    春秋五霸说开 春秋五霸,是指东周春秋时期相继称霸主的五个诸侯,“霸”,意为霸主,即是诸侯之领袖.典型的比如齐桓公,晋文公,春秋时期诸侯国的称霸,与今天要讨论的Raft算法很像. 一.更加直观的Raft ...

  9. Raft协议学习笔记

    目录 目录 1 1. 前言 1 2. 名词 1 3. 什么是分布式一致性? 3 4. Raft选举 3 4.1. 什么是Leader选举? 3 4.2. 选举的实现 4 4.3. Term和Lease ...

随机推荐

  1. ES Next & Arrow function & Promise & Iterator & Generator yield & Async Await

    ES Next & Arrow function & Promise & Iterator & Generator yield & Async Await co ...

  2. git in depth

    git in depth git delete remote branch # Deleting remote branches in Git $ git push origin --delete f ...

  3. ts 索引签名 无视多余的属性类型

    interface SquareConfig { color?: string; width?: number; [propName: string]: any; } function asd(opt ...

  4. 阿里面试这样问:redis 为什么把简单的字符串设计成 SDS?

    2021开工第一天,就有小伙伴私信我,还给我分享了一道他面阿里的redis题(这家伙绝比已经拿到年终奖了),我看了以后觉得挺有意思,题目很简单,是那种典型的似懂非懂,常常容易被大家忽略的问题.这里整理 ...

  5. 5分钟入门websocket

    5 个步骤快速掌握消息发送和接收 获取您的 appkey 先注册一个irealtime账号,然后登录到后台管理端,创建一个免费应用,就能得到您的 appkey.点击注册 各种前端生态端集成 ireal ...

  6. JDK源码阅读-Reference

    本文转载自JDK源码阅读-Reference 导语 Java最初只有普通的强引用,只有对象存在引用,则对象就不会被回收,即使内存不足,也是如此,JVM会爆出OOME,也不会去回收存在引用的对象. 如果 ...

  7. JAVA 8 新特性实用总JAVA 8 新特性实用总结结

    JAVA 8 新特性实用总结 作为一个工作两年多的 老 程序猿,虽然一开始就使用 jdk1.8 作为学习和使用的版本,随着技术的迭代,现有的 JDK 版本从两年前到现在,已经飞速发展到了 JDK 15 ...

  8. Sqoop 数据迁移工具

    Sqoop 数据迁移工具 sqoop : SQL to hadOOP 两个功能: 1. RDB 向HDFS导入 2. HDFS向RDB导入 注:拷贝mysql-connector.jar 和 json ...

  9. 微信小程序:优化页面要渲染的属性

    问题:页面中只用到四个属性:goods_name,goods_price,goods_introduce,pics,但是整个对象中有22个属性,小程序中建议:data中只存放标签中要使用的数据,而现在 ...

  10. 链表算法题二,还原题目,用debug调试搞懂每一道题

    文章简述 大家好,本篇是个人的第4篇文章. 承接第3篇文章<开启算法之路,还原题目,用debug调试搞懂每一道题>,本篇文章继续分享关于链表的算法题目. 本篇文章共有5道题目 一,反转链表 ...