【阅读笔记】rocketmq 命名服务 namesrv (三)

简单描述 namesrv 保存的信息

  1. 生产者、消费者从 namesrv 中获取可用的 broker 地址(查询功能)

  2. broker 定时向 naemsrv 发送心跳信息,维护可用 broker 地址(更新信息)

  3. 保存 key-value 配置信息

namesrv 的功能比较简单,就是保存信息。多个 namesrv 实例组成集群,但相互独立,没有信息交换

功能实现

KVConfig

KVConfig 保存 key-value 配置,核心的数据结构是 KVConfigManager。 KVConfigManager 的主要成员有

  • ReadWriteLock lock:一个读写锁,保护 configTable 成员
  • HashMap<String, HashMap<String, String>> configTable:一个二维的散列表,第一个 key 是 Namespace,第二个 key 是 Key,之后是 value

KVConfigManager 的数据可以写到磁盘并从磁盘加载

保存 broker 信息

broker 信息由 RouteInfoManager 类管理

RouteInfoManager 有 5 个表,分别保存 5 类重要的数据,所有数据都由一个读写锁保护

  1. HashMap<String, List> topicQueueTable
    保存 topic 信息,key 是 topic 名,QueueData 包含了队列信息。

    1
    2
    3
    4
    5
    6
    7
    class  {
    private String brokerName;
    private int readQueueNums;
    private int writeQueueNums;
    private int perm;
    private int topicSynFlag;
    }
  2. HashMap<String, BrokerData> brokerAddrTable
    保存 broker 信息,key 是 broker name,BrokerData 包含了 broker 信息

    1
    2
    3
    4
    5
    class BrokerData {
    private String cluster;
    private String brokerName; // broker 名字
    private HashMap<Long/* brokerId */, String/* broker address */> brokerAddrs; // broker 地址(包括主从)
    }
  3. HashMap<String, Set> clusterAddrTable
    保存 broker 集群信息,key 是集群名, set 保存了 broker namesrv

  4. HashMap<String, BrokerLiveInfo> brokerLiveTable
    保存 broker 的存活信息,key 是 broker 的地址

    1
    2
    3
    4
    5
    6
    class BrokerLiveInfo {
    private long lastUpdateTimestamp; // 最后更新时间
    private DataVersion dataVersion; // 数据版本号
    private Channel channel; // 用于通信的 channel
    private String haServerAddr;
    }
  5. HashMap<String, List> filterServerTable
    保存 filter server,key 是 broker 的地址,list 里是 filter server
    filter server 在 4.3.0 删除了

broker 注册

broker 发送 REGISTER_BROKER 命令时,会带来brokerName、brokerAddr、clusterName、haServerAddr、brokerId 以及 topic 信息。这些信息会保存到 RouteInfoManager 中

注册过程如下:

  1. 上锁
  2. 修改 clusterAddrTable,需要 clusterName 和 brokerName 两个要素
  3. 修改 brokerAddrTable,由于 BrokerData 里保存了 brokerId,当发生主从切换时,要先删除原 slave 的 brokerData,再插入 新 master 的 BrokerData
  4. 如果 broker 是 master 并且带来了 topic 的信息, 则更新 topicQueueTable
  5. 更新 brokerLiveTable 的数据
  6. 更新 filterServerList
  7. 解锁

REGISTER_BROKER 命令的返回结果里会包含这组 broker 的 master 地址以及 master 的 HA 地址

Broker 存活检查

存活检查有两种方法

  1. NamesrvController 有个线程定期(10秒)调用 routeInfoManager.scanNotActiveBroker(),检查brokerLiveTable 中的 lastUpdateTimestamp。
    如果 lastUpdateTimestamp + BROKER_CHANNEL_EXPIRED_TIME (2分钟)< 当前时间,则认为这个 broker 已经不再存活,并将之从 brokerLiveTable 删除。而 broker 周期性发送 REGISTER_BROKER 命令到 namesrv,namesrv 这时会更新 lastUpdateTimestamp

  2. BrokerHousekeepingService 侦听 Channel 事件,如果发生 close,exception, idle 等事件,也认为 broker 不再存活