NameServer保障数据一致性分析
简介
NameServer:名称服务,充当路由消息的提供者。生产者或消费者能够通过名字服务查找各主题相应的Broker IP列表。多个Namesrv实例组成集群,但相互独立,无状态,没有信息交换。
NameServer是一个非常简单的Topic路由注册中心,其角色类似Dubbo或者kafka中的zookeeper,Spring Cloud 中的 Eureka,NameServer支持Broker的动态注册与发现。主要包括两个功能:
Broker管理,NameServer接受Broker集群的注册信息并且保存下来作为路由信息的基本数据。然后提供心跳检测机制,检查Broker是否还存活。
路由信息管理,每个NameServer将保存关于Broker集群的整个路由信息和用于客户端查询的队列信息。Producer在投递消息之前和Conumser在拉取消息之前,都会通过NameServer获取整个Broker集群的路由信息,从而进行消息的投递和消费。
设计考量
作为命名服务,有些组件会选用zk作为一致性存储的中间件,保障数据的强一致性。
但NameServer保障数据的最终一致性,以提升系统可用性,因此,RocketMQ自制的NameServer实现的是AP。
由此,RocketMQ的架构设计决定了只需要一个轻量级的元数据服务器就足够了,只需要保持最终一致,因此,RocketMQ决定使用自制的NameServer来实现简单的路由管理服务,将元数据存储在RocketMQ内部,设计很简单,非常的轻量级。NameServer 集群间互不通信,因此它们之间的注册信息可能会不一致,这是一种去中心化的架构,所有注册信息保存在内存中(无状态),一台NameServer挂了也没关系,从另一台NameServer上拉取数据即可。
如何做到nameserver不去做信息交换?
总体流程
启动NameServer,NameServer起来后监听端口,等待Broker、Producer、Consumer连上来,相当于一个路由控制中心。
Broker启动,跟所有的NameServer保持长连接,定时发送心跳包。心跳包中包含当前Broker信息(IP+端口等)以及存储所有Topic信息。注册成功后,NameServer集群中就有Topic跟Broker的映射关系。
收发消息前,先创建Topic,创建Topic时需要指定该Topic要存储在哪些Broker上,也可以在发送消息时自动创建Topic。
Producer发送消息,启动时先跟NameServer集群中的其中一台建立长连接,并从NameServer中获取当前发送的Topic存在哪些Broker上,轮询从队列列表中选择一个队列,然后与队列所在的Broker建立长连接从而向Broker发消息。
Consumer跟Producer类似,跟其中一台NameServer建立长连接,获取当前订阅Topic存在哪些Broker上,然后直接跟Broker建立连接通道,开始消费消息。