高可用究竟指的是什么?请参考:关于高可用的系统
RocketMQ做了以下的事情来保证系统的高可用
多master部署,防止单点故障
消息冗余(主从结构),防止消息丢失
故障恢复(本篇暂不讨论)
那么问题来了:
怎么支持多broker的写?
怎么实现消息冗余?
下面分开说明这两个问题
多master集群这里强调出master集群,是因为需要多个broker set,而一个broker set只有一个master(见下文的“注意”),所以是master集群
broker有三种角色:ASYNC_MASTER、SYNC_MASTER和SLAVE,这些角色常用的搭配为:
ASYNC_MASTER、SLAVE:容许丢消息,但是要broker一直可用,master异步传输CommitLog到slave
SYNC_MASTER、SLAVE:不允许丢消息,master同步传输CommitLog到slave
ASYNC_MASTER:如果只是想简单部署则使用这种方式
master:负责消息的读写
slave:只负责读消息
SYNC_MASTER与ASYNC_MASTER的区别是sync会等待消息传输到slave才算消息写完成,而async不会同步等待,而是异步复制到slave
RocketMQ的架构图(原图地址)
注意:在RocketMQ里面有一个概念broker set,一个broker set由一个master和多个slave组成,一个broker set内的每个broker的brokerName相同。
在broker集群中每个master相互之间是独立,master之间不会有交互,每个master维护自己的CommitLog、自己的ConsumeQueue,但是每一个master都有可能收到同一个topic下的producer发来的消息
为了支持多master集群,需要解决几个问题:
namesrv怎么管理broker
producer发送消息的时候知道发送到哪一个broker(为什么是master)
1. namesrv怎么管理brokerbroker启动的时候会向namesrv注册自己的信息
// org.apache.rocketmq.broker.BrokerController#registerBrokerAll public synchronized void registerBrokerAll(final boolean checkOrderConfig, boolean oneway) { TopicConfigSerializeWrapper topicConfigWrapper = this.getTopicConfigManager().buildTopicConfigSerializeWrapper(); // 省略中间代码... RegisterBrokerResult registerBrokerResult = this.brokerOuterAPI.registerBrokerAll( this.brokerConfig.getBrokerClusterName(), this.getBrokerAddr(), this.brokerConfig.getBrokerName(), this.brokerConfig.getBrokerId(), this.getHAServerAddr(), topicConfigWrapper, this.filterServerManager.buildNewFilterServerList(), oneway, this.brokerConfig.getRegisterBrokerTimeoutMills()); // 省略中间代码... }