目录

一 一致性

二 Raft算法

1 leader选举

2 日志复制

3 leader切换时如何保证日志完整性

三 参考文献


一 一致性

一致性是指分布式系统中的多个服务节点,给定一系列操作,在特定协议的保障下,使这些节点对外呈现的状态是一致的,即保证集群中所有服务节点中的数据完全相同并且能够对某个提案达成一致,为什么需要一致性?
1 数据不能存在单个节点(主机)上,否则可能出现单点故障。
2 多个节点(主机)需要保证具有相同的数据。
3 一致性算法就是为了解决上面两个问题。

二 Raft算法

Raft是实现分布式共识的一种算法,主要用来管理日志复制的一致性。它和Paxos的功能是一样,但是相比于Paxos,Raft算法更容易理解、也更容易应用到实际的系统当中。下面用小时候经常玩的过家家来解释raft算法的工作原理,首先会有以下游戏规则,对应raft算法中的一些具体实现规则:
     C1 游戏中,每个小孩子都想做一家之主(谁不想当爸爸呢,叫爸爸),每个人发现当前没有人做爸爸就会主动申请做爸爸,发起投票
     C2 每个人看到有人发起投票时,如果发起人的请求合法就会投赞成票(实际的投票规则会更复杂,这里先做简单假设),当赞成票超过所有成员数的一半时,申请人成功当选爸爸
     C3 爸爸是有任期的,每发起一次投票任期就会累计
     C4 游戏中有三种身份:一家之主爸爸(leader),家庭成员(follower),独立状态(Candidate)(家庭纠纷吵架了,六亲不认这时候需要重新选取新的家长)
     C5 小孩子记性不好,小孩子的记忆在2s-5s之间(选举计时器election timeout 一般设置为 150ms~300ms 之间的随机数),所以一家之主需要不停的告诉其他成员自己是家长(实际上就是leader和follower的心跳),如果家庭成员忘记了谁是爸爸(选举计时器)超时,就会发起新的选举(所以实现中心跳的时间一定要比选举定时器短)。
     C6 游戏中只能有一个爸爸,没有干爸也没有隔壁老王,其他都是家庭成员
     C7 爸爸负责家庭所有的事务处理,成员只负责记笔记(写日志),当爸爸收到事务请求时自己记笔记的同时会广播给成员,成员收到通知自己记录后会给爸爸相应,如果爸爸收到超过一半的相应,则爸爸会则爸爸或通过此事务(commited)
     C8 家庭成员不处理任何外部事务,只处理leader的消息或者投票请求,如果收到外部事务请求会转给爸爸处理
     C9 如果家庭成员在一定的时间内没有收到爸爸自己是爸爸的证明通知(见C5),则家庭成员会认为你不想干了,就会发起新一期的选举,竞选新一期的爸爸
     C10 当某个家庭成员接收到爸爸的证明通知所携带的任期号大于当前节点本身记录的任期号,那么该节点会更新自身记录的任期号,同时会切换为Follower状态并重置远举计时器

1 leader选举

游戏开始时大家默认都是成员的身份,一段时间后,假如成员a先发现一段时间内没有收到爸爸自己是爸爸的证明通知(见C5)了,就会发起当爸爸的请求(切换为Candidate状态)任期为1,其他成员收到投票请求后拿出笔记本一看自己的任期数都是0,都没有投出任期为1的票,所以立马投赞成票(见C2)。当节点a收到超过一半的赞成票后就会在当前任期中切换成爸爸节点,其他节点为成员节点,同时所有的节点都会累加自己任期值。

这里有一种特殊情况,假如2个家庭成员a和b同时发现没有收到爸爸的任职通知,这时候就会同时发起选举,这个时候两个选举请求会分别先后到达其他节点,其他节点第一次该任期收到选举请求投出同意后会累加本地的任期数,当第二个投票请求到来是发现投票请求中携带的任期数已经投过了就会投出拒绝票,此时会出现三种情况
1 a得到超过一半的赞成票而b少于一半,此时a选举成功
2 b得到超过一半的赞成票而a少于一半,此时b选举成功
3 a和b都为获得超过一半的选票,则该任期选举失败,等待下一个成员的选举计时器超时,开启下一任期的选举
     不过这种情况发生的几率并不高,因为提到过 election timeout 是在一个时间区间内取的随机数,并不是一个固定的值(见C5)
     接下来看一下leader节点宕机的情况,假如当前当家长的小孩子A被一个玩具或者一个零食吸引了走了,不干正事了脱离游戏了,此时其他的家庭成员就不会收到来自爸爸的证明通知,那么就会有一个成员B发现有人叛逃了,就会立马发起新以任期的选举请求(见C1),其他成员收到投票请求后拿出笔记本一看选举任期大于当前投出的任期数就会投出赞成票(见C2),此时B就会成为新一任期的爸爸,继续当家做主。当小孩A开小差又想回来玩的时候,会收到节点B是爸爸的通知,该通知中携带的任期号大于节点 A 当前记录的任期号,所以节点 A 会切换成 Follower 状态(见C10)。

