分布式共识协议 Raft 是如何工作的?
Raft 解决的问题
提供一种共识算法(分布式一致性算法)。 Paxos是早先的一个分布式共识算法,Paxos 逻辑复杂而难以理解和实现。相比早先的 Paxos, Raft 提供一个容易理解和实现的共识算法,在很多的系统比如 etcd, ozone,tikv,RethinkDB 等项目中大量使用。
分布式共识协议, 源于我们对系统可用性,容错性的追求。分布式系统中,我们把数据复制到多个节点,为了解决多份数据的一致性问题, 常常将其简化为多份状态机的一致性问题。
对于客户端发来的指令, 只要能确保指令以唯一确定的顺序发送给所有结点, 那么只要各个状态机的初始状态相同, 执行完所有指令后, 也会到达相同的一致状态。 在多状态机一致性问题中, 共识算法( Consensus Algorithm) 的作用就是确保多份 log 中包含顺序和内容完全一致的指令,Raft 算法也即为了达到这个目的。
什么是共识? distributed consensus
共识是多个服务器在某一个值上达成一致。 这个值可以是商品的库存,可以是最大的Id值,可以是代表集群中主节点(Master 节点)的id,可以是账号里的余额数据,可以是任何的需要共识的数据,比如一份合同,钱包属于谁的,等等。
分布式共识的不同算法
Paxos (1990) – 可以工作,但少有人能够理解,难以正确实现
Raft (2014) – “In Search of an Understandable Consensus Algorithm” , Diego Ongaro and John Ousterhout – USENIX ATC’14, https://raft.github.io
Raft 算法的工作过程
多结点数据一致性的问题可以被抽象简化为多状态机副本一致性问题。
共识算法(一致性算法)是从复制状态机的背景下提出的。在这种方法中,一组服务器上的状态机产生相同状态的副本,并且在一些机器宕掉的情况下也可以继续运行。复制状态机在分布式系统中被用于解决很多容错的问题。例如,大规模的系统中通常都有一个集群领导人,像 GFS、HDFS 和 RAMCloud,典型应用就是一个独立的复制状态机去管理领导选举和存储配置信息并且在领导人宕机的情况下也要存活下来。比如 Chubby 和 ZooKeeper。
让整个集群拥有一个主结点, 客户端只向集群中的主结点发送指令, 如果客户端将指令发送给了集群中的非主结点, 非主结点都会直接返回主结点的地址, 让客户端与主结点建立连接,由主结点进行所有指令的接收和分发, 这样非常简单地就可以确保集群中的每个状态机都收到一份相同的指令,每一条指令即是一条日志。如果主节点出现故障,其他节点发起选举选出新的节点。
日志复制结构(图)
Raft 通过选举一个主节点,然后给予他全部的管理复制日志的责任来实现一致性。主节点从客户端接收日志条目(log entries),把日志条目复制到其他服务器上,并告诉其他的服务器什么时候可以安全地将日志条目应用到他们的状态机中。拥有一个主节点大大简化了对复制日志的管理。
Raft 将整个复杂的问题分解为三个相对独立的子问题逐个解决。
1.主结点选举问题
如何在一个主结点宕机后, 重新为集群选举出新的主结点。
2.指令集分发(日志分发)问题
主结点必须能够接收客户端发来的指令,并将指令 log 分发复制给集群中的其他结点, 并强迫其他状态机所持有且执行的指令 log 与自己的指令 log 达成一致。
3.安全性问题
Raft 算法对于安全性的定义有多条始终成立的性质共同构成
Raft 算法中的几个主要概念
概念 | 英文 | 概念定义 |
主节点 | Leader | Raft 集群中的一台主服务器,负责接收、处理、响应所有来自客户端的请求 |
跟随节点 | Follower | 跟随节点自己不会发送任何请求, 只会响应来自 leader 和 candidate 的请求, 不会响应其他 follower 发来的请求, 如果 follower 收到了来自客户端的请求, follower 会将主节点的信息返回客户端, 让客户端去联系 |
候选人节点 | Candidate | candidate 是选举过程中的候选节点角色, 当 leader 失效后, 会有follower 转变为 candidate , 下一个 leader 从candidate 中产生 |
任期 | Term |
在 Raft 协议中,时间被划分成一个个的任期,每个任期始于一次选举。在选举成功后,主节点会管理整个集群直到任期结束。有时候选举会失败,那么这个任期就会没有主节点而结束。任期之间的切换可以在不同的时间不同的服务器上观察到。 一个任期内最多只有一个主节点(也可能没有主节点); 任期 term 初始值为0,经过初次选举后变成1,单调递增; |
日志 | Log | 日志包含了用于状态机的命令,以及 Leader接收到该条目时的任期(任期从1开始) |
日志索引 | Log Index | 每一条日志条目都有一个整数索引值来表明它在日志中的位置 |
已提交日志 | Committed Log | Raft 算法保证所有已提交的日志条目都是持久化的并且最终会被所有可用的状态机执行。在领导人将创建的日志条目复制到大多数的服务器上的时候,日志条目就会被提交,提交之后变成已提交 |
最后应用的日志索引 | lastApplied Index | 已经被应用到状态机的最大的日志条目的索引(初始值为0,单调递增) |
任期 (图)
一个任期中可能有操作,也可能没有操作,一个任期中最多有一个 leader,也可能没有 leader。 图中有4个任期,t1, t2, t3, t4。
日志序列/日志索引(图)
图中日志的索引从1到8,每条日志里面有一个任期,以及一条赋值指令(如 x <- 3)。图中 leader 节点经历了3个任期,1, 2, 3。
几个主要问题是如何解决的?
1.如何选举出主节点
Raft 使用一种心跳机制来触发领导人选举。当服务器程序启动时,他们都是跟随者身份(Follower)。服务器节点只要从领导人或者候选人处接收到有效的 RPCs,就继续保持着跟随者状态。 Leader 节点周期性的向所有跟随者发送心跳包(即不包含日志项内容的附加条目(AppendEntries)的 RPCs)来维持自己的权威。
如果一个跟随者在一段时间里没有接收到任何消息,也就是选举超时,那么他就会认为系统中没有可用的领导人,此时跟随者变成候选人,并且发起选举以选出新的领导人。
开始一次选举的过程:跟随者先要增加自己的当前任期号并且转换到候选人状态。然后他会并行地向集群中的其他服务器节点发送请求投票的 RPCs 来给自己投票。候选人会继续保持着当前状态直到以下三件事情之一发生:
(a) 他自己赢得了这次的选举,
(b) 其他的服务器成为领导人,
(c) 一段时间之后没有任何一个获胜的人。
当一个候选人从整个集群的大多数服务器节点获得了针对同一个任期号的选票,那么他就赢得了这次选举并成为领导人。每一个服务器最多会对一个任期号投出一张选票,按照先来先服务的原则。要求大多数选票的规则确保了最多只会有一个候选人赢得此次选举。
一旦候选人赢得选举,他就立即成为领导人。
然后他会向其他的服务器发送心跳消息来建立自己的权威并且阻止发起新的选举。
在等待投票的时候,候选人可能会从其他的服务器接收到声明它是领导人的附加条目(AppendEntries)RPC。
如果这个领导人的任期号(包含在此次的 RPC中)不小于候选人当前的任期号,那么候选人会承认领导人合法并回到跟随者状态。 如果此次 RPC 中的任期号比自己小,那么候选人就会拒绝这次的 RPC 并且继续保持候选人状态。
第三种可能的结果是候选人既没有赢得选举也没有输:如果有多个跟随者同时成为候选人,那么选票可能会被瓜分以至于没有候选人可以赢得大多数人的支持。当这种情况发生的时候,每一个候选人都会超时,然后通过增加当前任期号来开始一轮新的选举。
Raft 算法使用随机选举超时时间的方法来确保很少会发生选票瓜分的情况,就算发生也能很快的解决。为了阻止选票起初就被瓜分,选举超时时间是从一个固定的区间(例如 150-300 毫秒)随机选择。这样可以把服务器都分散开以至于在大多数情况下只有一个服务器会选举超时;然后他赢得选举并在其他服务器超时之前发送心跳包。同样的机制被用在选票瓜分的情况下。每一个候选人在开始一次选举的时候会重置一个随机的选举超时时间,然后在超时时间内等待投票的结果;这样减少了在新的选举中另外的选票瓜分的可能性。
其他更多逻辑参考如下参考文章。
Raft 的教程,视频课程,以及不同语言中的实现
Raft Consensus Algorithm
参考文章
https://ramcloud.atlassian.net/wiki/download/attachments/6586375/raft.pdf
https://www.usenix.org/system/files/hotcloud19-paper-ahn.pdf
Apache Kudu - Introducing Apache Kudu
https://home.apache.org/~szetszwo/presentations/20171115brown_bag.pdf
https://arxiv.org/pdf/1711.06964.pdf
GitHub - maemual/raft-zh_cn: Raft一致性算法论文的中文翻译
分布式共识协议 Raft 是如何工作的?相关推荐
- Ubuntu 16.04 配置Raft(分布式共识协议)及Maven+Java运行环境
本文用于在Ubuntu 16.04中配置分布式共识协议 Raft, 运行环境为Java + Maven, 开辟端口为 8051-8080, demon中实际使用端口为8051-8053 Raft软件包 ...
- HoneyBadgerBFT:一个网络环境无关的Byzantine容错的分布式共识协议
2017-01-04 Jin Gao HoneyBadgerBFT:一个网络环境无关的Byzantine容错的分布式共识协议 作者介绍: 夏雨,麻省理工学院电子工程与计算作者机科学系博士一年级在读,本 ...
- 分布式一致性协议Raft(一)
铺垫 一个设计良好的分布式系统,应具备四大特点: 并行性能(parallel performance):任务能均衡高效地在多台机器上执行,无需过高的通讯和锁消耗. 容错性(fault-toleranc ...
- 分布式一致性协议Raft,以及难搞的Paxos
Raft这玩意,网上已经有好多解读文章了,大概比Paxos还要多一些,所以,这篇,不求细节,但求核心思想方面,追一下本源,然后,给自己做个笔记. Raft是什么,它想解决什么问题? 所以Raft是什么 ...
- 分布式共识算法 —— Raft详解
文章目录 分布式共识算法 顺序一致性 线性一致性 因果一致性 Raft 算法 原理概览 选举机制 新节点加入 leader 掉线处理 多个 follower 同时掉线 日志复制 参考文献 分布式共识算 ...
- [分布式一致性协议] ------ raft协议的解释与理解
前言 在分布式系统中,为了保证容错性,一般会维护多个副本集群,提高系统的高可用,但与之带来的问题就是多个副本的一致性(consensus)问题. 我们认为,对于一个具有一致性的的集群中,同一时刻所有节 ...
- 动画演绎分布式共识算法Raft
1. Raft 概述 Raft 算法是分布式系统开发首选的共识算法.主要在分布式集群架构下进行领导者(主节点)的确认. 比如现在流行的组件 Etcd.Consul.Nacos.RocketMQ.Red ...
- 分布式一致性协议Raft原理与实例
来源:http://m635674608.iteye.com/blog/2283621 1.Raft协议 1.1 Raft简介 Raft是由Stanford提出的一种更易理解的一致性算法,意在取代目前 ...
- 分布式共识算法——Raft算法(图解)
文章目录 Raft 算法 Raft 算法概念 Raft 角色 Raft 算法流程 Raft 算法原理 角色关系 任期原理 通信原理 图解算法流程 选举过程 执行操作过程(日志复制) 确保安全 Lead ...
最新文章
- Spring Cloud 微服务开发系列整理
- Spring Security OAuth 个性化token
- 忘记root密码如何处理
- mysql 已存在数据_MySQL跳过已存在的数据
- 剑指offer-合并链表
- 皮亚诺曲线java,多维空间点索引算法概述
- VS2017 QT/C++ 调用python函数传图像
- 使用NetronGraphLib类库开发Qfd质量屋编制工具
- htc+one+m7+linux驱动,HTC One M7简易刷Recovery教程
- 中国最好的AI竞赛落幕,我们整理了一份夺宝攻略
- ArcGIS学习总结(七)——河流制图综合
- 使用OPENCV对图片进行角度旋转
- 酒店客房管理系统(JAVA,JSP,SERVLET,MYSQL)
- C语言双人贪吃蛇游戏瘦身版本
- 客户想要 VS 客户预算
- 【物联网】思科扔下数颗物联网重磅炸弹,中国IoT圈却选择集体视而不见!
- 电脑突然连不上WIFI和以太网
- 解决Microsoft Visual Studio 2010 Macro宏无法运行
- Hashcat密码破解攻略
- php获取千千音乐的sign,关于QQ音乐sign参数的获取
热门文章
- 【项目实战】WaveNet 代码解析 —— train.py 【更新中】
- php 正则匹配数字范围,正则表达式匹配数字范围
- 自定义flink es source
- jmeter参数化几种方式详解
- 一个屌丝程序猿的人生(一百二十四)
- Android设置锁屏/休眠时长
- 基于FPGA的图像去噪
- [Hugo+Netlify]从零开始建立并发布一个网站
- HFSS仿真宝典 | 非屏蔽双绞线建模及其辐射发射仿真
- R语言使用epiDisplay包的kap函数(kap.ByCategory)函数计算Kappa统计量的值(总一致性、期望一致性)、对多个评分对象的结果进行一致性分析、评分的类别为多个类别