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

Raft 协议在 Nacos 中的实现

在 Nacos 中,服务注册表和配置中心的数据必须在多节点集群中保持一致。如果数据不一致,就可能导致某些消费者拿到过期实例,部分服务调用失败,甚至配置错乱。
为了解决这一问题,Nacos 在 2.x 版本中引入了 Raft 协议,用于集群内的数据一致性维护。相比 ZooKeeper 的 ZAB 协议,Raft 更易理解、实现更简单。

一、Raft的优势

在 Nacos 1.x 版本中,数据一致性依赖 MySQL + 数据库锁的方式。但随着服务规模增长,这种方案的问题逐渐暴露:

  • 写放大严重:所有节点必须落库,写入性能瓶颈明显

  • 脑裂风险高:数据库锁并不能完全避免分区导致的数据不一致

  • 可用性不足:数据库成为单点,宕机即导致注册中心瘫痪
    。 2.x,Nacos 引入了 Raft 协议 来替代数据库锁。Raft 具有以下特征:

  • 强一致性:依赖 Leader 节点顺序提交日志

  • 高可用性:只要超过半数节点存活,集群即可正常工作

  • 实现简单:相比 Paxos,Raft 的状态转换更直观

二、总体架构

在 Nacos 中,Raft 主要用于 Naming ServiceConfig Service 的数据同步。Nacos 集群节点通过 Raft 协议选举出一个 Leader,所有的写操作(注册、下线、配置更新)必须经由 Leader 提交,再同步到 Follower 节点。

Nacos 集群
AppendEntries
AppendEntries
ACK
ACK
注册服务
查询实例
查询实例
Follower1
Leader
Follower2
客户端
客户端
  • Leader 负责写:所有写请求都路由到 Leader
  • Follower 负责同步:从 Leader 接收日志并保持状态一致
  • 查询可从任意节点:Nacos 客户端默认支持就近查询

三、Raft 协议的核心流程

Nacos 中 Raft 协议主要包含三个核心过程:Leader 选举、日志复制、故障恢复

3.1 Leader 选举机制

当 Nacos 集群启动或 Leader 宕机时,集群会自动触发选举。

触发条件

  • 集群启动初期,无 Leader 节点
  • Leader 心跳超时(默认 5 秒)
  • 网络分区导致 Leader 不可达

选举流程

Follower1Follower2Follower3超时触发选举RequestVote(term=2)RequestVote(term=2)投票同意投票同意获得多数票 ->> 成为LeaderAppendEntries 心跳AppendEntries 心跳Follower1Follower2Follower3

源码解析
在 Nacos 2.x 中,Raft 逻辑位于 com.alibaba.nacos.core.distributed.raft 包内。
触发选举的关键逻辑在 RaftCore

if (leader == null || isLeaderDown()) {currentTerm.incrementAndGet();becomeCandidate();sendVoteRequests();
}
  • 采用随机超时时间避免选票冲突
  • 至少过半节点同意才能成为 Leader
  • 新 Leader 立即向其他节点发送 AppendEntries 心跳,避免二次选举

3.2 日志复制与提交

当客户端发起写请求(例如注册服务或更新配置)时,请求首先路由到 Leader。Leader 会将变更封装为一条 Raft 日志,并通过 AppendEntries RPC 推送到所有 Follower。

ClientLeaderFollower1Follower2注册实例 {ip=10.1.1.1, port=8080}AppendEntries(logId=101)AppendEntries(logId=101)ACKACK提交日志注册成功ClientLeaderFollower1Follower2
  • Leader 等待超过半数 Follower 返回 ACK 才能提交日志
  • 提交日志后才更新状态机并返回客户端结果
  • Follower 会顺序存储日志,保证状态机在所有节点上一致

源码解读
日志追加核心类是 com.alibaba.nacos.core.distributed.raft.RaftLogProcessor

public void appendLog(RaftLog log) {// 本地写入日志localStorage.append(log);// 异步同步到其他Followerfor (Peer peer : peers) {if (!peer.equals(self)) {sendAppendEntries(peer, log);}}
}

