登录 |  注册
首页 >  云计算&大数据 >  经典算法大全 · 实例详解 >  Raft算法原理及应用-分布式一致性算法

Raft算法原理及应用-分布式一致性算法

Raft协议分区容忍的一致性协议的核心思想:一致性的保证不一定非要所有节点都保持一致,只要大多数节点更新了,对于整个分布式系统来说数据也是一致性的。Raft 协议将概念分解成:Leader election、Log replication、Safety。Raft 把一致性协议划分为 Leader 选举、MemberShip 变更、日志复制、Snapshot 等几个几乎完全解耦的模块,实现了模块化设计。

Raft 设计原则是通过减少状态数量将状态空间简化:

  • 日志不允许出现空洞 , 并且 Raft限制了日志不一致的可能性

  • 使用随机化时钟简化了领导选举的算法

领袖选举

Raft协议为了保证Leader的健壮性,使用了以下技术保证选举的简单化实现:

超时驱动:Heartbeat/Election timeout

随机的超时时间:降低选举碰撞导致选票被瓜分的概率

Paxos.jpg

Raft协议为了保证选举投票的有效性,规定了一系列的投票原则:

  • 在任一任期内,单个节点最多只能投一票

  • 候选人知道的信息不能比自己的少优先:投票节点通过对比Term(任期)和CommitId来判断是否投“同意”票。

  • first-come-first-served 先来先得 :收到多个RequestVote RPC拉票,对首先到达的进行投票

Raft 整体选举流程如下:

  • Candidate发起投票时将自身当前任期加1(NewTerm),并向集群中所有节点发起投票请求(RequestVote RPC:请求中包含新的任期值);

  • follower节点 根据投票原则进行 投票

  • Candidate得到大于半数节点的“同意”后成为Leader,与其他节点建立心跳,并更新所有节点的当前任期为NewTerm;

  • 如果不够半数,则选举失败,启用随机选举超时策略

    • 所有 Condidate 随机sleep (即timeout)一段时间,然后开始新一轮的选举。

    • 第一个苏醒 Condidate 会向所有 Condidate 发出投票给我的申请

    • 还没有苏醒的 Condidate 就只能投票给已经苏醒的 Condidate 。

日志复制

Raft 协议定义的日志格式如下:

(TermId, LogIndex, LogValue)
其中 (TermId, LogIndex) 能确定唯一一条日志
br

Raft 协议 复制策略规定一系列的原则:

  • 连续性:日志不允许出现空洞

  • 有效性:

    • 一个log被复制到大多数节点,就是committed,保证不会回滚

    • leader一定包含最新的committed log,因此leader只会追加日志,不会删除覆盖日志

    • leader只能提交当前term的日志;不能提交前任日志

    • 当出现了leader与follower不一致的情况,leader强制follower复制自己的log

Followers 日志有效性检查:

  • AppendEntries RPC中还会携带前一条日志的唯一标识(prevTermId, prevLogIndex)

  • 递归推导

Followers 日志恢复:

  • Leader 将 nextIndex 递减并重发 AppendEntries,直到与 leader 日志一致

Raft协议的日志复制完整流程如下:

  • leader 将client的请求命令作为一条新的日志项写入日志。

  • leader 发送AppendEntries RPC 给follower 备份 该日志项。

  • follower收到leader的AppendEntries RPC,将该日志项记录到日志并反馈ack。

  • leader 收到 半数以上的follower 的ack,即认为消息发送成功

  • leader 将 该日志项 提交状态机(state machine)处理

  • leader 将执行结果返回给 client

  • leader 发送AppendEntries RPC 通知 follower 提交状态机

  • follower 收到AppendEntries RPC,follower判断该日志项是否已执行,若未执行则执行commitIndex以及之前的日志项。

raft.jpg

安全性

Radt协议通过一系列的规范定义,保证了整个Raft机制的数据的顺序一致性。整体原则如下:

选举限制

  • 用投票规则的限制来组织日志不全的服务器赢得选举

    • RequestVote RPC限制规则: 拒绝日志没自己新的candidate

  • 领袖节点只能追加日志,不能重写或者删除日志

  • 日志条目只能从leader流向follower

如何提交上一个任期的日志条目

  • 全程保持自己的任期号

