理解分布式一致性:Raft协议

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 理解分布式一致性:Raft协议

理解分布式一致性:Raft协议



在分布式系统中,分布式一致性是一个非常重要的概念,它是指分布式系统的各个服务器都保持一个统一的状态(数据)。但是在分布式系统中,通常由于网络,系统状态等原因会导致某些服务不可用或者不可靠。这就需要一种分布式一致性的协议来保证系统在某些服务失败的情况下仍然整体可用。


Raft协议是受到Paxos的影响而产生的,相对于Paxos而言,Raft协议更加简单易懂。我会在后面的博客里面专门详细介绍Paxos协议的具体内容。这里我们重点讨论Raft协议。


什么是分布式一致性


下面举个例子:


假如我们有一个单节点的服务节点A,这个单节点的服务只是用来存储一个字母。同时我们还有一个客户端向这个服务发起更新数据的请求。


对于单节点的分布式一致性来说,服务响应客户端的更新请求即可。但是当我们有多个服务节点的情况下会怎么样呢?


image.png

Raft协议就是保证多个服务器节点数据一致性的协议。


接下来我们看看Raft是怎么工作的。


Raft协议中,一个服务器的节点可以是以下三种状态中的任意一个:


  1. Follower 状态:跟随者,被动接收数据。我们用实心圆表示。


image.png

  1. Candidate 状态:候选人,可以被选做Leader。我们用实心圆+虚线边框表示。


image.png


  1. Leader 状态:领导者,处理所有客户端交互,日志复制等,一般一次只有一个Leader. 我们用实心圆+实线边框表示。


image.png


Leader选举


所有的节点都是从Follower状态开始的。


如果Follower在一定的时间里面没有收到选举请求或者Leader节点的回复,Follower则会转变为Candidate。


image.png


Candidate会发送选举请求给所有的其他节点,收到选举请求的其他节点会反馈回Candidate,当Candidate收到的所有响应数目大于n/2 时,Candidate会认为绝大多数节点已经选我作为Leader了,这时候Candidate就会转变为Leader。接下来所有的数据变化都会经由Leader发起。


image.png


日志复制流程


在Raft系统中,所有的数据变化都是以日志记录的形式添加到服务节点之中。服务节点会不断的读取日志记录,并将日志记录更新到服务节点的数据中。日志记录最开始的状态是uncommited, 更新之后状态则变为commited.


为了实现所有服务节点的一致性更新,步骤如下:


  1. client 发送数据更改请求到Leader


image.png


  1. Leader复制日志记录到Follower节点


image.png


  1. Leader等待大多数节点完成复制日志记录。


  1. Leader节点commit 当前日志记录,并更新Leader节点的数据。


image.png


  1. Leader通知Follower节点该日志记录已经commit.


  1. Follower节点commit该日志记录。


image.png


  1. 整个分布式系统实现了数据一致性。


term选举周期


在Raft 协议中,有一个term的概念。term是一个选举周期,一个term周期只会产生一个Leader,term连续递增。


timeout


在Raft协议中,为了保证选举和数据更新的顺利进行,规定了两种类型的timeout:

选举timeout和心跳timeout。


选举和选举timeout


1.每个term开始时,会重置选举timeout。在一个term中,Follower会等待timeout的时间,如果超出这个时间还没有得到其他节点的选举请求,Follower会主动转变为Candidate,并且term+1,意味着开启了新的选举周期。


选举timeout是150ms-300ms之间的一个随机数,之所以随机产生timeout,是为了避免同时产生多个Candidate的情况。

当Follower转变为Candidate之后,term加1, 然后开始新一轮的选举。Candidate首先会将自己的Vote Count 加1,然后发送请求选举的消息给其他节点。


image.png


  1. 接收节点首先会比较term的大小,如果自己的term小于Candidate的term,则更新自己的term和Candidate的term保持一致,并重置timeout。如果接收节点在这个term中还没有做任何选举,则会返回选举响应消息给Candidate节点。


image.png


  1. Candidate 节点收到大部分节点的选举响应之后,会变成Leader 节点。


