范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

深入浅出一文搞懂分布式一致性算法新贵Raft协议

  前言
  在分布式的世界里,要说最核心最复杂的功能,一致性地实现无出其右,之前的paxos算法堪称经典,被认为是同类算法中效果最好的,基本上成为分布式一致性的代名词,但是paxos算法也是出了名的难理解,而且相当不好实现。本人也花了很多时间、看了很多材料也没有真正理解。所以基于paxos的思想进行的一致性算法的简化和实现就成为了现实的需求,在此背景下,本文的主角Raft就出现了。
  Raft算法的头号目标就是容易理解(UnderStandable),这从论文中就可以看出来。当然,Raft增强了可理解性,在性能、可靠性、可用性方面是不输于Paxos的。建议大家拜读下作者的论文 Raft论文,下面将详细说明raft的思想以及实现的过程 正文
  raft为了实现容易理解的目标,在paxos的基础上进行的状态简化以及问题拆分,将之前复杂的逻辑拆成若干个子问题,基本上可以总结成下面几个方面: leader election:选取主节点 log replication:日志备份,数据同步 safety:为了实现上述两点而产生的一些约束条件和保障条件 leader electionrole
  首先先说明下Raft算法中节点的角色,分为以下三种: leader:由所有节点选举,在candidate中产生,负责整个集群的状态以及元数据管理,当发现更大的term时,转化为follower candidate:由follower在集群选举时转化而成,选举时得到多数选票,则转化为leader,若发现主节点或者更大的term则转化为follower follower:集群初始化时所有节点的角色都是follower,若未发现leader心跳,则发起leader选举,并将角色转化为candidate;leader以及candidate在某些条件下也会转化成follower
  给出状态机,协助大家理解:
  role
  上面在讲解role的时候好几次说到了一个名词term,这是raft算法中的一个核心概念,很多的机制都需要依赖term。term通俗来讲就是任期,即一个leader正常工作的时间段,如果因为某些原因当前的leader不再是leader时,则该term结束,重新进行选举,开始新的任期,是不是和现实生活中的选举很像?
  另外term在raft算法中也起到了逻辑时钟的作用,在raft的实现中起到了重要的作用,此处用一句话先来概括:即term大的优先级高,leader必须是拥有更大的term。用白话理解:就是当前总统和前总统的关系,总统只能有一个就是当期总统,前总统在当前总统面前就变成选民了。在Raft中,term是个整数型的值,term变化即将term的值加1 leader election process
  下面就来说说leader选举的详细过程,从上面的状态机可以看出,集群初始化时,大家都是follower,当未发现leader心跳并超时后,则follower变成candidate,并发起leader election。每个candidate的动作如下: 给自己投一票 向其他节点发起RequestVote RPC来进行拉票 等待其他节点的响应
  在此过程中会出现三种情况: 该candidate收到了多数(majority)的选票当选了leader,并发送leader心跳告知其他节点,其他节点全部变成follower,集群选主成功 该candidate收到了其他节点发来的leader心跳,说明主节点已经选举成功,该candidate变成follower,集群选主成功 一段时间内(election timeout),该candidate未收到超过半数的选票,也未收到leader心跳,则说明该轮选主失败,重复进行leader election,直到选主成功
  上述情况的产生需要满足下面几个约束: 在每个任期中每个人只能投出一票:注意是每个任期,任期变了(准确的说法是任期增加了)就可以重新投票 投票的规则:candidate肯定投给自己,follower是先到先得 当选leader的条件是得到多数(N/2+1)选票:此处的多数选票是为了避免脑裂而出现多leader的情况而进行的约束,保证了整个集群中leader的唯一性 leader的消息是最新的(其实就是term最大,index也是最大的,后面的log replication模块进行详细分析)
  上面的前两种情况比较容易理解,我们重点来说说第三中情况,用一个比较形象的例子来说明选举过程:
  有五个小伙伴要选取一个组长,选举过程如下:
  注:F,C,L分别对应的是follower,candidate和leader角色,在本例中就是组员,候选人和组长;名字是用来区分节点的标识;而括号中的数字则代表着term的值
  初始状态大家都是组员,等待组长联系自己 等待一段时间后(leader heartbeat timeout),昌坦,继东和呈祥发现没有组长或者组长掉线了,这三个人就变成了候选人,然后发起了组长选举的流程 选举开始后,三个候选人都将自己的任期加1变成了2,然后投了自己一票,而组员晓通选了昌坦,组员溪泽选了呈祥,三个候选人的票数比是2:1:2,未能达到法定的半数以上的多数票,未能选出组长 漫长的等待后(election timeout),昌坦发现自己没有获得多数选票,也没有收到其他候选人当选组长的消息(leader heartbeat),意识到了此次选举失败,然后将自己的任期加1变成3,再次发起选举,组员晓通和溪泽发现该任期中未投票 ,先到先得,直接投给了昌坦,而候选人继东和呈祥发现昌坦的任期比自己大,则放弃候选人的角色变成了组员并投票给昌坦(此处从候选人变成组员也可能是收到了昌坦当选组长的消息后转变的,因为组长的当选并不需要全票,只要达到多数选票即可) 昌坦全票当选组长,并向其他组员通报了自己成为组长的消息,后续所有的组内管理以及消息同步都通过组长昌坦向其他组员传达
  整个leader election流程就是这样,是不是很好理解,基本上符合现实生活中的理解。但是上述的流程可能有一个问题,分为以下两种情况: 如果在第三阶段三个候选人同时发现选举未成功,同时发起二次选举,而恰好昌坦和晓通的关系很好,呈祥和溪泽的关系很好(关系好可以理解为网络近,优先到达,优先获得投票),则可能出现多次2:1:2,无法达到多数(majority)的情况 如果当前的组员不是5个人,而是4个人或者6个人,而候选人是2个,则会出现2:2或者3:3的情况,无法达到多数(majority)的情况
  上述的两种情况会影响到leader election的成功率和效率,在设计中应该被规避,面对这两种情况,Raft给出了自己的解决方案: 节点数尽量是奇数个,尽量保证majority的产生 每个candidate的election timeout时间在某一个时间段内随机,如150ms-300ms,这样能最大程度上避免同时再次发起选举的概率,某个candidate可以率先发现election timeout然后增加term并重新发起选举,大概率能获得多数选票而当选,另外每一次选举每个candidate都会刷新election timeout,来保证majority的产生 leader election
  当系统有了leader后,系统就进入对外工作期了。客户端的一切请求来发送到leader,leader来调度这些并发请求的顺序,并且保证leader与followers状态的一致性。raft中的做法是,将这些请求以及执行顺序告知followers。leader和followers以相同的顺序来执行这些请求,保证状态一致。
  下图就是请求写入处理的相关流程:
  客户端向leader提交写入请求 leader接收到客户端请求后封装RPC并行将修改发送到follower follower在接收到leader发送的RPC后,回复leader已经收到该请求 在leader接收到多数(majority,含leader)follower的回复后,回复客户端接收成功,将变更状态设置为commited,然后将变更写入到状态机,此时写入实际上已经生效,无法回滚 leader与follower通信,协助follower完成变更的提交,当变更提交完毕后,follower会将变更写入到状态机,此时变更才真正的影响到节点,此时的状态可以理解为applied。此过程中,可能会出现各种问题,比如说网络连接超时,命令执行不成功等问题,leader会持续和follower进行通信,保证follower最终完成所有的操作,与leader达成最终一致性。这种最终一致性是对内的,对外部的client的透明的,外部的client只会看到leader上状态的强一致性。这种强一致性和最终一致性的配合使用,不仅降低了一致性实现的各种成本,还保证了系统的健壮性,能保证在各种异常情况下的恢复与状态同步。
  上述流程中,有点类似于两阶段提交(2PC),这种提交方式的好处就是能简化分布式事务的复杂性,在不直接使用分布式锁的前提下,能最大程度保证分布式事务的实现。但是这里和标准的2PC还是有差别的,差别就是这里leader只需要多数(majority)的follower答复即可,那么在这种情况下,raft是怎么保证一致性以及数据的完整性,尤其在集群主节点发生故障的时候呢?此处先留下这个问题,后续在safety模块进行解答
  最后看下log长什么样子吧:
  log由三部分组成: 序号:代表着命令的执行顺序,leader将命令按顺序发给follower,follower按顺序执行命令,保证数据的一致性 term值:将命令按term进行划分,每个命令都属于一个term 操作命令:真正执行和影响节点状态的命令
  log为了配合raft实现leader选举以及状态同步,需要具备某些特性 ,满足相关的约束: 回到上文的问题,leader选举的时候要保证leader上的log是最新的,那最新的概念是什么?这里解答下:log最新的概念就是term是最大的且index也是最大的,如图中的leader,term是4,index是7,都是最大的 从初始状态为空开始,leader将客户端请求(command)封装到一个个log entry,将这些log entries复制(replicate)到所有follower节点,然后大家按相同顺序应用(apply)log entry中的command,则状态肯定是一致的。 log是append only的file,对于已经committed的命令,log只会新增,不会修改和删除,这也带来了另外一个特性,就是如果两个不同节点在同一位置的日志相同,那么在此位置之前的所有的值都相同 只有leader的发送的log entry被多数(majority)的节点(包含leader)接收并响应,才会被标识为committed safety
  上面大部分说的都是正常情况下raft是怎么工作和运行的,但是一个分布式不仅需要在正常情况下能稳定高效的运行,也需要在任何情况下,系统都不能出现不可逆的错误,也不能向客户端返回错误的内容。raft也是如此,上面两个章节已经说明了为了达到safety目标raft所采取的一些策略和约束,下面就来以几个典型场景来说明下raft是怎样容错的。 follower crash
  follower crash处理起来相对简单,只要重新上线加入集群后 ,发现了已经存在的leader,直接加入集群并且接收来自leader的消息,然后在leader的指导下完成数据和状态的同步,在此过程中,leader与follower通信使用的是AppendEntries RPC,借用官方的结构图:
  另外,每个节点上的日志都是通过状态机(State Machine)进行管理的,节点上applied的command会提交到状态机进行保存,用于后续节点(leader-follower)之间进行数据和状态同步,下面是状态机中状态相关的结构图:
  从上图可以看出对于每个follower,leader保持2个属性,一个就是nextIndex即leader要发给该follower的下一个entry的index,另一个就是matchIndex即follower发给leader的确认index。
  实现过程如下:
  leader当选成功后,会进行部分属性的初始化: nextIndex=leader的log的最大index+1 matchIndex=0
  然后开始准备AppendEntries RPC请求的参数: prevLogIndex=nextIndex-1 prevLogTerm=从log中得到prevLogIndex对应的term
  初始化entries数组: 初始化以及成功当选的第一次心跳的时候是空 后续的值是从本地log中取prevLogIndex+1到最后的所有log entry
  最后是leaderCommit赋值: leaderCommit=leader上的commit indexentry
  至此,所有参数准备完毕,发送RPC请求到所有的follower,follower再接收到这样的请求之后,处理如下: 重置HeartbeatTimeout 检查传过来的请求term和当前follower的term,如果当前term大于master的term,则返回false 检查prevLogIndex和prevLogTerm和当前follower的对应index的log是否一致。检查的方法就是follower在prevLogIndex这里是不是有entry,如果有的话,term的值和prevLogTerm是否一致。这里可能就是不一致的,因为初始prevLogIndex和prevLogTerm是leader上log的lastLog,因为网络等原因,可能还未同步到这个index,如果不一致的话返回false,同时将该follower上log的lastIndex传送给leader leader接收到上述false之后,会记录该follower的上述lastIndex nextIndex=follower传回来的index+1 matchIndex=follower传回来的index 然后leader会从新按照上述规则,发送新的prevLogIndex、prevLogTerm、和entries数组 nextIndex=follower传回来的index+1 matchIndex=follower传回来的index prevLogIndex=follower传回来的index prevLogTerm=从log中得到上述prevLogIndex对应的term entry[]=从本地log中取prevLogIndex+1到最后的所有log entry leaderCommit=leader上的commit index follower检查prevLogIndex和prevLogTerm和对应index的log是否一致(目前一致了) 然后follower就开始将entries中的数据全部覆盖到本地对应的index上,如果没有则算是添加如果有则算是更新,也就是说和leader的保持一致 最后follower将最后复制的index发给leader,同时返回ok,leader会像上述一样来更新follower的macthIndex leader crash
  leader crash相对来说比较复杂,需要针对几个固定场景进行具体分析,详细参考这篇文章: Leader节点的一致性保障 leader与follower同步数据
  在集群出现异常重新选取leader后都需要面临数据同步的问题,下面这张图列举了集中场景:
  上面列举了6钟follower可能存在的状态,前两种follower的数据比leader少,中间两种follower数据比leader多,最后两种leader和follower数据有多有少。这里需要注意一下:
  图中的虚线框代表着uncommitted的log entry;
  另外,此时leader的term是8(如果这7个节点是一个集群的话),后续分析中这一点很重要。
  具体分析下上述几种场景中follower状态产生的原因: 第一种情况比较常见,follower和leader在同一term,就少一个index,这是client刚将数据写入到leader,leader正常将该数据同步到follower即可 第二种情况是follower在term 4就crash或者网络中断了,在term 6重新恢复,此时leader只要通过AppendEntries RPC正常同步即可。 第三种情况产生的原因是该follower在term 6的时候是leader,在写入第三个值的时候,还没来得及同步给follower,自己就crash或者网络中断了,所以最后一个log entry处于uncommitted的状态 第四种情况产生的原因是该follower在term 7的时候是leader,刚当选leader并通知其他follower后就网络中断了,自己处于一个局域网中,在client端写入两个值后,无法同步给follower,所以最后两个log entry处于uncommitted的状态 第五种情况产生的原因是该follower在term 4的时候是leader,刚当选leader并通知其他follower后,写入了两个值同步给follower并commit后就网络中断了,自己处于一个局域网中,在client端继续写入两个值后,无法同步给follower,所以最后两个log entry处于uncommitted的状态 第六种情况产生的原因是该follower在term 2的时候是leader,刚当选leader并通知其他follower后就网络中断了,自己处于一个局域网中,在client端写入三个值后,无法同步给follower,所以term 2的三个log entry处于uncommitted的状态;此时网络突然恢复,进入了term 3,在该term中,该follower参加leader选举又被选为leader,刚当选leader并通知其他follower后就网络中断了,自己处于一个局域网中,在client端写入三个值后,无法同步给follower,所以term 3的三个log entry处于uncommitted的状态
  上面的几种情况虽然不太具备现实意义,但是还是对于我们理解整个raft的各种机制有很大的帮助,建议大家好好梳理下,肯定会有收获的。
  针对上面的所有情况,处理方式就就是,leader选举时所有的uncommitted的log entry都会回滚(所以图中所有的uncommitted的log entry其实在term 8 leader选举后就不存在了,此处画出来仅仅是为了方便大家理解整个数据和状态的演变过程),然后当出现了leader与follower不一致的情况,leader强制follower复制自己的log,复制的过程参加follower crash这一章节 raft算法如何保证leader的数据永远是最新的且不会丢数据
  这个问题其实是由上面的几个majority以及几个约束共同来完成的: majoritycommit majority:一条消息只有变成committed状态才被认为已经提交成功,而committed状态的前提是该消息已经同步到了majority的节点 vote majority:某个candidate当选leader的条件就是该candidate获得到了majori节点的选票 约束leader当选的条件是log是最新的
  综上,commit majority代表着最新数据的持有;而vote majority代表着最后的leader会从这里面产生(candidate肯定会投自己的票,所以也在vote majority之中),而这两个majority肯定会有1到(N/2+1)个节点是重复的,也就是这些节点既有最新的数据,也有机会成为leader,再看那个约束条件,这个约束条件将vote majority中不具有最新数据的那些节点排除,那么最后的leader节点一定会在两个majority重复的节点中产生,而这些节点持有最新的数据,保证了leader的数据永远是最新的且不会丢数据。
  raft与其他协议(Viewstamped Replication、mongodb)不同,raft始终保证leader包含最新的已提交的日志,因此leader不会从follower catchup日志,这也大大简化了系统的复杂度。 总结
  raft将一致性问题分解成两个相对独立的问题,leader election,log replication。流程是先选举出leader,然后leader负责复制、提交log(log中包含command),为了在任何异常情况下系统不出错,即满足safety属性,对leader election,log replication两个子问题有诸多约束,在满足功能和性能的基础上,尽量简化模型以及状态,提高了整个算法的易理解性和易实现性,堪称经典且实用的算法。
  想想 Paxos 算法是 Leslie Lamport 在 1990 年就公开发表在了自己的网站上,想想我们是什么时候才听说的?什么时候才有一个可用的实现?而 Raft 算法是 2013 年发表的,现在可以看到有许多不同语言开源的实现库了。而且很多raft-like算法在raft的基础上进行了定制化扩展,用以满足各种系统需求(如elasticsearch 7中的集群协调子系统中定制化raft的实现),这就是易理解性和易实现性的重要性。

