【Raft】分布式一致性算法Raft和zab、paxos
目录
前言
开发面试Zookeeper肯定要问,Zab协议逃不掉,那么和 Raft 的区别和联系肯定也逃不掉。
Paxos知名分布式系统ceph的monitor集群使用的算法 太复杂了面试官自己也搞不懂,所以没必要深究。
Raft算法
Raft动画教程
http://thesecretlivesofdata.com/raft/ (带中文翻译:理解Raft分布式共识算法https://www.bilibili.com/video/BV1yJ411P76f?from=search&seid=8328232223355833905)
下图:各个节点的同步情况,实际上4节点目前远远落后于其他节点,而1-3-5节点的前7次log已经完成提交了,因为得到了超过半数节点的确认。(讲解:raft internal vs zab---https://www.bilibili.com/video/BV1Zz411i7Rr?from=search&seid=674793516552630434)
Raft手动设置模拟
主页:
peng-xin/raftscope: super hacky visualization of Raft --https://github.com/peng-xin/raftscope
用git命令下载下面的web项目后,直接点击打开index.html
git clone https://github.com/peng-xin/raftscope.git
Raft协议说明
多个节点的一致性
node有三个状态follower,candidate,leader,开始状态为follower,follower没有收到leader信息时可以变成candidate状态,candidate会发送投票给其他节点,其他节点返回相应,会变成leader状态,这个过程称为Leader选举。
所有的修改都是通过leader进行,当leader接收到修改的内容时,会作为Entry存储在log中,现在处于uncommit状态,leader发送给其他节点这个改变,只要多于一般的节点回复了,leader节点就更改本身设置的值,提交commit命令修改状态,这个过程称为日志复制。
Leader选举
leader选举有两个超时,一个选举超时,选举超时随机设置150-300ms,超时后,follower会变成candidate状态,发送请求投票给其他节点,其他节点没有发送请求投票就会投同意票,同时重置选举超时时间,candidate节点获得过半数票就会成为leader节点。leader会发送Append Entries消息给其他follower,消息发送在心跳超时前,follower会回复消息,这种情况会保持到follower停止接收心跳消息变成candidate结束。停止leader节点后,follower等待选举超时会变成candidate请求成为leader节点。过半的原则能够保证集群中有一个leader,如果多个节点同时获取相同选票,那么进入新一轮选举。
Log复制
客户端发送更改请求到leader,leader会添加到日志中,下一个心跳会发送给其他follower,过半节点应答了,leader会committed这个更改,同时回复给客户端。当有网络隔离造成集群分隔成两个集群时,会生成两个leader,分别接受更改的请求,但是由于需要过半同意才会提交更改,所以集群节点不过半的小集群没办法更改结果。如果这时候网络隔离消失了,集群节点通了,两个leader中term低的会自动停下,未提交的更改会回退回去,同步新的leader日志。
疑问?如果term低的是个大集群,然后提交了更改,然后网络通了,term低的leader停下,同步新leader的数据,原来提交的数据会同步过去吗?
链接:https://www.jianshu.com/p/5b59869d6273
Raft和zab区别
共同点:
- 都是共识算法,写数据时都需要大部分成功才能把日志应用到状态机。
- 都有选主、日志对齐、数据广播的流程。
- 都把数据分成快照+日志。
- 都使用timeout来重新选择leader.
- 采用quorum(法定人数)来确定整个系统的一致性(也就是对某一个值的认可),这个quorum一般实现是集群中半数以上的服务器,zookeeper里还提供了带权重的quorum实现.
- 都由leader来发起写操作.
- 都采用心跳检测存活性。
- zookeeper的zab实现里选主要求选出来的主拥有quorum里最新的历史,而raft的follower的选主投票根据term的大小+日志完成度来选择投票给谁,这点上来看是比较类似的。
链接:https://www.zhihu.com/question/28242561/answer/40075530
不同点:
- zab用的是epoch(时代; 纪元)和count的组合来唯一表示一个值, 而raft用的是term和index。
- raft协议数据只有单向地从leader到follower(成为leader的条件之一就是拥有最新的log), 而zab的zookeeper实现中 ,一个prospective leader需要将自己的log更新为quorum里面最新的log,然后才好在synchronization阶段将quorum里的其他机器的log都同步到一致.(prospective :有望的; 可能的; 预期的; 潜在的)
BTW, raft实现起来比zab会简单很多.
链接:https://www.zhihu.com/question/28242561/answer/40075530
- ZAB协议好像本身并没有实现配置变更的算法,而在raft论文中是明确提出相关算法的。这并不是说ZAB协议就不能实现,只能说原生的ZAB协议没有说明这一点。(凭印象)这也导致了ZooKeeper直到最近一两年才释出稳定版的可以支持动态配置更新的版本3.5。
paxos算法----编辑中
白话讲解paxos&raft算法原理及实战_https://www.bilibili.com/video/BV19t411c75p?p=2
Paxos算法解决的问题正是分布式一致性问题,即一个分布式系统中的各个进程如何就某个值(决议)达成一致。
Paxos算法背景
Paxos算法是一种基于消息传递的分布式一致性算法。
Paxos算法流程
Paxos算法运行在允许宕机故障的异步系统中,不要求可靠的消息传递,可容忍消息丢失、延迟、乱序以及重复。它利用大多数 (Majority) 机制保证了2F+1的容错能力,即2F+1个节点的系统最多允许F个节点同时出现故障。
一个或多个提议进程 (Proposer) 可以发起提案 (Proposal),Paxos算法使所有提案中的某一个提案,在所有进程中达成一致。系统中的多数派同时认可该提案,即达成了一致。最多只针对一个确定的提案达成一致。
Paxos将系统中的角色分为提议者 (Proposer),决策者 (Acceptor),和最终决策学习者 (Learner):
- Proposer: 提出提案 (Proposal)。Proposal信息包括提案编号 (Proposal ID) 和提议的值 (Value)。
- Acceptor:参与决策,回应Proposers的提案。收到Proposal后可以接受提案,若Proposal获得多数Acceptors的接受,则称该Proposal被批准。
- Learner:不参与决策,从Proposers/Acceptors学习最新达成一致的提案(Value)。
在多副本状态机中,每个副本同时具有Proposer、Acceptor、Learner三种角色。
Neat Algorithms - Paxos -http://harry.me/blog/2014/12/27/neat-algorithms-paxos/
这篇文章里面有用JS写的Paxos过程,有助理解。但是没怎么仔细看,没时间。
这篇文章用两军问题来讨论Paxos,也很有意思:
http://iunknown.iteye.com/blog/2246484
在计算机通信理论中,有一个著名的两军问题(two-army problem),讲述通信的双方通过ACK来达成共识,永远会有一个在途的ACK需要进行确认,因此无法达成共识。
(注意:两军问题是无解的。Paxos只是达成共识,涉及ack和行动,仍然是无解)
【转载】两军问题与Paxos算法 & 动画讲解Paxos算法 - https://www.cnblogs.com/charlesblc/p/6037963.html