ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

分布式一致性算法Raft

2021-10-22 01:02:13  阅读:228  来源: 互联网

标签:term 请求 leader follower 投票 一致性 Raft 节点 分布式


参考链接 https://raft.github.io/  可手动调整参数,模拟不同场景 http://thesecretlivesofdata.com/raft/  动态演示 强烈推荐   raft协议解决在分布式系统中的一致性问题,其容错性和性能基本上和Paxos相同,但是其复杂程度,易于理解程度都优于Paxos   raft的角色 raft中有三种角色,分别为 follower-追随者,candidate-候选人,leader-领导者 raft集群中的节点都在这个三个状态中转换,并且同一时刻只能为其中一种角色,     ps,在这三种角色中follower,leader是稳定的角色,即会长期稳定存在的,candidate为临时角色,正常只会存在很短的时间,            正常情况下,一个raft集群只会有一个leader存在,如果存在两个(比如发生网络分区),那么能正常使用的最多也只有一个   raft的选举     两种场景下会触发选举,1)集群刚刚初始化完成,处于初始状态,此时集群节点都处于follower状态,2)原有的leader节点没有及时的给集群的follower节点发送心跳,此时会触发选举机制,follower节点会发现没有接受到leader的心跳,等待一段时间后自身进入candidate状态,这段时间称之为选举超时时间,具体为150ms~300ms的随机时间,     某个follower先超时,那么它自身状态会从follower切换为candidate-选举人,并且1)立即投自已一票(vote for self),2)开始新任期term,如果之前没有term信息,则任期为1,否则为term +1, 3) 向其他所有follower发送 选举请求,请求其他节点投票给自己,如果此candidate获得超过半数的follower的投票,那么他就当选为leader,将自身状态转化为leader     从其他follower角度来看,此follower在等待 选举超时的过程中,收到了其他candidate的选举请求,1)重置选举超时时间,即重新开始等待超时,2)判断选举请求来源的term和自身的term进行对比,如果来源term比自身的大,且未在此term内投过票,则给来源candidate投票。如果收到的选举请求term比自身的term还小,那么显然不用理会。     一些情况的考虑:       1,ABCDE五个节点,其中A目前是leader切宕机,BCDE没有等到A的心跳,认为A已经宕机,由于没有A的心跳也不会重置选举超时时间。一段时间后,B节点timeout,则进入candidate角色,将自身term加1,比如目前为2,并向其他 所有节点 发送投票请求;几乎同时C节点timeout(此时没有收到B节点的投票请求),自身term置为2,进入candidate角色并向其他 所有节点 发送投票请求。     对于DE两个节点而言,先收到谁的投票请求就会给谁投票,这里假设投票给B,那么B节点就有个3张票。超过大多数,成功当选为leader,     对于BC节点而言,他们会收到对方发出的投票请求,且发现来源term和自身一致,但是由于BC节点在进入candidate后就会立即给自己投了一票,所以就不满足 在来源term内没有投票的限制,故不会给 对方投票,符合直观的认知,     ps:是否可以设定为 收到的来源term和自身一致,就不投票呢?我认为应该也行,term的变化一定伴随着投票的操作(我猜的),但可能在更复杂的情况下会有问题,之后在考虑     对于整个集群而言,B成为leader,且term为2,C竞选失败,term为2,此时的还想着再来一次竞选,当然这要等待一个选举超时时间,,但是B已经成为leader了,他会给所有的节点发送心跳,重置所有节点的选举超时时间,(这就是为何要给所有节点发送心跳,而不是给投票给自己的节点发送投票的原因吧),最终实现了集群的一致性         2,在1的基础上,将情况再复杂些。 2.1 现有集群S1~5,S1节点宕机,S4,S3节点timeout,在投票环节各自得到两票,所以这两都没有获得大多数的节点认同,故没有选出leader       2.2 这时S3和S4都发现,有一个节点没有给他们投票,即宕机的S1,所有他们会不停的给S1发送投票请求,期望S1能给自己一票,同时S4,S3自身依然会等待选举超时时间     ps 这个超时时间可能是永久存在的,只有leader的心跳信号可以重置此时间  2.3 接着 S4 首先timeout,此时的动作和之前的一致,自身term加1,并且向其他所有节点发送投票请求,   2.4 这一次,它成功获取大部分节点的投票,成功当选为leader,如果此时S1节点复活,会将自身term置为leader的term,并补全差距的日志(下一节)     3 本次场景为网络分区,导致集群脑裂,如下图所示, 成因:原集群为ABCDE,其中A是leader,发生网络分区导致AB 和DCE网络不同,DCE发生选举,选举E节点为leader(获得DCE三票,达到大多数), 此时clinet有可能访问到这两个leader,其中发送到E的请求正常执行,但是发送到A的请求,由于A节点无法获得大多数节点的认同,请求无法提交,进而导致请求失败,总的来说,集群还是只有一个leader 一段时间后 网络分区恢复,此时AEleader可以与所有节点通信,A节点的请求由于term小于DCE的term,SCE不会认同A的leader地位,而B节点显然会叛变, 对于A节点而言,它会收到另一个leader节点发送的请求,虽然自身也是leader,但由于term小于对方,所以会自动退位,从leader转化为follower。,认同E的leader地位,最后AB会补全和E的差异数据   以上图片来自https://raft.github.io/,非常好用的raft工具,可以自定义各种场景,用于分析     raft的日志   在一个正常运行的集群中,只有leader节点会与外界通信,集群内所有的改变,也是先由leader同步给集群内的其他节点,这时通过使用一种和心跳相同的,称之为 “append entries”的消息完成     1,集群leader S4 接受到client 一个请求,假设为set 2,leader会将请求记录在自己的日志里,注意此时请求并没有执行,只是记录在日志里,类似redolog 值得注意的还有,此时leader已经发送了心跳,其他节点正在返回信息,这时leader接受了clinet的请求,并不会立刻同步给followwe节点,而是等待下一次发送心跳时将请求发送给followe节点   2,下一次心跳中,follower节点接受到 leader的心跳后,发现心跳信号里包含请求,如果follower可以执行该请求,则将请求记录在本地的日志里,然后返回YES ps :如果不能执行呢?是不返回还是返回 NO。个人认为会返回NO,原因是不返回,可能会使得leader确认此请求是否被通过的时间增长,        3 leader收到大多数节点同意的信号后,将commit这个请求,并且返回client,此时对于client而言,请求已经完成,对于leader而言,还需要在下个心跳周期将请求commit的信息发送到follower。follower收到请求后,自身commit请求。最终达到集群一致     raft的学习暂且到这,下一篇将尝试对比下paxos和raft  

标签:term,请求,leader,follower,投票,一致性,Raft,节点,分布式
来源: https://www.cnblogs.com/zzyhogwarts/p/15436927.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有