当前位置: 首页 > news >正文

Raft:为什么几乎所有分布式系统都选了它

Raft:为什么几乎所有分布式系统都选了它

大家好,我是HLAIA光子。

分布式系统里最难的事情不是写代码,是让一群机器在同一件事上达成一致。Raft就是专门解决这个问题的协议,而且它用一种人类能看懂的方式做到了。etcd、Nacos、Redis Sentinel,几乎所有叫得出名字的分布式中间件都在用它。

先想一个场景:你的集群有五台节点,其中一台是 Leader,负责接收所有写入。突然这台 Leader 网络断了,剩下四台如果各自选出一个新 Leader,数据就开始分叉了。这就是"脑裂",分布式系统里最让人头疼的问题。Raft 用一套优雅的机制彻底解决了它。

分布式共识

分布式共识要解决的核心问题很简单:让多台机器对一份数据的值达成一致。说起来简单,但节点会崩溃、网络会延迟、消息会乱序,在这些干扰下保持一致性变得极其困难。

Raft 在 2014 年由 Diego Ongaro 和 John Ousterhout 提出,论文:“In Search of an Understandable Consensus Algorithm”。它要做 Paxos 能做的事,但让人类能看懂。

Raft 的设计思路是把共识问题拆成三个独立子问题:Leader 选举日志复制安全性。三个子问题可以分开理解,不用同时脑爆。

Leader 选举

Raft 集群里每个节点在任意时刻只处于三种角色之一:FollowerCandidateLeader。默认所有人都是 Follower,被动接收 Leader 的心跳和日志。如果 Follower 一段时间没收到心跳,它就认为 Leader 挂了,转成 Candidate 开始竞选。

选举流程很直观:Candidate 先给自己投一票,然后向其他节点发 RequestVote RPC。其他节点根据日志的新旧程度决定要不要投票。拿到多数票的 Candidate 晋升为 Leader,立刻开始发心跳。

有两个细节特别值得说。

第一个是Term,也就是"任期",每个 term 最多只有一个 leader。一旦有新的选举发生,term 就递增。旧 Leader 网络恢复后发现自己 term 落后了,会乖乖降级为 Follower。

第二个是随机化选举超时。每个节点的超时时间是随机的,范围大概 150 到 300 毫秒。这看起来是个小设计,但它巧妙地避免了多个节点同时发起选举的"抢跑"问题。如果超时范围设得太小,网络稍有波动就触发不必要的选举;设得太大,故障检测又太慢。

etcd 默认用的 150ms 到 300ms 这个范围,是个经验值。实际部署中如果网络延迟较高,可以适当调大这个范围,超时时间建议根据生产环境的实际情况来调整。

投票规则是,每个 term 内每个节点最多投一票,先到先得。而且投票时会检查 Candidate 的日志是否至少和自己一样新。这个限制保证了新 Leader 一定包含所有已提交的日志,是 Raft 安全性的核心保障。

日志复制

选出 Leader 之后就是干活了。客户端的所有写请求都由 Leader 处理。

Leader 收到客户端命令后,先追加到自己的本地日志,然后通过 AppendEntries RPC 发给所有 Follower。Follower 写入成功后回复确认。当 Leader 收到多数派的确认,这条日志就算"提交"了,Leader 给客户端返回成功。

这里有个很关键的一致性检查:Leader 发 AppendEntries 时会带上前一条日志的 index 和 term。Follower 收到后会检查自己本地对应位置有没有相同的条目,没有就拒绝。这保证了日志不会悄无声息地产生分歧。

如果 Follower 因为宕机或网络问题导致日志落后,Leader 会逐步回退,一条一条地把缺失的日志补上。Leader 永远不会覆盖或删除自己的日志,只做追加。这种"只追加"的设计大大简化了整个一致性推理。

补日志的过程在极端情况下可能比较慢。如果 Follower 落后了好几千条,Leader 要逐条回退确认,开销不小。etcd 在实现中做了批量发送的优化来加速同步。

安全性

Raft 的安全性可以归纳为四个核心属性。

选举安全:每个 term 最多一个 leader。Leader 只追加:Leader 不覆盖不删除自己的日志。日志匹配:如果两条日志的 index 和 term 相同,那它们存的一定是同一条命令,之前的所有日志也一样。Leader 完整性:已提交的日志一定会出现在后续所有 Leader 的日志里。

前三个比较好理解,第四个是精髓。投票时的日志新旧检查确保了任何成为 Leader 的节点都拥有全部已提交的日志条目。这意味着一旦一条日志被提交,它就永远不会丢失。

所以Raft安全性的逻辑就是,选举限制保证了新 Leader 有完整的已提交日志,日志匹配保证了日志不会产生分歧,Leader 只追加保证了一致性推理的简单性。

Paxos

在 Raft 出来之前,分布式共识的标准答案是Paxos。Paxos 由图灵奖得主 Leslie Lamport 在 1990 年提出,理论上很优雅,但工程实现极其困难。Google 花了好几年才在 Chubby 里正确实现了它。

Raft 论文里做了一个对照实验:让 43 个学生分别学 Raft 和 Paxos,然后回答同样的问题。33 个学生在学 Raft 之后回答得更好。

关键区别在于设计哲学。Paxos 是去中心化的设计,允许多个节点同时提案,冲突处理非常复杂。Raft 采用了强领导模型,所有请求都经过 Leader,思路清晰很多。

说白了,Raft 不是比 Paxos 更强,而是比 Paxos 更容易被正确实现。在分布式系统里,能正确实现比什么都重要。一个有 bug 的 Paxos 实现可能比没有共识协议还可怕。