最后来看一下由于网络故障导致网络分区的情况,游戏过程中,一群小孩子拉帮结派,只想跟自己想玩的人玩游戏,于是就出现了两个小团体。

当出现这种情况时,成员A的心跳消息只有节点B能收到,而集群中的其他节点收不到,假设分区之前A是爸爸,一段时间过后,组成新团体的C,D和E中会有一个节点发起选举(见C9),这里假设该节点是E,在新团体中只有节点 C、 D 都会投赞成票,加上E自己的一票超过半数,E就会成为新团体中的爸爸,而此时A是另外一个团体中的爸爸,但是E的任期数比A要大。

当网络故障被修复时会如何呢,加入拉帮结派的小朋友玩了一段时间后被老师发现了,一顿批评后重归于好,此时网络分区也就会消失,此时爸爸A发送的爸爸证明会被重新节点 C、 D 、 E 接收到,但是这些心跳消息中携带的 Term 值小于当前 C、 D 、 E 节点的Term 值,会被 C 、 D 、 E 节点忽略:同时,爸爸E发送的心跳消息会被节点 A、 B 接收到,A和B收到
比自己笔记本里记录的任期大的爸爸证明后发现有新爸爸了就会自动切换为家庭成员(follower),因为同一游戏中只能有一个爸爸(见C6)
    这里会有一种特殊情况加入游戏过程中出现了严重的拉帮结派,出现了很多个小团体小组织,导致很多小团体的成员数不足半数,此时这些小组织会出现无法选举出新的爸爸。待一段时间之后,会再次发起新一轮的选举,循环往复,从而导致不断发起选举, Term 号不断增长,直至溢出。在 Raft 协议中对这种情况有一个优化,当某个节点要发起选举之前,需要先进入一个叫作PreVote 的状态,在该状态下,节点会先尝试连接集群中的其他节点,如果能够成功连接到半数以上的节点,才能真正发起新一轮的选举。

2 日志复制

爸爸节点会将将客户端的更新操作以打包成消息(Msg1)发送到集群中所有的成员节点。当成员节点的小本本记下收到的这些消息之后,会向爸爸节点返回相应的响应消息(Msg2)。当爸爸节点在收到半数以上的成员节点的响应消息之后,会对客户端的请求进行应答,接着爸爸节点会提交客户端的更新操作,该过程会再次发送消息(Msg3)到成员节点,通知成员节点该操作己经提交,同时爸爸节点和成员节点也就可以将该操作应用到自己的状态机中。
    每个节点为了保证日志的完整性,小本本上会维护commitlndex和lastApplied 两个值,commitlndex表示的是当前节点接收到爸爸节点已提交通知的日志的最大索引也就是接收到Msg3
通知的最大日志索引,更新commitlndex后本节点就会把对应的日志引用到自己的状态机中,而lastApplied就记录了当前节点应用到自己状态机中最大的索引日志。因此当节点中的
commitlndex值大于lastApplied 值时,会将lastApplied 对应的日志应用到其状态机中并lastApplied加l。
    作为一家之主的爸爸,需要牢记家庭成员的状况,维护nextlndex和matchlndex两个数组,其中nextlndex数组记录了需要发送给每个家庭成员节点的下一条日志的索引值,matchlndex
记录了己经复制给每个家庭成员节点的最大的日志索引值。爸爸节点会发送从nextlndex开始的所有日志到对应的成员和节点,如果对应成员节点返回成功响应,则更新相应该 Follower 节点对应的nextlndex 值和 matchlndex值,如果因为日志不一致返回失败消息,则减少 nextlndex 值重试,直到返回成功为止,如此一来保证成员节点的日志的完整性。

如果爸爸节点宕机导致爸爸节点发生切换,此时新的爸爸节点会把nextlndex和matchlndex重置,nextlndex重置为自身最后一条已提交的日志索引(上面提到的commitlndex),
matchlndex重置为0,新的爸爸节点会从nextlndex开始的所有日志到个个成员和节点,如果对应成员节点发现日志的索引值比自己最后一条提交的索引值大,就会认为自己丢失了一些日志,返回追加失败,爸爸节点收到失败响应后前移对应的nextlndex重试,如果成员节点发现该日志比自己最后一条提交的索引值小就会直接返回成功,爸爸节点收到成功的响应后更新对应的nextlndex和matchlndex后后移nextlndex继续复制日志。

3 leader切换时如何保证日志完整性

回到最开始的leader选举部分(见C2),实际上成员节点首次收到某个节点的选举请求时并不是直接就将选票投给哪个Candidate节点, Follower 节点还需要比较该 Candidate 节点的日志记录与自身的日志记录,如果发起选举节点的日志没有自己的日志新,就会投出拒绝票,确保将选票投给包含了全部己提交(commited)日志记录的 Candidate 节点。这也就保证了己提交的日志记录不会丢失,Candidate 节点为了成为 Leader 节点,必然会在选举过程中向集群中半数以上的节点发送选举请求,因为己提交的日志记录必须存在集群中半数以上的节点中,这也就意味着每一条己提交的日志记录肯定在这些接收到节点中的至少存在一份。

