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。

参考资料:

相关推荐
Estar.Lee14 分钟前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi
2401_857610032 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
凌冰_2 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
码农飞飞3 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货3 小时前
Rust 的简介
开发语言·后端·rust
monkey_meng3 小时前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
Estar.Lee3 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
新知图书4 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
盛夏绽放4 小时前
Node.js 和 Socket.IO 实现实时通信
前端·后端·websocket·node.js
Ares-Wang5 小时前
Asp.net Core Hosted Service(托管服务) Timer (定时任务)
后端·asp.net