性能方面两者其实差不多。Raft 的强领导模型在某些场景下还有优势:客户端只需要和 Leader 通信,不需要复杂的冲突解决。

etcd

玩过k8s的朋友肯定知到etcd,可以说它是Raft 在工业界最成功的应用之一了,也是Kubernetes集群唯一的存储后端。你往 K8s 里提交的每一个 Pod、Service、ConfigMap,最终都存在 etcd 里。

K8s 选 etcd 有三个原因。强一致性保证,集群状态不能出错。Watch 机制天然适配 K8s 的声明式 API。Raft 自带高可用,容忍少数节点故障。

Nacos

Nacos 是阿里开源的配置与服务发现中心。

有意思的地方在于,Nacos 同时用了两套一致性协议,AP和CP。服务注册发现用Distro协议,走 AP 路线,牺牲强一致性换高可用。配置管理用Raft协议,走 CP 路线,牺牲可用性换强一致性。

这个设计还是有讲究的。服务注册这种场景,实例临时挂了问题不大,重新注册就行,所以高可用更重要。配置变更不行,两个节点返回不同配置,应用行为就不一致了,所以必须强一致。

Redis Sentinel

Redis Sentinel 不是标准的 Raft 实现,但借鉴了 Raft 的核心思想。

Sentinel 节点之间通过心跳检测 Master 是否下线。先形成"主观下线"判断,再通过多数派确认形成"客观下线"共识。然后用类似 Raft 的投票机制选出一个 Sentinel Leader,由这个 Leader 执行故障转移。

区别在于 Sentinel 的选举是为了选一个执行故障转移的"指挥官",Raft 的选举是选数据复制的源头。目标不同,但投票和多数派的思想是一致的。

写在最后

Raft 的价值不在于做了什么前人没做过的事,而在于把一件复杂的事做到了人类能理解的程度。从 Paxos 到 Raft,工程界走了将近 25 年。

如果你在准备面试,Raft是分布式架构里很经典的协议,可以把 Raft 和 etcd、Nacos、Redis Sentinel、TiKV 这些中间件串起来讲,展现架构思维。告诉面试官你不光知道 Raft 是什么,还知道它在真实系统里是怎么用的、为什么这么用。

如果你觉得这篇文章有帮助,点赞关注,点点赞~

http://www.gsyq.cn/news/1398093.html

相关文章:

  • 游戏开发中的物理模拟:如何用梯度、散度和拉普拉斯算子模拟水流与烟雾?
  • Ventoy玩出新花样:一个U盘同时存Ubuntu系统和个人文件,互不干扰的终极指南
  • 别再乱升级GCC了!搞懂Linux动态库版本管理,彻底告别`GLIBCXX not found`噩梦
  • AI Agent到底是什么?从“聊天助手“到“行动主力“的跨越
  • C++ 数字:基础与进阶解析
  • 保姆级教程:用NVFlash在Windows 10/11下备份你的N卡VBIOS(以RTX 3060为例)
  • 保姆级教程:在Windows 10/11上从零编译ZLMediaKit流媒体服务器(含OpenSSL配置避坑)
  • 不止是组策略:用DISM命令探索Windows 10/11家庭版被隐藏的系统功能包
  • 图像去噪/超分论文复现必备:手把手教你用Python实现PSNR、SSIM、IEF、UQI的完整计算与可视化
  • 从比特币到以太坊:手把手教你用Python实现一个简易的Merkle树
  • 数据分析师证书在营销策划岗位中的重要性
  • 区块链钱包技术解析:架构、安全与前沿演进
  • 别急着招人,你的部门可能一个人就够了
  • 2026用友开发实战:集成leCast投屏与自定义模块tinyPlayer/androidBrowser(附源码)
  • 真理归来:论贾子之路对西方伪科学体系的终结与人类认知共同体的重建
  • 从‘武林秘籍’到实战代码:手把手教你用Python复现Gabor滤波器的纹理识别效果
  • 2026年西南地区输送带厂家选型与性价比实测分析:传送带输送机/工业输送带/橡胶输送带/煤矿皮带输送机/皮带机输送机/选择指南 - 优质品牌商家
  • 国星宇航三闯港交所:当“太空AI第一股”遇上AI搜索时代的IPO大考
  • 大型机与 JCL:那些现代云原生程序员完全无法理解的“黑魔法”
  • 别再为高维数据发愁了!用Python手把手教你实现粗糙集属性约简(附完整代码)
  • 从建模软件到Unity屏幕:一个Mesh的完整生命周期与内存管理避坑指南(附MeshFilter.mesh陷阱)
  • 业务日志入库实战指南
  • 别再只用默认地形了!用Unity Terrain Tools 2022打造从森林到湖泊的完整生态场景(附素材包)
  • 悄悄用 Go 重写 AI 基础设施:NVIDIA 的 GPU 云平台为何选择 Go?
  • 从美术资源到可动角色:聊聊Unity中序列帧动画的性能优化与最佳实践
  • 【2026白皮书】嵌入式IoT模组市场全景与选型指南:5G RedCap/端侧AI/NTN深度解析
  • OFC大菠萝6周踩坑日记
  • Visual Assist X 番茄助手破解安装详细教程与注意事项适用于亲测VS2019,VS2022,VS2026有效;软件适用于VS2010-VS2026
  • 告别Selenium!用Python+WinAppDriver搞定Windows桌面软件自动化测试(保姆级避坑指南)
  • 告别老师傅依赖:智能锯切系统如何降低车间操作门槛