穿梭花海,乘风而行,来奉贤潘垫村踏青正当时!为助力全面推进乡村振兴战略,深入实施乡村旅游精品工程,上海市文化旅游局近期开展了第一批市级乡村旅游重点村遴选工作,确定了51个上海市级乡村旅游重点村名单,奉贤区庄行镇浦秀村潘垫村榜游1号公路赏万亩花海,叶县首届乡村电商节暨体育文化节开幕河南日报客户端记者张建新河南日报社全媒体记者王冰珂通讯员焦萌姬冠鹏4月16日,叶县保安镇杨令庄村,骑遇叶县自行车公开赛举行。随着发令枪响,骑手们沿着1号公路,向常村镇孤石滩水库飞驰下周上班时间有变!小伙伴们是不是已经在期待五一假期的到来了呢?但是有个重要提醒哦下周上班时间有变!4月23日(下周日)要!上!班!要!上!班!五一劳动节假期连休5天今年劳动节4月29日至5月3日放假万名青年随手拍洛阳抖音话题播放量突破7000万,总冠名仰韶酒业厚礼谢粉丝大河报豫视频记者李晓波目前,由中共洛阳市委网信办共青团洛阳市委员会河南日报社洛阳分社共同主办,大河报豫视频洛阳运营中心洛阳公益顺风车协会承办的万名青年随手拍洛阳抖音话题播放量突破7吴川一家庭农场上榜农场的小路边种满鲜花。受访者供图吴川市聚龙家庭农场池塘。受访者供图近日,广东省农业农村厅广东省文化和旅游厅发布关于公布2022年度省级休闲农业与乡村旅游示范单位名单的通知,经主体申如果想要自驾游,什么车比较合适,不知道的一定要点进来如果想要自驾游开什么车最靠谱,其实主要还是在于去哪里旅行,其次要去什么标准的旅行因为不同的需求会导致不同的车辆,如果规划的路线上铺满了道路,那么任何车辆都可以完成这项工作但是相反的特种兵式旅游火了!花最少的钱,废最快的腿!利用周末或小长假,用尽可能少的预算,玩最多的景点吃最多的美食,这种被称为特种兵式旅游的游玩方式,最近在年轻人特别是大学生中流行起来。小陆是广西南宁某大学的一名在校生,她最近就和外地主打的就是极限挑战!特种兵式旅游火了来源人民网天安门升旗看了,景山公园登高望远了,故宫角楼拍了,东交民巷到了,大栅栏前门瞧了,天坛祈年殿去了这是一名年轻人在一天时间内刷的景点。日行数万步,花最少的时间和费用游览最多的爆赞,赴甘入境首团已至敦煌!中国旅游业在这个春天走上稳步复苏的新通道旅游业三大市场中,国内旅游和出境旅游复苏相对较快,入境旅游的重启之路也已开启。赴甘入境首团!由澳门城市大学组织的艺术学博士学术考察交流团一行按图索冀春回大地万鸟归河北日报客户端春风至候鸟归近日在秦皇岛市北戴河大批回迁候鸟如约而至形成万鸟临海的壮观场面这些候鸟时而在浅滩觅食时而凌空翱翔时而结伴嬉戏吸引大量游人前来观鸟游玩北戴河海滨是驰名中外的我在漳河等你系列三到京河农家来做客吧从岩子河沿荆马线路过仙女村,再过仙女水库,转弯上坡后向左拐,进入新修的环库路(环漳河水库路),再往前就进入京河村了。京河村地处漳河东边,境内有五条自北向南低滑的大山岗,当地人俗称五
永恒岛手游春日焕新,趣味玩法哈喽。大家好,我是柠檬,永恒岛这款手游已经上线有一段时间了,热度还是居高不下的,有童年的那个味道了!!!这是一款复古版彩虹岛手游,游戏采用童话般画质风格,有丰富的剧情体验还有世界线骁龙8gen1高性价比亲民旗舰,从3999元跌至2799元,闭眼入一般来说,中档价位手机一定会有某个方面的缺点,需要消费者去权衡哪个方面是可以接受的,而RedmiK50至尊版打破了这一局面,它没有明显的短板,降价后更可以说是这个价位手机的性价比之数据驱动睡眠新革命,慕思引领健康睡眠行业新发展每年321世界睡眠日前后,各类睡眠白皮书调研报告扑面而来,各家企业从不同视角出发,调研不同群体的睡眠状况。在此之前,慕思也连续11年发布健康睡眠白皮书,围绕企业家中产阶级青年网民儿科大讯飞智能办公本不断推陈出新,打工人懂我!编辑虞尔湖出品潮起网于见专栏这几年,伴随着协同办公软件的普及。智能办公本也如同一个新概念,不断刷新人们的认知。2022年5月中旬,以专业,轻而易写为主题的2022年科大讯飞智能办公谷歌PixelWatch智能手表推送3月固件更新IT之家3月23日消息,谷歌通常会在每个月的第一个星期一向其设备发送月度更新,但3月的更新延迟了。现在,PixelWatch的3月重大更新终于发布了。本次更新后支持跌倒检测。智能手本科获完美世界阿里巴巴offer,他说逐风,趁年轻!星光闪烁,实验室里注入希望余音袅袅,展播厅内传递梦想翩翩起舞,赛场见证他的成长耀眼光芒,职场吹奏鼓舞号角今天,让我们一起走进逐风少年秦子康秦子康信息科学技术学院软件工程2019级本诏安公路分中心篱笆围挡占用公路用地,拆!海峡导报新福建客户端3月23日讯(通讯员黄小莹文图记者刘龙)为深入推进G228线滨海旅游风景道建设,诏安公路分中心联合县交通综合执法大队协同开展G228线滨海旅游风景道路域环境整治最强对手非邱贻可?马琳执教遭遇挑战,王曼昱新恩师被刘国梁认可头条创作挑战赛如何看待马琳的执教水平呢?目前中国乒乓球队正在备战四月份的新乡冠军赛,国乒女队再次受到关注。因为在刚结束的新加坡WTT大满贯赛上,国乒女队虽然表现强势,不仅夺得最终的40年前,大爷在供销社100多买了10瓶茅台,如今竟能在北京换套房40年前,大爷在供销社100多买了10瓶茅台,如今竟能在北京换套房最近大家关于物价的谈论也是不绝于耳,经历三年的疫情,感觉很多事情都变了,最近也是让很多人都怀念起过去,家住北京胡同国际乒联公布2023年第12周世界排名,龙胖对决仍是最强对决!2023年第24篇作者杨磊01实力决定一切天上不会掉馅饼,比赛结果不说谎,走到后面的都是强者。我们来看一下进入2023年WTT新加坡大满贯赛男单前十六强的选手名单冠军樊振东亚军马龙全球顶级迪拜七星酒店没有之一,最贵的皇家套房长期被中国人霸占近日,英国记者应酒店之邀,揭开世界顶级豪华酒店的神秘面纱。这套复式皇家套房可谓金碧辉煌。楼梯上铺着豹纹地毯,走在这样的房间里很容易忘记自己的身份。8,395平方英尺的皇家套房专为皇