raft协议 MySQL 切换_Raft 协议实战系列(二)—— 选主

注:本文原创,转载请标明出处。

欢迎转发、关注微信公众号:Q的博客。 不定期发送干货,实践经验、系统总结、源码解读、技术原理。

本文目的

笔者期望通过系列文章帮助读者深入理解Raft协议并能付诸于工程实践中,同时解读不易理解或容易误解的关键点。

该系列会从原理、源码、实践三个部分为大家讲解Raft算法,本文为《Raft实战》系列第二篇:

原理部分我们会结合 Raft 论文讲解 Raft 算法思路,整体分篇会遵循 Raft 的模块化思想,分别讲解 Leader election、Log replication、Safety、Cluster membership change、Log compaction 等。

源码部分我们会通过分析 hashicorp/raft 来学习一个工业界的 Raft 实现,hashicorp/raft 是 Consul 的底层依赖。

实践部分我们会基于 hashicorp/raft 来实现一个简单的分布式 kv 存储,以此作为系列的收尾。

什么是选主

选主(Leader election)就是在分布式系统内抉择出一个主节点来负责一些特定的工作。在执行了选主过程后,集群中每个节点都会识别出一个特定的、唯一的节点作为leader。

我们开发的系统如果遇到选主的需求,通常会直接基于 zookeeper 或 etcd 来做,把这部分的复杂性收敛到第三方系统。然而作为 etcd 基础的 raft 自身也存在“选主”的概念,这是两个层面的事情:基于 etcd 的选主指的是利用第三方 etcd 让集群对谁做主节点的决策达成一致,技术上来说利用的是 etcd 的一致性状态机、lease 以及 watch 机制,这个事情也可以改用单节点的 MySQL/Redis 来做,只是无法获得高可用性;而 raft 本身的选主则指的是在 raft 集群自身内部通过票选、心跳等机制来协调出一个大多数节点认可的主节点作为集群的 leader 去协调所有决策。

当你的系统利用 etcd 来写入谁是主节点的时候,这个决策也在 etcd 内部被它自己集群选出的主节点处理并同步给其它节点。

Raft 为什么要进行选主?

按照论文所述,原生的 Paxos 算法使用了一种点对点(peer-to-peer)的方式,所有节点地位是平等的。在理想情况下,算法的目的是制定一个决策,这对于简化的模型比较有意义。但在工业界很少会有系统会使用这种方式,当有一系列的决策需要被制定的时候,先选出一个 leader 节点然后让它去协调所有的决策,这样算法会更加简单快速。

此外,和其它一致性算法相比,raft 赋予了 leader 节点更强的领导力,称之为 Strong Leader。比如说日志条目只能从 leader 节点发送给其它节点而不能反着来,这种方式简化了日志复制的逻辑,使 raft 变得更加简单易懂。

Raft选主过程

下图的节点状态转移图,我们在前一篇文章已经看到了,但只是做了简单的描述,接下来我们会结合具体的Leader election细节来深刻理解节点的状态转换。

bf16218b0ee735131be12e501f100957.png

*图名:节点状态图

Follower状态转移过程

Raft 的选主基于一种心跳机制,集群中每个节点刚启动时都是 follower 身份(Step: starts up),leader 会周期性的向所有节点发送心跳包来维持自己的权威,那么首个 leader 是如何被选举出来的呢?方法是如果一个 follower 在一段时间内没有收到任何心跳,也就是选举超时,那么它就会主观认为系统中没有可用的 leader,并发起新的选举(Step: times out, starts election)。

这里有一个问题,即这个“选举超时时间”该如何制定?如果所有节点在同一时刻启动,经过同样的超时时间后同时发起选举,整个集群会变得低效不堪,极端情况下甚至会一直选不出一个主节点。Raft 巧妙的使用了一个随机化的定时器,让每个节点的“超时时间”在一定范围内随机生成,这样就大大的降低了多个节点同时发起选举的可能性。

3540e494487f90e60a1b602f80104583.png

*图解:一个五节点Raft集群的初始状态,所有节点都是follower身份,term为1,且每个节点的选举超时定时器不同

若 follower 想发起一次选举,follower 需要先增加自己的当前 term,并将身份切换为 candidate。然后它会向集群其它节点发送“请给自己投票”的消息(RequestVote RPC)。

46dabc4d360828208451d295c19c90f3.png

*图解:S1 率先超时,变为 candidate,term + 1,并向其它节点发出拉票请求

Candicate状态转移过程

Follower 切换为 candidate 并向集群其他节点发送“请给自己投票”的消息后,接下来会有三种可能的结果,也即上面节点状态图中 candidate 状态向外伸出的三条线。

1. 选举成功(Step: receives votes from majority of servers)

当candicate从整个集群的大多数(N/2+1)节点获得了针对同一 term 的选票时,它就赢得了这次选举,立刻将自己的身份转变为 leader 并开始向其它节点发送心跳来维持自己的权威。

909d7cf481e5e6a14c333e873240d2a6.png

