Raft协议学习笔记
目录
目录 1
1. 前言 1
2. 名词 1
3. 什么是分布式一致性? 3
4. Raft选举 3
4.1. 什么是Leader选举? 3
4.2. 选举的实现 4
4.3. Term和Lease比较 4
4.4. 选举图示 4
4.5. 选举总结 7
5. Raft日志复制 8
5.1. 什么是日志复制? 8
5.2. 日志复制的实现 8
5.3. 脑裂时的复制 10
6. 概念对比 12
7. 共性探讨 13
7.1. PacificA和HBase和Kafka 13
7.2. Redis&Raft&ZAB&PaxOS 13
8. 总结浓缩 13
8.1. 三种角色 13
8.2. 两种RPC 13
8.3. 两个超时时间 14
9. 参考 14
1. 前言
常见的一致性协议主要有:PaxOS、Raft、ZAB、PacificA等。同PaxOS,Raft也不考虑拜占庭将军问题(Byzantine failures,注:比特币采用工作量证明PoW和股权证明PoS解决了拜占庭将军问题)。
2. 名词
Distributed Consensus |
分布式一致性 |
Distributed Consensus Algorithms |
分布式一致性算法,PaxOS是分布式一致性算法的鼻祖,绝大多数的实现要么基于PaxOS,要么受PaxOS影响(如Zookeeper)。 |
就分布式系统中的某个值(在PaxOS中叫决议,即Proposer)达成一致的算法。PaxOS是分布式一致性协议的鼻祖,在Google的三大件未推出之前少为人知,1989年莱斯利·兰伯特提出。Leslie Lamport是大神的英文名,出生于1941年2月7日纽约。兰伯特目前就职于微软研究院,他也是排版系统LaTeX的作者,2008年获得冯诺依曼奖,2013年获得图灵奖,麻省理工学院学士和布兰戴斯大学博士。最早的实现为Google内部使用的Chubby。 |
|
Raft |
木筏协议,一种共识算法,旨在替代PaxOS,相比容易理解许多。斯坦福大学的两个博士Diego Ongaro和John Ousterhout两个人以易懂为目标设计的一致性算法,2013以论文方式发布。由于易懂,不从论文发布到不到两年的时间,即出现大量的Raft开源实现。为简化PaxOS的晦涩,它采用分而治之的办法,将算法分为三个子问题:选举(Leader Election)、日志复制(Log Replication)、安全性(Safety)和集群成员动态变更(Cluster Membership Changes)。 |
ZAB |
Zookeeper采用的一致性算法,全称“ZooKeeper Atomic Broadcast”,即Zookeeper原子广播协议,实为Zookeeper版本的PaxOS。 |
微软2008年提出的日志复制协议,与PaxOS和Raft不同,PacificA并不提供Leader选举,因此需要结合PaxOS或Raft,分布式消息队列Kafka的ISR算法类似于PacificA。小米开源的KV系统Pegasus基于PacificA实现。 |
|
Viewstamped Replication |
简称VR,最初被提出是作为数据库中的一部分工作,2012年作为单独的分布式共识算法再次发表。 |
Log Replication |
日志复制 |
Leader Election |
领导选举 |
Log |
代表一个修改操作 |
Entry |
(日志)条目(代表一个修改操作),Log在Raft中的实体,即一个Entry表示一条Log |
Term |
任期(可简单理解成租约,但稍有不同),是一个从0开始递增的整数值,每次发起选举时增一,最终所有节点的Term值是相同的。等同于ZAB协议中的zxid的高32位,即ZAB中的Epoch。 |
Index |
和Term密切相关,Term针对的是选举,而Index针对的是一条Log,它的值也是从0开始递增。同样最终所有节点的Index也相同,如果两个节点的Term和Index均相同,则这两个节点的数据是完全一致的。等同于ZAB协议中的zxid的低32位。 |
Node |
节点 |
Single Node |
单节点 |
Multiple Nodes |
多节点 |
Leader |
领导(唯一接受修改操作的) |
Follower |
跟随者(投票参与者) |
Candidate |
候选人(唯一具有发起选举的) |
Vote |
投票 |
Heal |
恢复,比如恢复网络分区(Heal the network partition) |
Step Down |
下台,当一个Leader发现有更大的Term时,自动降为Follower |
Logic Clock |
逻辑时钟,由Lampert提出,原因是分布式中无法使用精准的时钟维护事件的先后顺序,方法是为每个消息(或日志)加上一个逻辑时间戳。在ZAB协议中,每个消息均由唯一的zxid标识。zxid是一个64位无符号整数值,被分成两部分:高32位是Epoch,低32位是一个从0开始的递增值。类似于Raft的Term,每次选举新Leader,Epoch值增一,但同时zxid值清0。而Raft也类似,实际也是两部分组成,Term对应于Epoch,Index对应于zxid的低32位。 |
Quorum |
法定人数 |
Brain Split |
脑裂,同一个网络的节点被分成了两个或多个不互通的部分 |
3. 什么是分布式一致性?
多个节点(Multiple Nodes)的数据完全相同,即为分布式一致性。但因为多个节点通过网络互联,并不一定时刻可用,而服务不能因为某些节点(特别是少数节点)不可用时,导致整个系统不可用。
Raft将节点分成三种角色:Leader、Follower和Candidate,一个节点可为三种角色中的任意一种,但同一时刻只会为其中一种角色。正常情况下,只有Leader和Follower两种角色的节点,只有在选举时才会出现Candidate角色节点,而且可能多个节点同时处于Candidate角色同时竞争选举。
4. Raft选举
4.1. 什么是Leader选举?
Raft协议中,一个节点有三个状态:Leader、Follower和Candidate,但同一时刻只能处于其中一种状态。Raft选举实际是指选举Leader,选举是由候选者(Candidate)主动发起,而不是由其它第三者。
并且约束只有Leader才能接受写和读请求,只有Candidate才能发起选举。如果一个Follower和它的Leader失联(失联时长超过一个Term),则它自动转为Candidate,并发起选举。
发起选举的目的是Candidate请求(Request)其它所有节点投票给自己,如果Candidate获得多数节点(a majority of nodes)的投票(Votes),则自动成为Leader,这个过程即叫Leader选举。
在Raft协议中,正常情况下Leader会周期性(不能大于Term)的向所有节点发送AppendEntries RPC,以维持它的Leader地位。
相应的,如果一个Follower在一个Term内没有接收到Leader发来的AppendEntries RPC,则它在延迟随机时间(150ms~300ms)后,即向所有其它节点发起选举。
采取随机时间的目的是避免多个Followers同时发起选举,而同时发起选举容易导致所有Candidates都未能获得多数Followers的投票(脑裂,比如各获得了一半的投票,谁也不占多数,导致选举无效需重选),因而延迟随机时间可以提高一次选举的成功性。
4.2. 选举的实现
在Raft中,和选举有关的超时值有两个:
选举超时(Election Timeout) |
Follower等待成为Candidate的时间,为随机时间,随机范围为150ms~250ms。如果在超时之前收到了其它的AppendEntries,则重置选举超时重新计时,否则在选举超时后,Follower成为Candidate,投票给自己(Votes for itself)并发起新的选举任期(Term),发送RequestVote给所有其它节点,以请求投票给自己。如果在这个Term时间内仍然没有获得投票,则重置选举超时,以准备重新发起选举。而一旦获得多数节点的投票,则成为Leader。成为Leader后,定期性的发送AppendEntries给所有Followers,以维持Leader地位。发送AppendEntries的间隔叫作心跳超时。 |
心跳超时(Heartbeat Timeout) |
Follower会应答每一个AppendEntries,一个选举任期(Election Term)会一直存在,直到有新的Follower成为Candidate。Leader节点通过定期发送AppendEntries维护自己的Leader地位,定期的间隔时长即为心跳超时时长。在Raft中,心跳方向是:Leader -> Follower。 |
如果一个Follower在一个Term时间内没有收到AppendEntries(并非要求是来自Leader的AppendEntries,其它Candidates也一样有效),则它成为Candidate,并在等待选举超时(Election Timeout)后发起选举。
要求获得多数节点的投票,可以保证每个任期(Term)内只有一个Leader。如果两个Candidates同时发起选举,则会分割投票,这样需要再重新发起选举。Raft设计“选举超时”,可以降低两个或多个Candidates同时发起选举的概率,减少连续重选举。
Redis的选举有个借鉴意义,在Redis集群中,不同节点可有不同权重,权重大的优先获得发起选举几率。在Redis中,权重是指复制节点数据的新旧程度,而对Raft来说可考虑机架机房等作为权重。
4.3. Term和Lease比较
Raft中的Term可以简单看成Lease(租约),但概念上仍然是有区别的。Lease通常是一个节点向一个中心化节点请求,而Term是无中心化的。
如果没有发生选举超时,则Term的值不会发生变化,否则至少增一。
4.4. 选举图示
每个节点的Term值初始化为1(圆圈中的数字),每个节点选举超时时间为一个150ms~300ms的随机值(实际实现可以调整,但这个值是发明者测试得到的优值,详情请参见两位斯坦福大学教授的论文):
节点S2最先发起选举成为Leader,在发起选举之前,它需要先自增自己的Term值,因此Term值由1变成2,同时其它节点的Term值也需要更新为比自己大的Term值(如果一个Leader遇到一个更大的Term,它需要主动降为Follower):
人工将节点S1和S2停掉,这时两者不可用。这会导致其它正常的节点S3、节点S4和节点S5在选举超时时间内收不到来自Leader的心跳(实为AppendEntry),因此会触发节点S3、节点S4和节点S5发起选举(究竟哪个节点发起选举,视哪个节点最先达到选举超时):
因为节点S2的数据处于未提交状态,因为它的已提交Index值要小于S3和S5,它没有最新的数据,不可能成为新的Leader。新的Leader必然在S3和S5中产生。先强制重置S2的选举超时时长,以让出优先发起选举:
虽然S3和S5均有最新的数据,但因为S3的Term小于S5的Term,因此只有S5才能成为Leader,这样最新的Term值将为5+1为6:
这个时候恢复节点S1,Term值是否会改变?
一个Leader节点,如果遇到比自有更大的Term值,则主动放弃Leader身份,并使用原Term替代自己的Term,然后转变为Candidate重新开始选举。
非Leader节点也是一样的,只要遇到比自己大的Term,都会使用更大的Term替代自己的Term。这样能保证节点均能正常通信时,Leader节点总是持有最大的Term。
4.5. 选举总结
能成为Leader的条件:
1) 有最大的Term;
2) 如果Term相同,则有最大的Index;
3) 如果Term相同,Index也相同,就看谁最先发起;
4) 最先发起者也不一定成为Leader,还得看谁最先获得多数选票。
一个Leader主动放弃Leader条件:
1) 遇到比自己更大的Term,这个时候会转为Follower。
5. Raft日志复制
5.1. 什么是日志复制?
Leader收到一个修改请求后,先将该请求记录到本地日志,这条日志在Raft中叫作Enry,此时处于未提交状态(Uncommitted),然后复制Entry给所有的Followers。当多数Followers节点确认已完成该Entry的写入后,Leader本地提交该Entry,响应客户端成功,这个过程叫日志复制(Log Replication)。如果一个Entry不能复制到多数节点,则该Entry状态一直为未提交,如果发生Leader转换,有可能被覆盖。
5.2. 日志复制的实现
正常的复制不需要理解,主要看异常时的复制处理。让节点S5成为Leader,然后停掉节点S2、S3和S4,然后客户端再请求写操作,但此时由于写操作不能得到多数节点的确认,所以无法提交(不能应用到状态机中):
先停掉节点S1和S5,再恢复节点S2、S3和S4,并让节点S3成为Leader,然后客户端发起一笔写操作。让写操作在三个节点S2、S3和S4中得到确认,这样该笔写操作为已提交状态(Committed),可以看到变成如下状态了。显然节点S1和节点S5上存在了两笔脏数据:
恢复节点S1:
停止节点S3,构造条件让S1成为新的Leader:
\
5.3. 脑裂时的复制
网络分裂时,出现两个Leader:
具有多数节点的一方仍然能够继续,但少数一方已不可用,这个时候从节点B读不到最新的数据:
当网络恢复后,节点B发现更大的Term,自动从Leader将为Follower,同时回滚未提交的Entries,集群又重新实现一致。
6. 概念对比
Raft |
PaxOS (Multi PaxOS) |
ZAB |
PacificA |
Viewstamped Replication |
获得多数同意 |
获得多数同意 |
获得多数同意 |
需所有都同意 |
获得多数同意 |
强Leader(领导),总是包含了最全最新的日志,日志无空洞,随机化简化Leader选举(Redis也采用了这个方法,并且加了节点权重)。 |
Proposer(提议者),允许有多个Proposer,并且不一定最包含了最全最新的日志,日志可存在空洞 |
强Leader(领导) |
Primary(主) |
Primary |
Follower(跟随者) |
Acceptor(接受者) |
Follower(跟随者,参与投票) |
Secondary(副),接收Primary的心跳,一个Primary对多个Secondary |
Backup |
Candidate(候选者) |
Learner(学习者) |
Looking(竞选状态) |
||
Observing(观察者,不参与投票,只同步状态) |
||||
Entry |
达到一致的叫Value(即决议),达到一致前叫提议 |
类似PaxOS |
||
Term(任期) |
Ballot(选票) |
Epoch(纪元),为txid的高32位(注:Redis中也叫Epoch,作用类似) |
View |
|
Index(序号) |
Proposal Number |
txid的低32位 |
Serial Number |
7. 共性探讨
所有的并不是完全孤立的,而是存在很多共性。
7.1. PacificA和HBase和Kafka
PacificA和HBase均依赖于PaxOS这样的设施,HBase依赖于Zookeeper,PacificA同样依赖于类似的配置管理服务。
如同HBase依赖Zookeeper来发现Keys的位置信息,PacificA依赖配置管理服务发现分片的位置。
Kafka其实也类似,早期Kafka直接将位置信息存储在了Zookeeper中,遭遇了Zookeeper吞吐瓶颈,于是采取和HBase类似的做法,将位置信息作为一个特殊的Partition。
7.2. Redis&Raft&ZAB&PaxOS
Redis同Raft、ZAB和PaxOS并不是一类东西,但核心均有Quorum的朴素思想,即服从多数(多数人理解的即为真理),而且均依赖于一个递增的值来达到一致性状态,这个递增的值在Redis和ZAB中叫Epoch,Raft中叫Term。
8. 总结浓缩
8.1. 三种角色
1) Leader(领导者)
2) Follower(跟随者)
3) Candidate(候选人)
8.2. 两种RPC
1) AppendEntry(心跳和写操作)
2) RequestVote(请求投票)
8.3. 两个超时时间
中文名 |
英文名 |
主要问题 |
小技巧 |
选举超时 |
Election Timeout |
选票分裂造成活锁 |
随机时间(Redis非强一致,另加了权重) |
心跳超时 |
Heartbeat Timeout |
不能小于选举超时时长 |
9. 参考
1) https://translate.google.cn
2) https://raft.github.io/raft.pdf
4) http://thesecretlivesofdata.com/raft/
6) 分布式共识(Consensus):Viewstamped Replication、Raft以及Paxos
7) https://static.googleusercontent.com/media/research.google.com/en//archive/paxos_made_live.pdf
Raft协议学习笔记的更多相关文章
- HTTP协议学习笔记(四)
HTTP协议学习笔记(四) 与 HTTP 协作的 Web 服务器 一台 Web 服务器可搭建多个独立域名的 Web 网站,也可作为通信路径上的中转服务器提升传输效率. 1.用单台虚拟主机实现多个域名 ...
- HTTP协议学习笔记(三)
HTTP协议学习笔记(三) 1.状态码告知从服务器端返回的请求结果 状态码的职责是当客户端向服务端向服务端发送请求时,描述返回的请求结果.借助状态码,用户可以知道服务端是正常处理了请求,还是出现了错误 ...
- HTTP协议学习笔记(二)
HTTP协议学习笔记(二) 1.HTTP报文 HTTP报文:用于HTTP协议交互的信息.请求报文:请求端(客户端)的HTTP报文叫做请求报文.响应报文:响应端(服务端)的HTTP报文叫做响应报文. H ...
- HTTP协议学习笔记(一)
HTTP协议学习笔记(一) 1.HTTP协议用于客户端和服务端之间的通信 客户端:请求访问文本或图像等资源的一端服务端:提供资源响应的一端 在两台计算机之间使用HTTP协议通信时,在一条通信线路上必定 ...
- 分布式协议学习笔记(一) Raft 选举
Raft官网 官方可视化动画1 官方可视化动画2 论文中文翻译 论文英文地址 感觉作为paxos的升级精简版 Raft在设计之初就以容易理解为目标 看完资料 脑海里都有了大概的轮廓. 有了这些详细的资 ...
- 分布式协议学习笔记(三) Raft 选举自编写代码练习
由于时间安排上的原因,这次的代码写的稍微有些简略,只能算是自己对RAFT协议的一个巩固. 实现定义2个节点,使用读取配置文件来获取IP和端口以及节点ID 网络使用boost同步流程 一个线程收 一个线 ...
- TCP/IP协议学习笔记
计算机网络基础知识复习汇总:计算机网络基础知识复习 HTTP协议的解析:剖析 HTTP 协议 一个系列的解析文章: TCP/IP详解学习笔记(1)-- 概述 TCP/IP详解学习笔记(2)-- 数据链 ...
- RSA算法、SSL协议学习笔记
最近学习计算机网络,涉及到SSL协议,我想起了去年密码学课程讲过的非对称加密RSA算法,结合阮老师的博客,写写学习笔记,这里再回忆一下. RSA算法 RSA算法是一种非对称密码算法,所谓非对称,就是指 ...
- 网络协议学习笔记(二)物理层到MAC层,交换机和VLAN,ICMP与ping原理
概述 之前网络学习笔记主要讲解了IP的诞生,或者说整个操作系统的诞生,一旦有了IP,就可以在网络的环境里和其他的机器展开沟通了.现在开始给大家讲解关于网络底层的相关知识. 从物理层到MAC层:如何在宿 ...
随机推荐
- BadgeView 圆形数字提醒 购物车常用
实际上BadgeView这个类就是继承TextView的.很多TextView中设置字体的方法都适用于BadgeView. 1. setTargetView(View) --> 设置哪个控件显示 ...
- hdu 3368 曾经下过的棋
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3368 就是讲一种下棋的方法,很多人小时候也应该玩过,输入8*8的矩阵代表棋盘,*代表空位 D代表黑子, ...
- 778A String Game
A. String Game time limit per test 2 seconds memory limit per test 512 megabytes input standard inpu ...
- iOS.FileSystem.HardLinkAndSymbolicLink
关于iOS中的硬连接和符号连接(软连接),iOS其实是Unix的变体, 所以在这方面也继承了Unix的特性,下面这个连接比较详细的进行了 类比说明. 1. http://www.tanhao.me/p ...
- ok,机房小感
难得一次能早来机房,趁今天考完试没啥事,随便写两句牢骚. 学习与编程 老师曾经在招生的时候认真讨论过这个问题,这两者彼此协调并不是一件容易事,很明显,编程是一门大课.它虽然与理科有一定联系,但不代表它 ...
- pycharm 创建文件时,自动添加文件头注释
File->settings->Editor->File and Code Templates->Python Script # -*- coding: utf-8 -*- & ...
- 20岁的设计师vs30岁的设计师
20岁的设计师vs30岁的设计师 如果你还是20来岁,要恭喜你,你还年轻, 一切才刚刚开始 还有时间去探索无尽的可能 还有时间去找到无限的前途 如果30岁的你还不够强大, 请记得时刻给予自己信心, ...
- 在linux虚拟机上安装Docker
1.简介Docker是一个开源的应用容器引擎:是一个轻量级容器技术: Docker支持将软件编译成一个镜像:然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像: 运行中的这个 ...
- js中将斜杠\替换的方法
js中将/替换的方法replace(/\//g, '-') 中间涉及到js的一些转义问题,试了几个方法,发现这个可以,就记下来.
- ContactDetail 和 ContactEditor 界面头像响应点击过程
1,联系人详情界面 ContactDetailFragment中处理,ViewAdapter装载数据显示头像 private final class ViewAdapter extends BaseA ...