5000 字| 揭秘 Nacos 的 AP 架构 「Distro 一致性协议」(二)
三、定时同步:如何保持数据一致性
3.1 为什么需要定时同步
在 Nacos 集群模式下,它作为一个完整的注册中心,必须具有高可用特性。
在集群模式下,客户端只需要和其中一个 Nacos 节点通信就可以了,但是每个节点其实是包含所有客户端信息的,这样做的好处是每个 Nacos 节点只需要负责自己的客户端就可以(分摊压力),而当客户端想要拉取全量注册表到本地时,从任意节点都可以读取到(数据一致性)。
那么 Nacos 集群之间是如何通过 Distro 协议来保持数据一致性的呢?
3.2 定期检验元数据
在版本 v1 中 ,采用的是定期检验元信息的方式。元信息就是当前节点包含的客户端信息的 md5 值。
检验的原理如下图所示:Nacos 各个节点会有一个心跳任务,定期向其他机器发送一次数据检验请求,在校验的过程中,当某个节点发现其他机器上的数据的元信息和本地数据的元信息不一致,则会发起一次全量拉取请求,将数据补齐。
请求 URL:
http://其他 Nacos 节点的 IP:port/nacos/v1/ns/distro/checksum?source = 本机的IP地址:本机的端口号
参数:DistroData,内部包装的是一个Map<服务名称,服务下实例的验证字符串 checksum>
3.3 关于版本迭代的说明
在版本 v2 中,定期校验数据已经不用了,采用的是健康检查机制,来和其他节点来保持数据的同步,由于涉及的内容还挺多,放到下一讲来专门讲解 Nacos 的健康检查机制:
• 客户端与 Nacos 节点的健康检查机制。
• 集群模式下的健康检查机制。
四、新节点同步机制,如何保持数据一致性
4.1 原理
新加入的 Distro 节点会进行全量数据拉取,轮询所有的 Distro 节点,向其他节点发送请求拉取全量数据。
在全量拉取操作完成之后,每台机器上都维护了当前的所有注册上来的非持久化实例数据。4.2 源码分析
DistroProtocol 类的构造方法会启动一个同步任务,从其他 Nacos 节点全量拉取非持久化实例数据。
/nacos/core/distributed/distro/DistroProtocol.java
startDistroTask();
startLoadTask();
/nacos/core/distributed/distro/task/load/DistroLoadDataTask.java
run();
load();
loadAllDataSnapshotFromRemote();
五、本地读机制
5.1 原理
每个 Nacos 节点虽然只负责属于自己的客户端,但是每个节点都是包含有所有的客户端信息的,所以当客户端想要查询注册信息时,可以直接从请求的 Nacos 的节点拿到全量数据。
读操作的原理
这样设计的好处是保证了高可用(AP),分为两个方面:
• ① 读操作都能进行及时的响应,不需要到其他节点拿数据。
• ② 当脑裂发生时,Nacos 的节点也能正常返回数据,即使数据可能不一致,当网络恢复时,通过健康检查机制或数据检验也能达到数据一致性。
六、总结
本篇通过原理图 + 源码的方式讲解了 Distro 协议的原理,其中又分为几个机制,而这几个机制共同保证了 Nacos 的 AP。
不足之处,本篇未针对源码的设计进行深入剖析,只是把主线捋出来了。如文中有问题,欢迎探讨~
后续:详解 Nacos 的定期同步:心跳机制。