3.3 故障恢复与脑裂处理

Raft 的一个优势是天然避免脑裂。在 Nacos 中,如果 Leader 宕机或网络分区,Raft 会自动选出新 Leader,并保证日志不会回退。

场景一:Leader 宕机

  • Follower 检测到心跳超时
  • 重新发起选举
  • 新 Leader 从已提交日志开始同步,不影响一致性

场景二:网络分区

  • 被隔离的旧 Leader 会因为拿不到多数派投票而自动降级为 Follower
  • 其他节点选出新 Leader,继续处理写请求
  • 网络恢复后,旧 Leader 会通过日志追赶机制同步最新状态

四、Nacos 中 Raft 的实现细节

相比原生 Raft,Nacos 做了很多优化。

4.1 多 Raft Group 设计

在 Nacos 2.x 中,不同的服务命名空间和配置分片对应不同的 Raft Group。这样做有两个好处:

  • 写入隔离:不同服务间的注册操作互不干扰
  • 扩展性更强:单个 Raft Group 压力不会成为瓶颈
RaftGroupMember group = raftCore.getRaftGroup("naming_service");
group.appendLog(new RaftLog("REGISTER", instanceMeta));

4.2 长连接与增量推送

传统 Raft 协议基于短连接 RPC,而 Nacos 在此基础上引入了 gRPC 长连接

  • Follower 启动时与 Leader 建立长连接
  • 日志变更通过流式推送,降低握手成本
  • 支持增量日志同步,而非全量拉取

4.3 本地快照与故障快速恢复

当 Raft 日志过多时,Nacos 会定期做本地快照(Snapshot):

  • 快照文件存储最新状态机数据
  • 新节点加入时,可以直接加载快照,而不必从零回放日志
  • Leader 崩溃重启时,可以从快照恢复,大幅缩短恢复时间
snapshotManager.saveSnapshot(currentState);
http://www.xdnf.cn/news/1424971.html

相关文章:

  • 从零开始实现Shell | Linux进程调度实战
  • Product Hunt 每日热榜 | 2025-09-01
  • 基于YOLOv11的脑卒中目标检测及其完整数据集——推动智能医疗发展的新机遇!
  • 齿轮里的 “双胞胎”:分度圆与节圆
  • [React]监听Form中某个字段的变化
  • 微算法科技(NASDAQ:MLGO)张量网络与机器学习融合,MPS分类器助力顶夸克信号识别
  • deepseek doubao chatgpt 优缺点分析
  • 并发--并发中的线程状态及不同状态下线程所在队列
  • React学习教程,从入门到精通, React 入门指南:创建 React 应用程序的语法知识点(7)
  • OpenCV-CUDA 图像处理
  • 数据库常见故障类型
  • 知识产品和标准化
  • 在 Qt 中加载 .qm 翻译文件
  • 跳跃游戏(二):DFS 求解最少跳跃次数与最优路径
  • 专项智能练习(Word)
  • JavaSE:抽象类和接口
  • 计算机视觉(五):blur
  • 原子操作(Atomic Operation) 是指不可被中断的操作——要么完整执行,要么完全不执行
  • 贵州在假期及夏天结束后保持旅游活力的策略分析
  • AI如何重塑电力工程设计?揭秘良策金宝AI的六大“超能力”
  • SQLSERVER关键字:N
  • VBA数据库解决方案第二十二讲:根据工作表数据生成数据库中数据表
  • 算法练习——189.轮转数组
  • 【逆序对 博弈】P10737 [SEERC 2020] Reverse Game|普及+
  • 【开题答辩全过程】以 基于JSP的养生网站设计与实现为例,包含答辩的问题和答案
  • MySQL 中 InnoDB 引擎的事务隔离级别与“可重复读”隔离级别下的 SQL 编写规范
  • Linux 进程间通信(IPC)
  • 大型语言模型微调 内容预告(69)
  • 【Docker】2025版Ubuntu 22.04 安装 Docker Docker Compose 指南
  • 电力工程师的AI时代已来,这6大功能彻底颠覆传统工作模式