携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情
RockerMQ有两处地方使用到读写分离机制
Broker Master-Slave读写分离
写消息到Master,异步同步到Slave,然后从Slave读取消息。
开启配置为:
slaveReadEnable=True
Broker Direct Memory-Page Cache读写分离
在开启这个机制的时候,写消息会写到Direct Memory,读消息的时候会从操作系统的Page Cache读取。
page cache,又称pcache,其中文名称为页高速缓冲存储器,简称页高缓。page cache的大小为一页,通常为4K。
开启配置为:
transientStorePoolEnable=True
Broker Master-Slave读写分离
这个机制的实现,分为两个步骤:
1 第一步
Broker在处理Pull消息的时候会判断下次是否从slave读取消息。看代码。
long diff = maxOffsetPy - maxPhyOffsetPulling;
long memory = (long) (StoreUtil.TOTAL_PHYSICAL_MEMORY_SIZE
* (this.messageStoreConfig.getAccessMessageInMemoryMaxRatio() / 100.0));
getResult.setSuggestPullingFromSlave(diff > memory);
maxOffsetPy是当前Master Broker存储的所有消息的最大物理位点。
maxPhyOffsetPulling是拉取的消息的最大物理位点
diff是两者的差值,那么就是没有消费的消息数量
StoreUtil.TOTAL_PHYSICAL_MEMORY_SIZE是当前Master Broker全部的物理内存大小
this.messageStoreConfig.getAccessMessageInMemoryMaxRatio可以配置,默认是40,也就是说分配百分之40的内存作为Broekr的临界值,当大于这个临界值时,认定Broker处于一个比较繁忙的状态。
memory就是Broker临界值下认可使用的内存大小。
在这个前提下,若是diff>memory为true 那么表示没有拉取的消息占用的内存比认定可以使用的内存大,说明Master节点处于比较繁忙的状态,下一次拉取消息的时候将从Slave节点拉取消息。
public void setSuggestPullingFromSlave(boolean suggestPullingFromSlave) {
this.suggestPullingFromSlave = suggestPullingFromSlave;
}
判断完之后,给suggestPullingFromSlave赋值,true或者false
也就是说,在每次从Master节点拉取消息的时候,都会判断Broker Master节点的状态,若是Master上尚未读取的消息较多,超过设定的阈值,那么下一次拉取消息的时候,将从Slave节点拉取。
第二步
当消费者Pull消息返回结果的时候,根据上边代码设置的isSuggestPullingFromSlave来判断下一次获取消息的位置。
if (this.brokerController.getBrokerConfig().isSlaveReadEnable() && !this.brokerController.getBrokerConfig().isInBrokerContainer()) {
if (getMessageResult.isSuggestPullingFromSlave()) {
responseHeader.setSuggestWhichBrokerId(subscriptionGroupConfig.getWhichBrokerWhenConsumeSlowly());
}
else {
responseHeader.setSuggestWhichBrokerId(subscriptionGroupConfig.getBrokerId());
}
} else {
responseHeader.setSuggestWhichBrokerId(MixAll.MASTER_ID);
}
isSlaveReadEnable就是我们设置的配置slaveReadEnable=true
isInBrokerContainer是这样解释的,如果是BrokerStartup启动的Broker,就是false,如果是BrokerContainer启动的就是true。
所以这里要求的是BrokerStartup启动的Broker,开启了slaveReadEnable开关,isSuggestPullingFromSlave为true的时候,下次将从Slave读取消息。
setSuggestWhichBrokerId(1)表示从Slave读取,为0则是从Master读取。
读写分离能很大程度上提高吞吐量,但也会造成数据不一致的风险,