*图解:“大部分”节点都给了S1选票

6cf18d12cb75a1da9020d55339e645bc.png

*图解:S1变为leader,开始发送心跳维持权威

每个节点针对每个 term 只能投出一张票,并且按照先到先得的原则。这个规则确保只有一个 candidate 会成为 leader。

2. 选举失败(Step: discovers current leader or new term)

Candidate 在等待投票回复的时候,可能会突然收到其它自称是 leader 的节点发送的心跳包,如果这个心跳包里携带的 term 不小于 candidate 当前的 term,那么 candidate 会承认这个 leader,并将身份切回 follower。这说明其它节点已经成功赢得了选举,我们只需立刻跟随即可。但如果心跳包中的 term 比自己小,candidate 会拒绝这次请求并保持选举状态。

68125afcea3039efd73accdd28964e75.png

*图解:S4、S2 依次开始选举

bbef2463f50c7d7fdb06dda1363fa951.png

*图解:S4 成为 leader,S2 在收到 S4 的心跳包后,由于 term 不小于自己当前的 term,因此会立刻切为 follower 跟随S4

3. 选举超时(Step: times out, new election)

第三种可能的结果是 candidate 既没有赢也没有输。如果有多个 follower 同时成为 candidate,选票是可能被瓜分的,如果没有任何一个 candidate 能得到大多数节点的支持,那么每一个 candidate 都会超时。此时 candidate 需要增加自己的 term,然后发起新一轮选举。如果这里不做一些特殊处理,选票可能会一直被瓜分,导致选不出 leader 来。这里的“特殊处理”指的就是前文所述的随机化选举超时时间。

0b39d9abcc865eade82afde49d6ed2f0.png

*图解:S1~S5都在参与选举

e323313b68bdedc24855834e50e80263.png

*图解:没有任何节点愿意给他人投票

e7aa16b30bd5fb2704542ae0f342cc18.png

*图解:如果没有随机化超时时间,所有节点将会继续同时发起选举……

以上便是 candidate 三种可能的选举结果。

Leader 切换状态转移过程

节点状态图中的最后一条线是:discovers server with higher term。想象一个场景:当 leader 节点发生了宕机或网络断连,此时其它 follower 会收不到 leader 心跳,首个触发超时的节点会变为 candidate 并开始拉票(由于随机化各个 follower 超时时间不同),由于该 candidate 的 term 大于原 leader 的 term,因此所有 follower 都会投票给它,这名 candidate 会变为新的 leader。一段时间后原 leader 恢复了,收到了来自新leader 的心跳包,发现心跳中的 term 大于自己的 term,此时该节点会立刻切换为 follower 并跟随的新 leader。

上述流程的动画模拟如下:

9ca7523f0e89e2836d13819ab3ad785b.png

*图解:S4 作为 term2 的 leader

9c17e6375fa99844501caa35e94be8a0.png

*图解:S4 宕机,S5 即将率先超时

d6d1d8ad5352a128bbc6a7cbee8fee41.png

*图解:S5 当选 term3 的 leader

230fc51ccd4bbdb20de0198a24e49bf9.png

*图解:S4 宕机恢复后收到了来自 S5 的 term3 心跳

da6befbfb32c438370d323d06f4eb997.png

*图解:S4 立刻变为 S5 的 follower

以上就是 raft 的选主逻辑,但还有一些细节(譬如是否给该 candidate 投票还有一些其它条件)依赖算法的其它部分基础,我们会在后续“安全性”一篇描述。

当票选出 leader 后,leader 也该承担起相应的责任了,这个责任是什么?就是下一篇将介绍的“日志复制”~

欢迎转发、关注微信公众号:Q的博客,不定期发送干货,实践经验、系统总结、源码解读、技术原理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/531746.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二分匹配最大匹配的理解(附图解)

定义一个PXP的有向图中,路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每…

Floyd算法的理解

转载于:https://www.cnblogs.com/hujunzheng/p/3919226.html

hdu1269迷宫城堡(判断有向图是否是一个强连通图)

