Leader election

Raft采用心跳机制来触发Leader选举。Leader周期性的发送心跳(如果有正常的RPC的请求情况下可以不发心跳)包保持自己Leader的角色(避免集群中其他节点认为没有Leader而开始选举)。

Follower在收到Leader或者Candidate的RPC请求的情况下一直保持Follower状态。而当一段时间内(election timeout)没有收到请求则认为没有Leader节点而出发选举流程。

选举流程如下:

  1. Follower递增自己的任期并设置为Candidate角色
  2. 投票给自己并且并发的给所有节点发送投票请求
  3. 保持Candidate状态直到:
    • 同一个任期内获得大多数选票,成为Leader(一个节点在一个任期内只能给一个Candidate投票,任期相同则选票先到先得)并给其他节点发送心跳来保持自己的角色
    • 收到其他节点的RPC请求,如果请求中的任期大于等于Candidate当前的任期,认为其他节点成为了Leader,自身转换为Follower;如果其他节点的任期小于自身的任期,拒绝RPC请求并保持Candidate角色
    • 一段时间后仍旧没有Leader(可能是出现了平票的情况),则在选举超时后重新发起一轮选举(递增任期、发送投票请求)

为了避免平票的问题,同时在出现平票的情况后能快速解决,Raft的选举超时时间是在一个区间内随机选择的(150~300ms)。这样尽量把服务器选举时间分散到不同的时间,保证大多数情况下只有一个节点会发起选举。在平票的情况下,每个节点也会在一个随机时间后开始新一轮选举,避免可能出现的一直处于平票的情况。

Log replication

一旦Leader被选举出来后,Leader就开始为集群服务:处理所有的客户端请求并将数据复制到所有节点。

一旦日志被“安全”的复制,那么Leader将这个日志应用到自己的状态机并响应客户端。

如果有节点异常或网络异常,Leader会一直重试直到所有日志都会正确复制到所有节点(日志不允许有空洞,所以每个节点上的日志都是连续的,不能有因为失败引起的空洞)。

日志组织形式如上图,每个日志条目中包含可执行的指令、和日志被创建时的任期号,日志条目也包含了自己在日志中的位置,即index。一旦一个日志条目存在于大多数节点,那么该日志条目是committed的。

Raft算法保证所有committed的日志都是持久化的(日志需要在大多数节点上持久化之后再响应给客户端,这意味着每个Follower节点收到AppendEntry请求后需要持久化到日志之后再响应给Leader),且最终会被所有的状态机执行。

Raft算法保证了以下特性:

  • 如果两个日志条目有相同的index和term,那么他们存储了相同的指令(即index和term相同,那么可定是同一条指令,就是同一个日志条目)
  • 如果不同的日志中有两个日志条目,他们的index和term相同,那么这个条目之前的所有日志都相同

两条规则合并起来的含义:两个日志LogA、LogB,如果LogA[i].index=Log[i]B.index且LogA[i].term=Log[i].term,那么LogA[i]=Log[i]B,且对于任何n < i的日志条目,LogA[n]=LogB[n]都成立。(这个结论显而易见的可以从日志复制规则中推导出来)

一个新Leader被选举出来时,Follower可能是上图中的任何一种情况。

  • (a)(b)可能还没复制到日志
  • (c)(d)可能曾经是Leader,所有包含了多余的日志(这些日志可能被提交了,也可能没提交)
  • (e)可能是成为Leader之后增加了一些日志,但是在Commit之前又编程了Follower角色,且还没有更新日志条目
  • (f)可能是在任期2称为了Leader并追加了日志但是还没提交就Crash了,恢复之后在任期3又成了Leader并且又追加了日志

在Raft中,通过使用Leader的日志覆盖Follower的日志的方式来解决出现像上图的情况(强Leader)。Leader会找到Follower和自己想通的最后一个日志条目,将该条目之后的日志全部删除并复制Leader上的日志。详细过程如下:

  • Leader维护了每个Follower节点下一次要接收的日志的索引,即nextIndex
  • Leader选举成功后将所有Follower的nextIndex设置为自己的最后一个日志条目+1
  • Leader将数据推送给Follower,如果Follower验证失败(nextIndex不匹配),则在下一次推送日志时缩小nextIndex,直到nextIndex验证通过

上面的方式显然可以通过一些方法进行优化来减少重试的次数,但是在Raft论文中对是否有必要进行优化提出了质疑,因为这种异常的情况很少出现。

