zoukankan      html  css  js  c++  java
  • Raft选举算法

    目标:分布式集群中,选举Leader,保持数据一致性
     
    集群中每个节点都有三种状态:
    1. Follower:纯小弟
    2. Candidate:候选人。我原来是小弟,但我现在想当老大
    3. Leader:老大
    集群状态:
    1. 有明确的老大(稳定状态)
    2. 没有老大,选举中
    有老大的状态:
    Follower内有倒计时(150ms~300ms)。Leader定期(例如50ms)给follower发心跳消息(广播告诉小弟:老大还活着,所有人继续当小弟)。小弟收到心跳后,重置倒计时器。
    所有节点内,维持一个数据结构(Term2,LeaderA),表示当前是第2任老大,老大是A
     
    一旦老大挂了:
    此时所有小弟还在倒计时,但是收不到老大的心跳了...
    直到某个小弟B自身倒计时结束,他首先意识到“老大挂了,社团不能没有老大,我最早觉醒的,那么就有我来开启新时代(Term+1)吧“(自身状态为Candidate)。
    于是,B广播给所有小弟(包括已经凉了的A),“大家来选举第3任老大,老大是B”(发送VFM(VoteForMe)消息)。
    其他小弟发现要来到新时代了(Term3>Term2),不管自身倒计时有没有结束,纷纷拥护B作为新老大(返回OK信息,更新自身数据结构:Term3,LeaderB)。
    B收到多数人的投票后,就成为名副其实的新一任的老大(状态:Candidate->Leader)
    B作为老大,定时给所有小弟发送AppendEntries消息(我已经得到权威认证了)
      
    如果两个小弟同时觉醒
    例如B、C。设定,集群为5个节点,A、B、C、D、E,此时,A凉了,B、C同时觉醒相当老大,D、E还是小弟状态(倒计时中)
    那么,B、C会同时向其他节点(B->ACDE,C->ABDE)发送VFM消息(B的VFM消息:Term3,LeaderB;C的VFM消息是Term3,LeaderC)。
    DE收到消息后,会做如下逻辑判断:VFM.Term > this.Term ? OK:不OK。(如果要开启新时代,那么就认新老大。不认旧时代的新老大)
    例如,E先收到C的VFM消息,判断了一下this.Term(2)<VFM.Term(3) 成立,于是更新自身状态(Term3,LeaderC),认C为新老大;
    之后E又收到了B的VFM消息,判断了一下this.Term(3)<VFM.Term(3) 不成立,于是给B回不同意的消息,我在Term3时代不认B做老大。。
     
    此时,集群整体会存在两种情况:
    1. B、C各自收到相等的投票,选举失败状态,例如(B:D同意E反对;C收到:D反对E同意,A凉了)
      1. 那么,B、C各自重新开启一个随机倒计时(Elaction),谁先倒计时完,谁再重新广播VFM请求(例如,C先倒计时结束,则发起新的Vote,Term4,LeaderC)
    2. B、C收到不等的投票,例如(DE选举C,无人选B,A凉了)
      1. 那么,C认为自己是老大,开始对B、D、E广播AppendEntries(我C是老大)。
      2. 虽然B在倒计时等待重新发起Election,但是一旦收到AppendEntries请求,就认为C是老大,自己回到Follower状态
     
    参考:
  • 相关阅读:
    Web的26项基本概念和技术
    StringComparison枚举
    WebDriver使用指南(完整篇)
    Sublime Text 2 入门及技巧
    每天一个 Linux 命令(16):which whereis locate命令
    每天一个 Linux 命令(13):less 命令
    每天一个 Linux 命令(12):more命令
    每天一个linux命令(11):nl命令
    每天一个linux命令(10):cat 命令
    每天一个命令 ls
  • 原文地址:https://www.cnblogs.com/cc299/p/11145889.html
Copyright © 2011-2022 走看看