1 /* 题意: 给你一个图,求这个有向图示否是一个强连通图(每两个节点都是可以相互到达的)! 思路1:按正向边dfs一遍,将经过的节点计数,如果记录的节点的个数小于…

mgg mysql_mgg文件怎么转换mp3格式?

步骤/方法方法/步骤1:下载载视频转换器,我们说到在官网下载比较好吧。下载完成之后,我们就直接点击进行安装,一般 在安装的过程也是非常快速的,主要是按照安装向导上的步骤进行就可以了。方法/步骤2:安装好之后,我们就…

java dao 泛型的好处_java中泛型有什么作用

泛型的作用如下:1、类型安全泛型的主要目标是提高 Java 程序的类型安全。编译时的强类型检查;通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或…

java ==和=_Java ==和equals()的区别

前言本篇文章讲的是从JVM角度比较和equals的区别一:** Java数据类型分类**Paste_Image.png1:基本数据类型又称为原始数据类型,他们之间的比较应该使用(),比较的是他们的值。2:引用数据类型当引用数据类型用()进行比较&…

poj1330Nearest Common Ancestors 1470 Closest Common Ancestors(LCA算法)

LCA思想:http://www.cnblogs.com/hujunzheng/p/3945885.html 在求解最近公共祖先为问题上,用到的是Tarjan的思想,从根结点开始形成一棵深搜树,非常好的处理技巧就是在回溯到结点u的时候,u的子树已经遍历,这…

LCA算法的理解

LCA思想:在求解最近公共祖先为问题上,用到的是Tarjan的思想,从根结点开始形成一棵深搜树,非常好的处理技巧就是在回溯到结点u的时候,u的子树已经遍历,这时候才把u结点放入合并集合中, 这样u结点…

java词汇速查手册_java 词汇表速查手册

Abstract class 抽象类:抽象类是不允许实例化的类,因此一般它需要被进行扩展继承。Abstract method 抽象方法:抽象方法即不包含任何功能代码的方法。Access modifier 访问控制修饰符:访问控制修饰符用来修饰Java中类、以及类的方法和变量的访问控制属性。Anonymous …

python3.5 连接mysql_python3.5 連接mysql本地數據庫

前期准備工作:安裝python的模塊,網上大部分讓安裝mysqldb模塊,但是會報錯,原因是python3.5不被其支持:請看該鏈接 我們也可以這樣解決:直接執行:sudo pip3 install pymysql;在python3中輸入impo…

java异常顺序_网易新闻

public class SmallT {public static void main(String args[]) {SmallT t new SmallT();int b t.get();System.out.println(b);}public int get() {try {return 1;} finally {return 2;}}}返回的结果是2。我可以通过下面一个例子程序来帮助我解释这个答案,从下面…

下载国外网站资料需java_Java开发必知道的国外10大网站

1、https://www.google.com/不解释2、https://stackoverflow.com里面包含各种开发遇到的问题及答案,质量比较高。3、https://github.com/免费的开源代码托管网站,包括了许多开源的项目及示例项目等。4、https://dzone.com/提供技术新闻、编程教程、及各种…

java 空数组如何判断,java判断数组是否为空

java判断数组是否为空根据数组长度判断,如果为0,则为空,反之不是。 (推荐学习:java课程)public class Main {public static void main(String[] args) {int[] array1 new int[]{}; //被当成 {0}if (array1 null) {System.out.pr…

php访问网页post获取源码,第一次抓别人网站数据,用postman直接请求可以获取到返回数据,通过代码的方式就一直报错,php...

最近需要抓取下KFC的一些数据通过postman把请求地址和参数都拿过来后可以返回数据我就天真的以为可以通过代码直接发送一个post请求即可但是通过php的curl模拟请求后,返回的一直是服务器异常刚开始时好像成功过,但现在一直都是报这个,我用的就…

php注册机制,php自动注册登录验证机制实现代码_PHP教程

背景:在phpwind站点后台添加一个名为“广告管家”(广告管家为CNZZ的一款广告投放的应用)的应用,整个“广告管家”的应用是通过iframe载入,载入的具体内容根据不同站点显示针对该站点的具体内容,为了提高易用性,有以下的…

php实现直播答题系统,直播答题解决方案

概述即构提供直播答题一站式解决方案,包括 Windows 主播端、移动 APP 端示例源代码(iOS、Android)。1 下载/体验地址由于直播答题场景需要主播端(推流、发题)和观众端(拉流、答题)配合使用,因此开发者需要同时下载这两端的软件。下载后,具体的…

matlab桥梁受力计算公式,matlab桥梁计算

等级:文件 218KB格式 pdf内容简介 该文结合斜拉桥施工监控的工程实践,分析研究利用MATLAB 6.0神经网络算法,可实现模式识别和函数逼近,进行信号处理,利用人工智能进行自动控制及非线性预测等。斜拉桥智能施…

2014 网选 5011 Game(Nim游戏,数学题)

/*题意&#xff1a;Nim游戏&#xff01; 思路&#xff1a;通过异或&#xff0c;判断将n个数表示成二进制的形式之后&#xff0c;是否对应位的数字1 的个数是偶数&#xff01; */ #include<iostream> using namespace std;int main(){int n, x, s;while(cin>>n){s…

先序,中序,后序线索二叉树

//后序线索&#xff0c;这种方法不容易想到 1 #include<iostream>2 #include<cstring>3 #include<cstdio>4 #include<algorithm>5 6 using namespace std;7 8 struct TREE{9 int val; 10 TREE *ch[2]; 11 TREE *thread;//该节点的线索的…

oracle的todate函数 不用英文,关于在mybaties 和 oracle的to_date函数的问题?

ITMISSD)TO_DATE使用详解时常使用to_date函数来查询特定时间内的数据。语法&#xff1a;TO_DATE(x [, format])用于将字符串x转换为时间值&#xff0c;该函数可以指定一个可选的字符串format参数来说明x的格式。如果没有指定format参数&#xff0c;日期就使用默认的数据库格式(…