大规模服务一直向注册中心进行注册、发送心跳、服务发现,对于注册中心来说,高并发的读写请求压力是非常巨大的,通常注册中心是怎么保证高性能呢?
RocketMQ
RocketMQ的NameServer不仅作为Broker的注册中心,他还需要存储路由的基础信息,所以他维护了多个数据结,包括Topic消息队列路由信息、Broker基础信息、Broker集群信、Broker状态信息等。
也就是说在进行Broker注册、Broker删除的时候,是需要对多个数据结构进行修改。
在高并发场景下,RocketMQ是通过读写锁来对这些数据结构保障数据的安全性。在同一时刻,NameServer只能对一个Broker进行处理,但是在读的时候,却是可以多线程同时读取。
Nacos
Nacos为了防止高并发的读写,用了CopyOnWrite的思想,但是并不是说他就不加锁了,他会对Service进行细粒度的加锁。
由于CopyOnWrite会占用空间,Nacos复制的时候,仅针对相应的内存进行了复制,处理完成后,再把这部分内存替换回去。
Eureka
Eureka则使用了多级缓存,包括只读缓存、读写缓存、注册表。这里引用Eureka - 服务续约和注册、下线(Server)的图。
文章图片
Zookeeper
Zookeeper在并发量不是很大的情况是可以作为注册中心(在大数据领域更多的是作为一个协调器),但是在并发量很大的时候,他有以下不足。
Zookeeper是CP模型的,所以当服务注册的时候,必须有过半的Zookeeper节点保存成功,这个服务才算保存成功(但实际场景中,我们并不需要保持强一致性)。过半服务保存的时间相对单个节点来说,是比较耗时的。
而且CP模型在网络分区的时候,会造成部分服务无法进行注册,导致同一个区的服务因为注册中心的问题而无法正常使用。
【大军闲聊 -- 注册中心怎么保证高性能】Zookeeper通过长连接来进行活性探测,并通过Watch机制来通知服务,服务很大的时候,也给Zookeeper带来了一定的性能损耗。