简单描述 namesrv 保存的信息
基本功能
- 生产者、消费者从 namesrv 中获取可用的 broker 地址(查询功能) 
- broker 定时向 naemsrv 发送心跳信息,维护可用 broker 地址(更新信息) 
- 保存 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 类重要的数据,所有数据都由一个读写锁保护
- topicQueueTable 
 保存 topic 信息,key 是 topic 名,QueueData 包含了队列信息。- 1 
 2
 3
 4
 5
 6
 7
 8
 9- HashMap<String, List<QueueData>> topicQueueTable; 
 class QueueData {
 private String brokerName; // broker 名字
 private int readQueueNums;
 private int writeQueueNums;
 private int perm;
 private int topicSynFlag;
 }
- brokerAddrTable 
 保存 broker 信息,key 是 broker name,BrokerData 包含了 broker 信息- 1 
 2
 3
 4
 5
 6
 7- HashMap<String, BrokerData> brokerAddrTable; 
 class BrokerData {
 private String cluster; // broker 所在集群名
 private String brokerName; // broker 名字
 private HashMap<Long/* brokerId */, String/* broker address */> brokerAddrs; // broker 地址(包括主从)
 }
- clusterAddrTable 
 保存 broker 集群信息,key 是集群名, set 保存了 broker namesrv- 1 - HashMap<String, Set<String>> clusterAddrTable; 
- brokerLiveTable 
 保存 broker 的存活信息,key 是 broker 的地址- 1 
 2
 3
 4
 5
 6
 7
 8- HashMap<String, BrokerLiveInfo> brokerLiveTable; 
 class BrokerLiveInfo {
 private long lastUpdateTimestamp; // 最后更新时间
 private DataVersion dataVersion; // 数据版本号
 private Channel channel; // 用于通信的 channel
 private String haServerAddr;
 }
- filterServerTable 
 保存 filter server,key 是 broker 的地址,list 里是 filter server- 1 - HashMap<String, List<String>> filterServerTable - 注:filter server 在 4.3.0 删除了 
broker 注册
broker 发送 REGISTER_BROKER 命令时,会带来brokerName、brokerAddr、clusterName、haServerAddr、brokerId 以及 topic 信息。这些信息会保存到 RouteInfoManager 中
注册过程如下:
- 上锁
- 修改 clusterAddrTable,需要 clusterName 和 brokerName 两个要素
- 修改 brokerAddrTable,由于 BrokerData 里保存了 brokerId,当发生主从切换时,要先删除原 slave 的 brokerData,再插入 新 master 的 BrokerData
- 如果 broker 是 master 并且带来了 topic 的信息, 则更新 topicQueueTable
- 更新 brokerLiveTable 的数据
- 更新 filterServerList
- 解锁
REGISTER_BROKER 命令的返回结果里会包含这组 broker 的 master 地址以及 master 的 HA 地址
Broker 存活检查
存活检查有两种方法
- NamesrvController 有个线程定期(10秒)调用 routeInfoManager.scanNotActiveBroker(),检查brokerLiveTable 中的 lastUpdateTimestamp。 
 如果 lastUpdateTimestamp + BROKER_CHANNEL_EXPIRED_TIME (2分钟)< 当前时间,则认为这个 broker 已经不再存活,并将之从 brokerLiveTable 删除。而 broker 周期性发送 REGISTER_BROKER 命令到 namesrv,namesrv 这时会更新 lastUpdateTimestamp
- BrokerHousekeepingService 侦听 Channel 事件,如果发生 close,exception, idle 等事件,也认为 broker 不再存活