三 参考文献

一文搞懂Raft算法 - xybaby - 博客园

raft流程动画演示

共识算法:Raft - 简书

etcd技术内幕

过家家巧说raft算法相关推荐

  1. 图解:什么是Raft算法?

    导读 在之前的文章<基于SpringCloud的微服务架构演变史?>中我们介绍了分布式注册中心Consul集群中使用了Raft这种分布式一致性算法,那么在这一篇的内容中就给大家详细介绍下什 ...

  2. 分布式系统的Raft算法

    2019独角兽企业重金招聘Python工程师标准>>> 分布式系统的Raft算法 过去, Paxos一直是分布式协议的标准,但是Paxos难于理解,更难以实现,Google的分布式锁 ...

  3. 分布式系统的Raft算法——在失联阶段这个老Leader的任何更新都不能算commit,都回滚,接受新的Leader的新的更新 意味着还是可能丢数据!!!...

    过去, Paxos一直是分布式协议的标准,但是Paxos难于理解,更难以实现,Google的分布式锁系统Chubby作为Paxos实现曾经遭遇到很多坑. 来自Stanford的新的分布式协议研究称为R ...

  4. 一文搞懂Raft算法

    英文解析: 1 follower : 信徒 2 candidate :候选人 3 majority :多数 4 term :术语 5 election :选举 6 leader :领导 7 repli ...

  5. raft算法mysql主从复制_Raft算法赏析

    前言 最近抽空看了大名鼎鼎的Raft算法论文,看完后就一个感觉:如此复杂的算法居然可以设计得如此简洁.巧妙. 反复看了几遍,非常过瘾,原文不仅通俗易懂,而且非常严谨,所有异常情况都做了充分的考虑以及给 ...

  6. 【转】分布式一致性算法:Raft 算法(Raft 论文翻译)

    编者按:这篇文章来自简书的一个位博主Jeffbond,读了好几遍,翻译的质量比较高,原文链接:分布式一致性算法:Raft 算法(Raft 论文翻译),版权一切归原译者. 同时,第6部分的集群成员变更读 ...

  7. Raft算法和开源实现

    CoreOS是一个基于Docker的轻量级容器化Linux发行版,专为大型数据中心而设计,旨在通过轻量的系统架构和灵活的应用程序部署能力简化数据中心的维护成本和复杂度.CoreOS作为Docker生态 ...

  8. raft算法动画演示

    简言 1. 分布式一致性算法,知名的有Paxos,Multi Paxos,Raft 3种算法,其中Raft算法最容易理解 2. 关于Raft算法的原理,可以参考这篇博客:https://blog.cs ...

  9. Raft算法的Leader选举和日志复制过程

    Raft 简介 Raft 是一种为了管理复制日志的一致性算法.它提供了和 Paxos 算法相同的功能和性能,但是它的算法结构和 Paxos 不同,使得Raft 算法更加容易理解并且更容易构建实际的系统 ...

最新文章

  1. 关于命令行窗口输入pip list出错的一些解决办法
  2. shell中的函数及脚本调试方法
  3. 【知识发现】天池平台新浪微博互动预测-ItemCF推荐方法
  4. Fiddler抓取手机APP数据包
  5. 【转】4.3SharePoint服务器端对象模型 之 使用CAML进行数据查询(Part 3)
  6. 广州驾校考试实际道路考试注意事项(图)
  7. 新架构让数据中心犹如PC
  8. 饿了么4年+阿里2年:研发路上的一些总结与思考
  9. 钉钉电脑版如何申请调休 钉钉电脑版申请调休方法
  10. 解决Appium连接报错Could not find ‘apksigner.jar‘
  11. 社会内卷的真正原因:华为内部论坛的这篇短文讲透了
  12. 为什么很多程序员不用switch,而是大量的if……else if?
  13. 特斯拉自动驾驶遭遇中国性价比强敌!纽劢(mài)L3方案发布,成本1万3
  14. [转]ios面试题收集(二)
  15. mdt 计算机名_配置 MDT 部署共享规则
  16. 数据结构试卷(一)及答案
  17. 【黑客编程】手把手教你编写POC
  18. mysql插入表情_向MySQL数据库中插入带emoji表情符的数据时报错
  19. xticklabel 显示下划线_[转载]matlab坐标轴属性及标注
  20. js正则表达式密码校验

热门文章

  1. blob没权限 ie_IE浏览器对象不支持Blob属性或方法,IE浏览器不支持canvas toBlob()方法的Polyfill...
  2. P1506 拯救oibh总部(DFS)
  3. 【QT】QSS美化——主窗体
  4. 计算机应用基础本科类第三阶段机考,网络教育统考计算机应用基础机考要注意什么?...
  5. [转]论青楼女子与游戏策划的异同
  6. mac突然蓝屏进入Recovery模式的解决方案
  7. 新年新形象,2022年试试这么穿
  8. Unity3d基础知识之Texture纹理、Shader着色器、Material材质、Rendering Mode
  9. MPEG简介 + 如何计算 CBR/VBR MP3 的播放时间
  10. 电子科技大学信息门户模拟登录