解读Raft(二 选举和日志复制)的更多相关文章

  1. 图解Raft之日志复制

    日志复制可以说是Raft集群的核心之一,保证了Raft数据的一致性,下面通过几张图片介绍Raft集群中日志复制的逻辑与流程: 在一个Raft集群中只有Leader节点能够接受客户端的请求,由Leade ...

  2. 解读Raft(一 算法基础)

    最近工作中讨论到了Raft协议相关的一些问题,正好之前读过多次Raft协议的那paper,所以趁着讨论做一次总结整理. 我会将Raft协议拆成四个部分去总结: 算法基础 选举和日志复制 安全性 节点变 ...

  3. Raft 实现日志复制同步

    Raft 实现日志复制同步 本篇文章以 John Ousterhout(斯坦福大学教授) 和 Diego Ongaro(斯坦福大学获得博士学位,Raft算法发明人) 在 Youtube 上的讲解视频及 ...

  4. 基于 raft 协议的 RocketMQ DLedger 多副本日志复制设计原理

    目录 1.RocketMQ DLedger 多副本日志复制流程图 1.1 RocketMQ DLedger 日志转发(append) 请求流程图 1.2 RocketMQ DLedger 日志仲裁流程 ...

  5. MySQL复制(二)--基于二进制日志文件(binlog)配置复制

    基础环境:   主库 从库 服务器IP地址 192.168.10.11 192.168.10.12 版本 5.7.24 5.7.24 已存在的数据库 mysql> show databases; ...

  6. Etcd中Raft日志复制的实现

    Raft state of log commitIndex : A log entry is committed once the leader that created the entry has ...

  7. Raft算法系列教程3:日志复制

    1.日志复制的过程 Leader选出后,就开始接收客户端的请求.Leader把请求作为日志条目(Log entries)加入到它的日志中,然后并行的向其他服务器发起 AppendEntries RPC ...

  8. Paxos 实现日志复制同步

    Paxos 实现日志复制同步 本篇文章以 John Ousterhout(斯坦福大学教授) 和 Diego Ongaro(斯坦福大学获得博士学位,Raft算法发明人) 在 Youtube 上的讲解视频 ...

  9. Paxos 实现日志复制同步(Basic Paxos)

    Paxos 实现日志复制同步 本篇文章以 John Ousterhout(斯坦福大学教授) 和 Diego Ongaro(斯坦福大学获得博士学位,Raft算法发明人) 在 Youtube 上的讲解视频 ...

随机推荐

  1. java 中String类的常用方法总结,带你玩转String类。

    String类: String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象.String类对象创建后不能修改,StringBuffer & St ...

  2. nginx和nfs

    1.安装nginx #yum install epel-release -y #yum install nginx -y #vim /usr/local/nginx/conf/nginx.conf - ...

  3. 解决将/etc/passwd文件中1000改为0后只能guest进入系统的问题 ||ubuntu下将普通用户权限升级为root用户权限的方法;

    其实我现在才知道linux系统对于用户权限管理比较严,在ubuntu下系统不允许root权限的用户进入图像界面系统.由于之前没弄过权限这个东西瞬间掉坑了了. 我是想修改一下root下的nginx.co ...

  4. [LeetCode] IPO 上市

    Suppose LeetCode will start its IPO soon. In order to sell a good price of its shares to Venture Cap ...

  5. kafka知识体系-kafka设计和原理分析-kafka leader选举

    kafka leader选举 一条消息只有被ISR中的所有follower都从leader复制过去才会被认为已提交.这样就避免了部分数据被写进了leader,还没来得及被任何follower复制就宕机 ...

  6. [Ubuntu 16.04 LTS ]屏幕分辨率 Unknown display

    新装完Ubuntu 16.04 LTS 通过System settings-->Displays 设置屏幕分辨率 显示"Unknown display",选择后无反应,并且屏 ...

  7. (MariaDB/MySQL)MyISAM存储引擎读、写操作的优先级

    MariaDB/MySQL中使用表级锁的存储引擎(例如MyISAM.Aria(MariaDB对MyISAM引擎的改进,前身是MyISAM))在读(select).写操作(insert.delete.u ...

  8. [SCOI 2010]字符串

    Description lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数不能少于0的个数.现在lxhgw ...

  9. [ZJOI2010]数字计数

    题目描述 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 输入输出格式 输入格式: 输入文件中仅包含一行两个整数a.b,含义如上所述. 输出格式: 输出文件 ...

  10. VK Cup 2017 - Квалификация 2

    因为资格赛1已经通过了,资格赛2随便打打玩.这次题目比上次还简单,FallDream看了两眼觉得太水就不做了,我一个人闲着无聊只好默默做了 A. Новый пароль 题目大意:给出N和K,要求构 ...