安全性论证

  • 领导人完整性原则(Leader Completeness)

    • 某指令在某个任期中存储成功,则保证存在于领袖该任期之后的记录中。

    • 不同节点,某位置上日志相同,那么该位置之前的所有日志一定是相同的。

  • 状态机安全原则(State Machine Safety)

    • 如果节点将某一位置的日志应用到了状态机,那么其他节点在同一位置不能应用不同的日志

通过上述的规范定义,我们可以通过一些异常场景来突出Raft协议的安全性:

追随者死机 

当某台追随者死机时,所有给它的转发指令和拉票的消息都会因没有回应而失败,此时发送端会持续重送。当这台追随者引导重新加入集群,就会收到这些消息,追随者会重新回应,如果转发的指令已经写入,不会重复写入。

领袖死机

领袖死机或断线时,每个已存储指令必定已经写入到过半的服务器中,此时选举流程会让记录最完整的服务器胜选。其中一个因素是Raft候选人拉票时会揭露自己记录最新一笔的信息,如果服务器自己的记录比较新,就不会投票给候选人。

超时期限和可用性

因为Raft引导选举是基于超时,使得超时期限的选择至为关键。若遵守算法的时限需求:广播时间 << 超时期限 << 平均故障间隔。这三个时间定义如下:

  • 广播时间:单一服务器发送消息给集群中每台服务器并得到回应的平均时间,需要测量得到。

  • 超时期限:发动选举的超时期限,由部署Raft集群的人选定。

  • 平均故障间隔:服务器发生故障之间的平均时间,可以测量或估计得到。

广播时间典型是 0.5ms 到 20ms,平均故障间隔通常是用周或月来计算的,所以可以将超时期限设在 10ms 到 500ms。

总结   

本文总体介绍了Raft协议的三个核心概念及对应流程规范,通过这三个概念流程我们可以很容易理解和实现Raft协议。Raft以容易理解著称,业界也涌现出很多 raft 实现,比如大名鼎鼎的 etcd, braft, tikv 等。也有很多知名的独立的Raft协议开源框架:

lhttps://github.com/sofastack/sofa-jraft/ 源于蚂蚁,java编写

lhttps://github.com/hashicorp/raft 源于hashicorp,go编写

lhttps://github.com/baidu/braft 源于百度,C++编写

https://github.com/rabbitmq/ra 源于rabbitmq,Erlang编写

上一篇: Paxos算法原理及应用-分布式一致性算法
下一篇: PacificA算法分析-分布式一致性框架
推荐文章
  • MD5(Message-DigestAlgorithm5)是一种广泛使用的散列函数(哈希函数),由美国密码学家罗纳德·李维斯特(RonaldL.Rivest)在1991年设计。MD5的作用是对任意长度的信息生成一个固定长度(128位,即32个十六进制字符)的“指纹”或“消息摘要”,并且几乎不可能找到
  • 循环冗余校验(CyclicRedundancyCheck,CRC)是一种用于检测数据传输和存储过程中发生错误的技术,属于一种基于数学原理的错误检测编码(ErrorDetectionCoding)方法。它通过在原始数据上附加一个固定长度的校验码,使得接收端可以通过同样的计算规则对收到的数据进行校验,确
  • AES(AdvancedEncryptionStandard)是一种广泛使用的对称密钥加密算法,它是美国国家标准与技术研究院(NIST)于2001年制定的加密标准,用于替代原有的DES(DataEncryptionStandard)。AES算法以其高效性、安全性和可靠性而著称,在众多应用领域中被广泛
  • RSA(Rivest-Shamir-Adleman)是一种广泛应用的非对称加密算法,由RonRivest、AdiShamir和LenAdleman在1977年提出。其安全性基于数学上的大数因子分解难题,即对于足够大的两个素数p和q而言,已知它们的乘积很容易,但想要从这个乘积中恢复原始的素数则异常困难
  • 最小生成树(MinimumSpanningTree,MST)是一种图论算法,用于在一个带权重的无向连通图中找到一棵包括所有顶点且总权重尽可能小的树。常见的最小生成树算法有两种:Prim算法和Kruskal算法。Prim算法原理:Prim算法是一种贪心算法,它从图中的一个顶点开始,逐步增加边,每次都添
  • 关于最短路径算法的Java实现,这里简述一下几种常用的算法及其基本原理,并给出一个Dijkstra算法的基本实现框架。Dijkstra算法(适用于无负权边的图)Dijkstra算法用于寻找图中一个顶点到其他所有顶点的最短路径。它维护了一个距离表,用来存储从源点到各个顶点的已知最短距离,并且每次都会选
学习大纲