Nacos distro协议简单解析

266 阅读4分钟

我们知道 Nacos 它是支持两种分布式定理的:CP(分区一致性)和 AP(分区可用性) 的,而 AP 是通过 Nacos 自研的 Distro 协议来保证的,CP 是通过 Nacos 的 JRaft 协议来保证的。

问题:Nacos 中哪些地方用到了 AP 和 CP?

  • 针对临时服务实例,采用 AP 来保证注册中心的可用性,Distro 协议。
  • 针对持久化服务实例,采用 CP 来保证各个节点的强一致性,JRaft 协议。(JRaft 是 Nacos 对 Raft 的一种改造)
  • 针对配置中心,无 Database 作为存储的情况下,Nacos 节点之间的内存数据为了保持一致,采用 CP。Nacos 提供这种模式只是为了方便用户本机运行,降低对存储依赖,生产环境一般都是通过外置存储组件来保证数据一致性。
  • 针对配置中心,有 Database 作为存储的情况下,Nacos 通过持久化后通知其他节点到数据库拉取数据来保证数据一致性,另外采用读写分离架构来保证高可用,所以这里我认为这里采用的 AP,欢迎探讨。
  • 针对 异地多活,采用 AP 来保证高可用。

一、Distro协议解析

Distro 协议 是 Nacos 自研的一种轻量级的一致性协议,主要用于服务的注册与发现。它是一种 AP(Availability and Partition tolerance)模型协议,适用于不需要严格一致性但需要高可用性的场景。

原理

Distro 协议通过将服务实例信息在多个节点间分片存储和同步,来实现服务的注册与发现的高可用性。它主要依赖于以下机制:

  1. 数据分片:将全量的服务实例数据分成多个片段,每个节点负责一部分数据的存储和管理。
  2. 数据同步:各个节点之间定期同步它们各自管理的服务实例数据,确保数据的最终一致性。

工作过程

  1. 服务注册:当一个服务实例注册到 Nacos 时,Nacos 会根据某种哈希算法将该实例分配到特定的节点上,这个节点负责该实例的数据管理。
  2. 数据同步:每个节点会定期将自己负责的服务实例数据同步到其他节点。这样,即使某个节点出现故障,其他节点也能够通过同步的数据继续提供服务注册与发现功能。
  3. 服务发现:客户端向 Nacos 查询服务时,Nacos 会根据现有的数据返回相应的服务实例信息。由于数据在多个节点上都有备份,查询请求可以从任意节点获得服务实例数据,提高了系统的可用性。

DistroClientComponentRegistry类进行协议的初始化

image.png

DistroClientDataProcessor 继承 SmartSubscriber 可以在监听到各种事件时进行数据同步

image.png

image.png 可以看到,不管是全部同步还是单个机器同步,最终的核心接口是sync

image.png

 sync 的核心逻辑

核心步骤

  • 遍历其他节点,创建一个同步的任务,加到 map 中。
  • 后台线程不断从 map 中拿到 task,然后移除这个 task。
  • 把这个 task 加到一个队列里面。
  • 有个 worker 专门从队列里面拿到 task 来执行。 具体流程看图:

image.png 大佬画的非常好,我就直接拿来了,大家感兴趣可以看原文:nacos.io/blog/articl…

二、JRaft 协议解析

JRaft 是一个基于 Raft 算法的 Java 实现,主要用于实现分布式系统中的一致性协议。Raft 算法是一种用于在分布式系统中管理日志复制的一致性算法。Nacos 使用 JRaft 来实现数据的一致性和高可用性。

原理

Raft 算法通过选举机制和日志复制来确保在分布式系统中各个节点的一致性。它主要分为三个角色:Leader、Follower 和 Candidate。

  1. Leader:负责处理客户端的请求,复制日志到所有 Follower,并确保所有节点数据的一致性。
  2. Follower:被动接收 Leader 的日志复制请求,并将日志应用到本地状态机。
  3. Candidate:在 Leader 选举过程中,如果 Follower 在一定时间内没有收到 Leader 的心跳,就会变成 Candidate 并发起选举。

工作过程

  1. Leader 选举:系统启动时,各个节点最初都是 Follower,如果在一段时间内没有收到 Leader 的心跳消息,Follower 节点会转变为 Candidate,并发起选举。Candidate 向其他节点发送投票请求,如果得到多数节点的同意,就成为 Leader。
  2. 日志复制:Leader 接收到客户端的请求后,将请求作为日志条目追加到本地日志,并并行地将日志条目发送到所有 Follower。Follower 接收到日志条目后,写入本地日志并回复 Leader。如果 Leader 收到了大多数 Follower 的确认,则认为日志条目已经提交,并将结果返回给客户端。
  3. 心跳机制:Leader 会周期性地向所有 Follower 发送心跳消息,保持领导地位并防止重新选举。