• 已删除用户
Administrator
发布于 2021-10-19 / 9 阅读
0

Nacos 一致性协议

Nacos 在开源支持就定下了⼀个目标,尽可能的减少用户部署以及运维成本,做到用户只需要⼀个程序包,就可以快速以单机模式启动 Nacos 或者以集群模式启动 Nacos。而 Nacos 是⼀个需要存储数据的⼀个组件,因此,为了实现这个目标,就需要在 Nacos 内部实现数据存储。单机下其实问题不大,简单的内嵌关系型数据库即可;但是集群模式下,就需要考虑如何保障各个节点之间的数据⼀致性以及数据同步,而要解决这个问题,就不得不引入共识算法,通过算法来保障各个节点之间的数据的⼀致性。

为什么同时运行 CP 协议和 AP 协议

为什么 Nacos 会在单个集群中同时运行 CP 协议以及 AP 协议呢?这其实要从 Nacos 的场景出 发的:Nacos 是⼀个集服务注册发现以及配置管理于⼀体的组件,因此对于集群下,各个节点之间 的数据⼀致性保障问题,需要拆分成两个方面。

从服务注册发现来看

AP:可用性 + 分区容错

服务发现注册中心,在当前微服务体系下,是十分重要的组件,服务之间感知对方服务的当前可正常提供服务的实例信息,必须从服务发现注册中心进行获取,因此对于服务注册发现中心组件的可用性,提出了很高的要求,需要在任何场景下,尽最大可能保证服务注册发现能力可以对外提供服务;同时 Nacos 的服务注册发现设计,采取了心跳可自动完成服务数据补偿的机制。如果数据丢失的话,是可以通过该机制快速弥补数据丢失。

因此,为了满足服务发现注册中心的可用性,强⼀致性的共识算法这里就不太合适了,因为强⼀致性共识算法能否对外提供服务是有要求的,如果当前集群可用的节点数没有过半的话,整个算法直接“罢工”,而最终⼀致共识算法的话,更多保障服务的可用性,并且能够保证在⼀定的时间内各个节点之间的数据能够达成⼀致。

从配置管理来看

CP:一致性 + 分区容错

配置数据,是直接在 Nacos 服务端进行创建并进行管理的,必须保证大部分的节点都保存了此配置数据才能认为配置被成功保存了,否则就会丢失配置的变更,如果出现这种情况,问题是很严重的,如果是发布重要配置变更出现了丢失变更动作的情况,那多半就要引起严重的现网故障了,因此对于配置数据的管理,是必须要求集群中大部分的节点是强⼀致的,而这里的话只能使用强⼀致性共识算法。

为什么是 Raft 和 Distro

对于强⼀致性共识算法,当前工业生产中,最多使用的就是 Raft 协议,Raft 协议更容易让人理解, 并且有很多成熟的工业算法实现,比如蚂蚁金服的 JRaft、Zookeeper 的 ZAB、Consul 的 Raft、 百度的 braft、Apache Ratis;因为 Nacos 是 Java 技术栈,因此只能在 JRaft、ZAB、Apache Ratis 中选择,但是 ZAB 因为和 Zookeeper 强绑定,再加上希望可以和 Raft 算法库的支持团队随时沟通交流,因此选择了 JRaft,选择 JRaft 也是因为 JRaft 支持多 RaftGroup,为 Nacos 后面的多数据分片带来了可能。

Distro 协议是阿里巴巴自研的⼀个最终⼀致性协议,而最终⼀致性协议有很多,比如 Gossip、 Eureka 内的数据同步算法。而 Distro 算法是集 Gossip 以及 Eureka 协议的优点并加以优化而出来的,对于原生的 Gossip,由于随机选取发送消息的节点,也就不可避免的存在消息重复发送给同⼀节点的情况,增加了网络的传输的压力,也给消息节点带来额外的处理负载,而 Distro 算法引入了权威 Server 的概念,每个节点负责⼀部分数据以及将自己的数据同步给其他节点,有效的降低了消息冗余的问题。