图解:什么是Raft算法?
导读
在之前的文章《基于SpringCloud的微服务架构演变史?》中我们介绍了分布式注册中心Consul集群中使用了Raft这种分布式一致性算法,那么在这一篇的内容中就给大家详细介绍下什么是Raft算法。
我们知道进行微服务架构很重要的一个目标就是实现分布式提升整体系统的性能和可靠性。而提供系统可靠性的关键就是通过建立多个副本节点的方式来保证系统中一台或多台服务节点故障的情况下,系统仍然可用。但是多个副本之间的数据一致性如何保证,就成了一个新的问题,而分布式一致性算法就是为了解决分布式环境下多副本之间数据一致性问题的。
在基于SpringCloud的微服务体系中,Consul作为整个服务的注册中心,处于十分关键的位置,所以Consul在生产环境下都是以集群的方式来提供服务的,而整个Consul集群间的节点数据同步就需要像Raft这样的一致性算法来实现。
下面我们就以图解的方式来深入了解下Raft的工作机制!
Raft的角色
在Raft算法中节点存在Follower、Candidate、Leader三种状态。
Raft节点选举(Leader Election)
在初始状态下集群中所有的节点都处于Follower状态。
此时如果某个Follower节点,如Node a首先感知不到来自Leader节点发送的心跳,就会将自身的状态转换为Candidate。
这里有一个选举超时时间为随机分配的150ms~300ms之间,选举超时后,Follower节点就会转换为Candidate节点并开始新的选举任期Term。
此时进入Candidate状态的节点首先会给自己投上一张选票(Voted For a)然后会向其他节点发送选举请求(Vote For me),要求选举自己为Leader。
如果接收到Candidate Vote请求的其他节点在这个选举任期(Term=1)还没有进行过投票,那么它们就会给发送请求的Candidate进行投票响应,并且重置本节点的选举超时时间设置。
如果Candidate节点得到大多数节点的选票,那么它就会成为本届任期内新的Leader节点。
此时Leader节点与各个Follower节点之间就会通过发送heartbeats来感知彼此的状态,直到某个Follower节点率先感知不到Leader节点的心跳,变成Candidate状态后重新发起新一届选举为止。
Raft日志复制(Log Replication)
在选举产生新的Leader节点后,集群系统的所有改变都将通过Leader节点,并由Leader节点同步给其他所有节点。这是通过使用一种与心跳相同的,称之为“Append Entries”的消息来完成的。
下面我们就来具体看下这个过程具体是什么样的:
首先,客户端向Leader节点发送数据变化请求“SET 5”,Leader节点接收到这个改变后,会将其添加到节点的日志条目中。
然后这个改变会在下一次发送心跳时,同步给所有的Follower节点。一旦这个改变被大部分Follower节点所接受,那么Leader节点就会正式Commit这个条目,并向Client端进行响应。
之后Leader节点会再次向所有Follower节点同步Commit请求,Follower节点完成此条目的提交,此时集群就现在系统的状态达成了一致。
如果此时再次发起一个“ADD 2”的操作,过程也是一样的,最终集群中所有的节点的值会达成7的共识。
选举冲突
在前面的节点选举的示例中,某个Follower在选举超时时间内没有接收到Leader心跳后就会转换为Candidate角色发起选举,并由其他多数Follower节点选举为Leader节点,这是一种比较理想的状况。
实际上,一旦集群中Leader节点挂掉,此时可能多个Follower节点可能会同时过了选举超时时间而变成Candidate状态,从而同时发起新一届的选举请求。如图:
两个节点都开始了同一任期的选举…
并且每一个都先于另外一个得到一个Follower节点的选票,但此时在这届任期类两个Candidate都将不会得到更多的选票了,那么在这一届的选择中就无法选出新的Leader节点了。
此时所有的节点都将进入等待状态,并重新尝试开始下一次选举。如图:
经过下一届选举,最终Node d成为新的Leader。事实上这次选举也可能会出现选举分裂的情况的,所以在实际应用中,一般都建议在集群中部署奇数个节点,例如,之前的Consul集群我们就是部署5个节点,目前就是防止偶数节点导致选举出现冲突的情况。
集群分裂
我们再来考虑另外一种极端的情况,假设集群因为某些原因(如网络切断)导致集群被切割为两块,有Leader节点的一块继续运行、没有Leader节点的一块则进入选举状态,并选出自己新的Leader节点,如图:
此时c、d、e三个节点组成集群选举产生了新的Leader节点e,并且选举任期更新为2,比节点b更高,同时两个Client分别向这两块集群发起了SET请求。由于节点b不能复制到大多数节点,所以一直处于Uncommit状态,而节点c因为能够复制到大多数节点所以可以正常commit。
当集群分裂问题恢复后,原先的Leader节点B看到更高的选举任期就会主动下台,而A和B两个节点将回滚它们未提交的条目,并匹配新leader节点c的日志,从而实现日志在整个集群中的一致性(实际上是少数节点的集群学习多数节点的集群的leader,进而完成一致性过程)。
后记
Raft 和Paxos是目前分布式系统领域中两种非常著名的解决一致性问题的共识算法,两者都能解决分布式系统中的一致性问题,但是Paxos的实现与证明非常难以理解,Raft的实现则比较简洁并且遵循人的直觉,它的出现就是为了解决 Paxos 难以理解并和难以实现的问题。
后续有机会可以再和大家一起讨论关于Paxos算法的相关的知识,谢谢大家的支持!
参考:
http://www.cnblogs.com/hzmark/p/raft.html
http://thesecretlivesofdata.com/raft/
https://raft.github.io/
—————END—————
原作者公众号
-更多文章-
Spring Cloud GateWay初体验
Kubernetes基础与架构
对业务系统的监控 No.118
Kubernetes对象模型
拜托!面试请不要再问我Spring Cloud底层原理
【性能优化之道】每秒上万并发下的Spring Cloud参数优化实战
Docker 核心技术与实现原理
学习别跟我谈兴趣 No.88
条件注解 @ConditionalOnBean 的正确使用姿势
分布式事务的实现原理
-关注我-
图解:什么是Raft算法?相关推荐
- 分布式共识算法——Raft算法(图解)
文章目录 Raft 算法 Raft 算法概念 Raft 角色 Raft 算法流程 Raft 算法原理 角色关系 任期原理 通信原理 图解算法流程 选举过程 执行操作过程(日志复制) 确保安全 Lead ...
- 分布式系统的Raft算法
2019独角兽企业重金招聘Python工程师标准>>> 分布式系统的Raft算法 过去, Paxos一直是分布式协议的标准,但是Paxos难于理解,更难以实现,Google的分布式锁 ...
- 分布式系统的Raft算法——在失联阶段这个老Leader的任何更新都不能算commit,都回滚,接受新的Leader的新的更新 意味着还是可能丢数据!!!...
过去, Paxos一直是分布式协议的标准,但是Paxos难于理解,更难以实现,Google的分布式锁系统Chubby作为Paxos实现曾经遭遇到很多坑. 来自Stanford的新的分布式协议研究称为R ...
- 一文搞懂Raft算法
英文解析: 1 follower : 信徒 2 candidate :候选人 3 majority :多数 4 term :术语 5 election :选举 6 leader :领导 7 repli ...
- 图解JVM垃圾回收算法
1 简单介绍下----->垃圾回收概念 GC中的垃圾,指的是存在于内存中的.不会再被使用的对象.而垃圾回收就是把那些不再被使用的对象进行清除,收回占用的内存空间.如果不及时对内存中的垃圾进行清理 ...
- raft算法mysql主从复制_Raft算法赏析
前言 最近抽空看了大名鼎鼎的Raft算法论文,看完后就一个感觉:如此复杂的算法居然可以设计得如此简洁.巧妙. 反复看了几遍,非常过瘾,原文不仅通俗易懂,而且非常严谨,所有异常情况都做了充分的考虑以及给 ...
- 动图图解C语言插入排序算法,含代码分析
C语言文章更新目录 C语言学习资源汇总,史上最全面总结,没有之一 C/C++学习资源(百度云盘链接) 计算机二级资料(过级专用) C语言学习路线(从入门到实战) 编写C语言程序的7个步骤和编程机制 C ...
- 【转】分布式一致性算法:Raft 算法(Raft 论文翻译)
编者按:这篇文章来自简书的一个位博主Jeffbond,读了好几遍,翻译的质量比较高,原文链接:分布式一致性算法:Raft 算法(Raft 论文翻译),版权一切归原译者. 同时,第6部分的集群成员变更读 ...
- Raft算法和开源实现
CoreOS是一个基于Docker的轻量级容器化Linux发行版,专为大型数据中心而设计,旨在通过轻量的系统架构和灵活的应用程序部署能力简化数据中心的维护成本和复杂度.CoreOS作为Docker生态 ...
最新文章
- html固定且居中布局含footer,如何用一行 CSS 实现 10 种现代布局?
- 从薪资、需求来分析,武汉Java开发就业前景好不好?
- CodeForces - 1395D Boboniu Chats with Du(贪心)
- 2019年招聘过程的种种酸甜苦辣历程
- python 图形_Python图形数据
- C++ STL vector的操作
- 贾跃亭成了,FF 91预量产车下线完成
- 无限复活服务器,绝地求生无限复活模式怎么玩 无限复活玩法说明介绍
- 2018年线程与多线程面试必知必会内容
- 4.nslookup
- C#中,接口继承、基类继承中父类与基类的执行顺序
- 学计算机 数学日记,数学日记3篇
- CVE-2018-0798_微软公式编辑器漏洞分析
- android x86玩和平精英,和平精英iOS和安卓可以一起玩吗 和平精英iOS和安卓数据互通吗...
- 等保测评所需postgresql数据库命令以及内容解析
- 记java的那些编辑器的故事之凌嘉文+李晓彤-结对编程
- 软件文档的作用和分类
- java 调用 delphi_【java】试用JNA调用Delphi的dll方法。
- bzoj1864 [Zjoi2006]三色二叉树
- 0x00000004 因果推理 —— 入门学习笔记
热门文章
- RXJAVA之变换操作
- Kindeditor学习中的那些坑
- oracle测试环境表空间清理
- LESS 的 operation 是 特性
- cf-Sasha and Array
- [转] Gradle: 此时不应有 Androidandroid-studiosdk oolslib\find_java.exe。解决方法
- UI学习第二篇 (控件)
- 【Whalepaper】NLP论文研读 - Keyword-Attentive Deep Semantic Matching
- LeetCode实战:相交链表
- Matlab与线性代数--矩阵的正交分解