image.png


  1. 一个选举周期完成,接下来Leader 发送更新日志给Follower节点,进入日志更新阶段。


选举分裂


值得注意的是Candidate只有得到超出n/2个节点的选举响应才能变为Leader节点。如果两个Follower节点同时变成Candidate节点,则会产生选举分裂的问题。


现在假设我们总共有4个节点,其中两个节点同时变成Candidate节点,并向其余两个节点发送选举请求:


image.png


节点B,C成为Candidate节点并行向节点A,D发送选举请求。


image.png


节点A,D分别响应节点B,C的请求,这时候两个Candidate节点由于得到的Vote都是2,不满足大于n/2的条件,则其不能转变为Leader节点,继续等待timeout至新的term开始并开启新一轮的选举,只到符合条件为止。


image.png


日志复制和心跳timeout


当系统进入到日志复制阶段,Leader节点会以心跳timeout的节奏向Follower节点发送日志记录,并且需要确保所有的节点都能够接受到完整的日志记录。


  1. 客户发送set 5 给Leader, 在下一个心跳timeout,Leader将set 5的日志记录发给Follower。


image.png


  1. Leader 收到大部分节点的ack 响应之后,commit 该日志记录。


image.png


  1. Leader通知Client已经提交该日志记录,同时通知Follower 提交该日志记录。


image.png

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
2天前
|
存储 缓存 负载均衡
一致性哈希:解决分布式难题的神奇密钥
一致哈希是一种特殊的哈希算法,用于分布式系统中实现数据的高效、均衡分布。它通过将节点和数据映射到一个虚拟环上,确保在节点增减时只需重定位少量数据,从而提供良好的负载均衡、高扩展性和容错性。相比传统取模方法,一致性哈希能显著减少数据迁移成本,广泛应用于分布式缓存、存储、数据库及微服务架构中,有效提升系统的稳定性和性能。
10 1
|
2月前
|
JSON 分布式计算 前端开发
前端的全栈之路Meteor篇(七):轻量的NoSql分布式数据协议同步协议DDP深度剖析
本文深入探讨了DDP(Distributed Data Protocol)协议,这是一种在Meteor框架中广泛使用的发布/订阅协议,支持实时数据同步。文章详细介绍了DDP的主要特点、消息类型、协议流程及其在Meteor中的应用,包括实时数据同步、用户界面响应、分布式计算、多客户端协作和离线支持等。通过学习DDP,开发者可以构建响应迅速、适应性强的现代Web应用。
|
2月前
|
架构师 Java 数据中心
二阶段提交:确保分布式系统中数据一致性的关键协议
【10月更文挑战第16天】在分布式系统中,数据一致性的维护是一个至关重要的挑战。为了应对这一挑战,二阶段提交(Two-Phase Commit,简称2PC)协议应运而生。作为一种经典的分布式事务协议,2PC旨在确保在分布式系统中的所有节点在进行事务提交时保持一致性。
42 0
|
3月前
|
监控
分布式-Zookeeper-Zab协议
分布式-Zookeeper-Zab协议
|
3月前
|
网络协议 网络安全 网络架构
分布式基础-网络通信协议讲解
分布式基础-网络通信协议讲解
分布式基础-网络通信协议讲解
|
2月前
|
消息中间件 缓存 算法
分布式系列第一弹:分布式一致性!
分布式系列第一弹:分布式一致性!
|
2月前
|
算法 Java 关系型数据库
漫谈分布式数据复制和一致性!
漫谈分布式数据复制和一致性!
|
4月前
|
自动驾驶 5G 调度
|
4月前
|
Oracle 关系型数据库
分布式锁设计问题之Oracle RAC保证多个节点写入内存Page的一致性如何解决
分布式锁设计问题之Oracle RAC保证多个节点写入内存Page的一致性如何解决
|
4月前
|
消息中间件 存储 监控
消息队列在分布式系统中如何保证数据的一致性和顺序?
消息队列在分布式系统中如何保证数据的一致性和顺序?
下一篇
DataWorks