NameServer负责维护Producer和Consumer的配置信息、状态信息,并且协调各个角色的协同执行。通过NameServer各个角色可以了解到集群的整体信息,并且他们会定期向NameServer上报状态。
在 org.apache.rocketmq.namesrv.routeinfo 包下的RouteInfoManager类中,定义了许多变量,通过5个HashMap变量存储和维护集群的状态信息
private final static long BROKER_CHANNEL_EXPIRED_TIME = 1000 * 60 * 2;
private final HashMap<String/* topic */, List<QueueData>> topicQueueTable;
private final HashMap<String/* brokerName */, BrokerData> brokerAddrTable;
private final HashMap<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable;
private final HashMap<String/* brokerAddr */, BrokerLiveInfo> brokerLiveTable;
private final HashMap<String/* brokerAddr */, List<String>/* Filter Server */> filterServerTable;
public class QueueData implements Comparable<QueueData> {
private String brokerName;//broker名
private int readQueueNums;//读取queue数量
private int writeQueueNums;//写入queue数量
private int perm;
private int topicSynFlag;//同步标识
}
public class BrokerData implements Comparable<BrokerData> {
private String cluster;
private String brokerName;
private HashMap<Long/* brokerId */, String/* broker address */> brokerAddrs;
}
class BrokerLiveInfo {
private long lastUpdateTimestamp;
private DataVersion dataVersion;
private Channel channel;
private String haServerAddr;
}
zookeeper是apache旗下用于分布式服务协调的开源软件,并且拥有选举机制,能够在master宕机时从slave中通过选举机制选出一台slave变成master。但是在NameServer的设计中,MasterBroker中没有一台拥有全部的Topic信息,消息分布平均,失去选举机制意义。其次,NameServer仅仅被用于存储集群的配置信息、元数据信息,不需要太复杂的功能,所以放弃重量级的zookeeper选择轻量级的NameServer。
在Broker中存在着两个角色:CommitLog和ConsumeQueue。
通过CommitLog和ConsumeQueue相互配合完成消息的存储。
消息的存储地址在配置文件中通过 storePathRootDir 进行配置。在存储路径下的存储目录结构如下
/home
└── rocketmq
├── store-a
│ ├── abort
│ ├── checkpoint
│ ├── commitlog
│ │ └── 00000000000000000000
│ ├── config
│ │ ├── consumerFilter.json
│ │ ├── consumerFilter.json.bak
│ │ ├── consumerOffset.json
│ │ ├── consumerOffset.json.bak
│ │ ├── delayOffset.json
│ │ ├── delayOffset.json.bak
│ │ ├── subscriptionGroup.json
│ │ ├── topics.json
│ │ └── topics.json.bak
│ ├── consumequeue
│ │ ├── OFFSET_MOVED_EVENT
│ │ │ └── 0
│ │ │ └── 00000000000000000000
│ │ ├── OrderTest
│ │ │ ├── 0
│ │ │ │ └── 00000000000000000000
│ │ │ ├── 1
│ │ │ │ └── 00000000000000000000
│ │ │ ├── 2
│ │ │ │ └── 00000000000000000000
│ │ │ └── 3
│ │ │ └── 00000000000000000000
│ ├── index
│ │ └── 20190722164917530
│ └── lock
可以看到在存储目录中有Commit Log、ConsumeQueue、index等, ConsumeQueue 目录中存储了所有的Topic信息,以及index索引文件。CommitLog采用顺序写、随机读的方式加快写入效率,并且由于ConsumeQueue中仅存储20字节的偏移量、Tags等,所以能够存进内存当中,读取速度也很快。
从生产者读取到消息后会将消息存储到本地磁盘,RocketMQ提供两个存储方式:同步刷盘和异步刷盘。
Broker的集群有master和slave两种角色,通过在配置文件中配置实现。Broker集群中master和slave区别如下:
在Broker组中,需要将master中的消息复制各个slave中以达到消息同步的目的。RocketMQ提供两种消息复制的机制:同步复制和异步复制。