NameServer作为RocketMQ的注册中心,主要存储了哪些信息,如何存储,信息有变更时如何通知出去的?下面我们带着这几个问题一起分析下NameServer

一,NameServer记录的信息
NameServer作为RocketMQ的注册中心,主要存储着队列与Topic关系列表,broker列表,集群与broker关系列表,当前存活的broker列表

public class RouteInfoManager {
    
    //Broker向NameServer上报心跳的最大时间
    private final static long BROKER_CHANNEL_EXPIRED_TIME = 1000 * 60 * 2;
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    //主题与队列的关系列表,其中队列里有读队列与写队列
    private final HashMap<String/* topic */, List<QueueData>> topicQueueTable;
    private final HashMap<String/* brokerName */, BrokerData> brokerAddrTable;//所有broker信息
    private final HashMap<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable;//每个集群包括哪些broker
    //当前存活broker,因为nameserver 10S扫描一次所以会有延迟
    private final HashMap<String/* brokerAddr */, BrokerLiveInfo> brokerLiveTable;
    //记录每个Broker分别使用了哪些消息过滤服务器
    private final HashMap<String/* brokerAddr */, List<String>/* Filter Server */> filterServerTable;

}
  • topicQueueTable:各topic属于那个broker上;每个topic下有多少队列;各队列的读写数量及权限
  • brokerAddrTable:各broker id与address关系,会区分broker的master与slave
  • clusterAddrTable:各cluster包含的broker
  • brokerLiveTable:当前存活的broker,会有一定的延迟
  • filterServerTable:每个Broker分别使用了哪些消息过滤服务器

如果上面的数据发生了变化NameServer如何处理呢?答案是通过BrokerHousekeepingService进行监听,它实现了ChannelEventListener接口,如果通道发生了变动,比如Nameserver与 Broker的连接通道在关闭、通道发送异常、通道空闲时,会触发BrokerHousekeepingService的回调,然后移除相应的Broker。

二,NameServer的工作机制
image.png
RocketMQ的路由信息主要是指Topic的队列信息,也就是队列分布在哪个Broker里。

  • NameServer 命名服务,集群部署,各节点间不通信
  • Broker 消息服务器,每隔30S向NameServer发送心跳信息
  • Producer,Consumer 消息客户端,同一时间内只会连一个NameServer服务器,每隔30S更新一次Topic信息

NameServer启动后会每隔10S扫描Broker集群,如果一定时间内(120S)内未收到Broker心跳信息,NameServer会将此Broker移除,以提高消息发送高可用。这就是典型的PULL模式,而ZK则是一种PUSH的模式,ZK是通过事件机制来实现的PUSH模式,这种模式一个优点就是具有实时性,一旦服务端有变动,客户端可以马上贴到ZK的通知,但这种强一制性是牺牲了可用性的,这会导致服务在一定时间内不可用。

但PULL模式也有它的问题,NameServer存储的路由信息如果发生了变化它不会主动通知客户端,面是需要客户端主动去拉取最新的路由信息(一定频率的定时任务拉取),这样显然是不及时的。RocketMQ是如何应对的呢?答案是通过客户端的重试与Broker的规避策略(可以参考前面写的RocketMQ学习四-消息发送高可用设计)。
我们可以分析下,如果NameServer集群信息不一致对消息发送端与消息消费端分别有什么影响。

  1. 对发送端的影响
    假设有如下场景:
    image.png
    因为一些原因Namerserver-2里的broker信息只有broker-a可以使用,对于消息发送端的Producer-1可以将消息发送到broker-a与broker-b两个broker上且Consumer-2可以正常消费,而Producer-2则只能将消息发送到broker-a上且Consumer-1只能消费到broker-a上的消息,这样后果是压力全在broker-a上,但服务还是可用的,经过人工干预后问题可以解决。所以NameServer集群路由信息不一致并不会导致消息发送不可用。
  2. 对消费端的影响(待定,这一块需要看完broker与consumer之后再写,需要弄清楚重复消费)

参考的文章:
RocketMQ4.0源码分析之-路由管理
Nameserver 背后的设计理念


步履不停
38 声望13 粉丝

好走的都是下坡路