Raft共识算法PartA:Leader Election And HeartBeat

前言

接触了一些分布式相关的理论基础,并且也看了Raft的论文,是时候该总结一下了。

本篇文章主要聊了下面一些东西

  • 分布式下为何要共识
  • CAP理论
  • 多数派原则
  • Raft共识算法PartA:选举与心跳

分布式下为何需要共识

  • 何为分布式?

一群Server共同工作,每个Server都是一台计算机,各个Server可以相互通信。也即:多个Server一起做多个事情。多个人干多个事。

-何为集群?

同一个服务,部署多个节点共同承担流量,这就是集群。一件事由多个人来干。

  • 为什么要进行共识?

在日常生活中,我们与他人进行工作,是需要沟通协作的。共识算法就是一种让分布式下的几个Server对某种操作达成共识。

为什么需要区分主从节点?

分布式下,数据一致性保证是很重要的。所有的Server对一条数据,应当达成一种共识状态。而主从架构,则是最直观的数据一致性保证方式。(现实也是,无论组织什么活动,都有一个发起人来统一管理,这样是最有效的)。如果不存在数据一致性的要求,也没必要采用主从架构咯。

从这张图中,可以讨论很多有趣的问题。

CAP 理论

CAP理论探讨的是,设计分布式架构的时候,总是在Consistent(一致性)Availablity(可用性)Partition Tolerance(分区容错性) 之间做取舍。分布式系统最重要的一点,当发生了网络分区的时候,服务依旧是可用的,也就是说P是必要的。

具体的CAP详细分析可看我上一篇文章:各注册中心对比以及简单原理分析

你可能注意到,我在Master向Follower进行同步的时候,他们的请求的顺序是一样 的。原因是,这个过程是并行向All Follower发送同步请求,异步接收成功通知(这取决于网络/或处理速度)。那么在向Client回复Success的时候,这个请求必然已经被同步到了Follower。

接下来的问题是:万一有服务断开连接了怎么办?(断电、地震、死机......)Client应该收到Success的回复吗?

当Follower1挂了,从而导致整个服务瘫痪不可用,你自己觉得可以这样干吗?当然不行啦。还有两台机留着浪费呢???

强行进行CP是不太现实的,因此人们提出了一种折中的方式,那就是允许数据存在短暂的不一致的情况。下面则更像是对于CP的延展。

多数派原则

多数派原则 不仅仅是现实生活中一种公平的手段,也是分布式中很重要的原则。一旦这个同步请求,接收到了多数派Follower的成功回复,那么Master就会回复Client,请求成功。

这也是一个问题的答案:为什么集群节点都是奇数节点而不是偶数节点?

如果一个集群中服务挂了大多数,那么这个服务就是不可用了。

假设现在有5台机器,大多数则是2台机器。 他可以允许两台同时故障。那么如果变成6台机器,他的大多数是4,他也只运行挂两台。所以,都是采用奇数节点的方式。

什么是共识算法

上面巴拉巴拉一堆,已经说清楚了为什么要共识:各个Server间需要协调。

而共识算法,这就是这个协调过程的具体实现。

分布式共识算法最有名的Paxos共识算法,也是公认的很抽象的一种共识算法。而Raft不仅仅论文详细,还给出了2k多行的C++代码具体实现。目前也有很多用Raft作为共识算法的组件,例如etcd这些。

Raft共识算法介绍

Raft共识算法被在论文中被分解成三个重要组成部分。

  • Leader Election(领导者选举)
  • Log Replication(日志复制
  • Safety(安全性)

术语

  • 节点状态:
    • Leader:领导者节点,负责心跳,日志同步。
    • Follower:随从节点。
    • Candidate:候选人。
  • Term:任期,类似于皇帝的朝代。当Term发生变化,称之为改朝换代。
  • 心跳:特殊的AppendEntries RPCs
    • 不带日志的RPC请求

Raft共识算法PartA:领导者选举与心跳

Leader Election(领导者选举)

Raft共识算法讲述的是一个强leader的算法。由leader来主导一切事务流程。Raft共识算法中提到,每一个Term中,整个集群中至多存在一个Leader。可以不存在Leader。

状态转换图

每种状态都有过期时间。

  • Leader:自己挂掉,亦或者收到来自Term更高的心跳。
  • Follower:心跳超时
  • Candidate:选举超时

注意:除了Leader之外,另外两种状态会有多个节点持有,因此为了避免每次都同时过期,每个节点选择的过期时间是不一样的。论文中提到超时的时间选取可以在150ms - 300ms之间。

初始化,每个节点都是Follower状态,并且每个节点的心跳超时时间不同。当一个Follower发现心跳超时,那么这个Follower自动转换成为Candidate,选择一个选举过期时间,并且尝试投自己一票,然后并行的向其他节点发送求票消息。(注意这里是其他节点可能是Follower,也可能是Candidate)当Follower收到多数票的时候,自己变成Leader。

这里的投票状态有几个问题:

  • (Vote Split)选票平分问题。如果选票被平分,那么这个Term里面就没有Leader。此时Candidate会超时,并且进行重新选举。
  • 确定自己可不可以投票。只要发现求票者的任期比自己大,并且自己手中的票未投出,则可将票给予。注意,在一个Term中只能投一票。(这里还有一个限制:求票的Server日志必须比自己新,否则投反对票)

此时Leader已经被选出,Leader会定期发送心跳给Follower,宣誓自己的主权。(抑制选举)。

在集群正确运行一段时间后如果发生网络故障:

  • Leader挂了,Follower超时,重新开始选举,重复上面的几步。当旧的Leader回来后,收到更大的Term心跳包,那么他会主动转换为Follower。
  • Follower挂了,不影响。但是在重连回来的时候,收到了Term的心跳包,确认自己还是Follower,不会影响现任的Leader。

参考资料:

相关推荐
Yaml442 分钟前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
WX187021128731 小时前
在分布式光伏电站如何进行电能质量的治理?
分布式
小码编匠2 小时前
一款 C# 编写的神经网络计算图框架
后端·神经网络·c#
AskHarries2 小时前
Java字节码增强库ByteBuddy
java·后端
佳佳_2 小时前
Spring Boot 应用启动时打印配置类信息
spring boot·后端
许野平3 小时前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
不能再留遗憾了4 小时前
RabbitMQ 高级特性——消息分发
分布式·rabbitmq·ruby
茶馆大橘4 小时前
微服务系列六:分布式事务与seata
分布式·docker·微服务·nacos·seata·springcloud
BiteCode_咬一口代码4 小时前
信息泄露!默认密码的危害,记一次网络安全研究
后端