微服务注册中心Eureka、zooKeeper、consul、Nacos对比

微服务注册中心Eureka、zooKeeper、consul、Nacos对比

CAP理论

CAP理论是分布式架构中的重要理论,以上四种工具的核心区别就在于对于CAP理论体现的不一致。

在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

分区容错性(可靠性)

大多数的分布式系统都分布在多个子网络(区),不同的区之间可能会通信失败。

 

微服务注册中心Eureka、zooKeeper、consul、Nacos对比

 

例如,在上图中,G1向G2发信息,G2 可能无法收到。系统设计的时候,必须考虑到这种情况。一般来说,分区容错无法避免,因此可以认为 CAP 的 P 总是成立。CAP 定理告诉我们,剩下的 C 和 A 无法同时做到。

一致性

意思是,写操作之后的读操作,必须返回该值。举例来说,某条记录是 v0,用户向 G1 发起一个写操作,将其改为 v1。

微服务注册中心Eureka、zooKeeper、consul、Nacos对比

接下来,用户的读操作就会得到 v1。这就叫一致性。

微服务注册中心Eureka、zooKeeper、consul、Nacos对比

但问题在于,用户有可能向 G2 发起读操作,由于 G2 的值没有来得及发生变化,因此返回的是 v0。G1 和 G2 读操作的结果不一致,这就不满足一致性了。

微服务注册中心Eureka、zooKeeper、consul、Nacos对比

为了让 G2 也能变为 v1,就要在 G1 写操作的时候,让 G1 向 G2 发送一条消息,要求 G2 也改成 v1。

微服务注册中心Eureka、zooKeeper、consul、Nacos对比

可用性

意思是只要收到用户的请求,服务器就必须给出回应。

用户可以选择向 G1 或 G2 发起读操作。不管是哪台服务器,只要收到请求,就必须告诉用户,到底是 v0 还是 v1,否则就不满足可用性。

一致性(C)与可用性(A)的矛盾

一致性和可用性,为什么不可能同时成立?答案很简单,因为可能通信失败(即出现分区容错)。

如果保证 G2 的一致性,那么 G1 必须在写操作时,锁定 G2 的读操作和写操作。只有数据同步后,才能重新开放读写。锁定期间,G2 不能读写,没有可用性。

如果保证 G2 的可用性,那么势必不能锁定 G2,所以一致性不成立。

综上所述,G2 无法同时做到一致性和可用性。系统设计时只能选择一个目标。如果追求一致性,那么无法保证所有节点的可用性;如果追求所有节点的可用性,那就没法做到一致性。

总结

  1. 分区容错性/可靠性P:不同地区的同一个系统的集群,集群间的通信可能失败(必然事件)

  2. 一致性C:同一时间请求集群中任何一个节点,返回的数据一致

  3. 可用性A:集群中的每个节点,任何时候都是可用的

Eureka

Eureka强调了CAP理论中的AP,即可用性和可靠性,一致性方面保证的是弱一致性,只能保证最终的一致性。

Eureka的弱一致性

Eureka为了保证高可用,在任何时候,服务消费者都能正常获取服务列表,但不保证数据的强一致性,消费者可能会拿到过期的服务列表。Eureka为保证其弱一致性,在数据同步时采用的是对等复制(Peer to Peer)。副本间不分主从,任何副本都可以接收写操作,然后每个副本间互相进行数据更新。对等复制模式,任何副本都可以接收写请求,不存在写压力瓶颈,但各个副本间数据同步时可能产生数据冲突。

与之相对的是主从复制Master-Slave 模式,有一个主副本,其他为从副本,所有写操作都提交到主副本,再由主副本更新到其他从副本。写压力都集中在主副本上,是系统的瓶颈,从副本可以分担读请求。

ZooKeeper

ZooKeeper强调了CAP理论中的CP,即一致性与可靠性,任何时候对 Zookeeper 的访问请求能得到一致的数据结果,同时系统对网络分割具备容错性,但是 Zookeeper 不能保证每次服务请求都是可达的。

从 Zookeeper 的实际应用情况来看,在使用 Zookeeper 获取服务列表时,如果此时的 Zookeeper 集群中的 Leader 宕机了,该集群就要进行 Leader 的选举,又或者 Zookeeper 集群中半数以上服务器节点不可用(例如有三个节点,如果节点一检测到节点三挂了 ,节点二也检测到节点三挂了,那这个节点才算是真的挂了),那么将无法处理该请求。所以说,Zookeeper 不能保证服务可用性。

当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30~120s,而且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署环境下, 因为网络问题使得zk集群失去master节点是大概率事件,虽然服务能最终恢复,但是漫长的选举事件导致注册长期不可用是不能容忍的。

Consul

Consul 遵循CAP原理中的CP,保证了强一致性和分区容错性,且使用的是Raft算法,比zookeeper使用的Paxos算法更加简单。虽然保证了强一致性,但是可用性就相应下降了,例如服务注册的时间会稍长一些,因为 Consul 的 raft 协议要求必须过半数的节点都写入成功才认为注册成功 ;在leader挂掉了之后,重新选举出leader之前会导致Consul 服务不可用。

Nacos

Nacos是阿里开源的,Nacos 支持基于 DNS 和基于 RPC 的服务发现。在Spring Cloud中使用Nacos,只需要先下载 Nacos 并启动 Nacos server,Nacos只需要简单的配置就可以完成服务的注册发现。

Nacos除了服务的注册发现之外,还支持动态配置服务。动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。

一句话概括就是Nacos = Spring Cloud注册中心 + Spring Cloud配置中心。

主流注册中心产品对比

微服务注册中心Eureka、zooKeeper、consul、Nacos对比

 

使用区别

性能和容量

Eureka在实例数达到5000左右时,就会出现服务不可用的问题。而Zookeeper和Nacos能够达到百万级,这部分的性能不是说越高越好,提高这些性能都是在其它方面做出了牺牲的。

易用性

易用性包括多方面的工作,例如API和客户端的接入是否简单,文档是否齐全易懂,控制台界面是否完善等。对于开源产品来说,还有一块是社区是否活跃。Zookeeper的易用性是比较差的,Zookeeper的客户端使用比较复杂,没有针对服务发现的模型设计以及相应的API封装,需要依赖方自己处理。对多语言的支持也不太好,同时没有比较好用的控制台进行运维管理。

从目前来看(2020年初),Eureka和Nacos有针对服务注册与发现的客户端,也有基于SpringCloud体系的starter,帮助用户以非常低的成本无感知的做到服务注册与发现。同时还暴露标准的HTTP接口,支持多语言和跨平台访问。从社区活跃度的角度来看,目前由于Zookeeper和Eureka的存量用户较多,很多教程以及问题排查都可以在社区搜索到,这方面新开源的Nacos还需要随着时间继续沉淀。综合考虑,Eureka的易用性最高。

集群扩展性

集群扩展性和集群容量以及读写性能关系紧密。当使用一个比较小的集群规模就可以支撑远高于现有数量的服务注册及访问时,集群的扩展能力暂时就不会那么重要。从协议的层面上来说,Zookeeper使用的ZAB协议,由于是单点写,在集群扩展性上不具备优势。Eureka在协议上来说理论上可以扩展到很大规模,因为都是点对点的数据同步,但是从我们对Eureka的运维经验来看,Eureka集群在扩容之后,性能上有很大问题。

参考:

https://cloud.tencent.com/developer/article/1522802

https://blog.csdn.net/fly910905/article/details/100023415

https://blog.csdn.net/weixin_41838683/article/details/85010565