持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情
面试官:创建Topic时为什么要指定MessageQueue数量?
指定MessageQueue
要搞明白生产者工作的原理,需要明白MessageQueue是什么,需要把他跟topic以及broker综合起来看。创建Topic时需要指定MessageQueue数量,简单来说就只要指定这个Topic对应了多少个队列。
我们知道,每个Topic的数据都是分布式存储在多个broker中,但我们如何决定这个Topic的哪些数据存放在这个broker,哪些数据存放在另一个broker,所以在这里RocketMQ引入了MessageQueue的概念,本质上就是一个数据分片的机制。通过MessageQueue将一个Topic上的数据拆分为很多个数据分片,然后在每个broker上都存储一些MessageQueue,实现Topic数据分布式存储。
面试官:生产者发送消息时写入哪个MessageQueue?
写入MessageQueue
生产者会跟NameServer进行通信并获取Topic的路由数据,所以生产者从NameServer中可以知道一个Topic有几个MessageQueue,哪些MessageQueue在哪台broker机器上。
生产者会把消息写入不同的MessageQueue,通过这个方法,可以让生产者把写入请求分散给多个broker,分摊写入压力。通过这个方法,可以让一个Topic中的数据分散在多个MessageQueue中,进而分散在多个broker上,实现分布式存储。
面试官:如果某个broker出现故障怎么办?
broker故障
接下来我们分析一下,如果某个Broker临时出现故障了,比如Master Broker挂了,此时正在等待的其他Slave Broker自动热切换为Master Broker,那么这个时候对这一组Broker就没有Master Broker可以写入了。
如果你还是按照之前的策略来均匀把数据写入各个Broker上的MessageQueue,那么会导致你在一段时间内,每次访问到这个挂掉的Master Broker都会访问失败,这个似乎不是我们想要的样子。
对于这个问题,通常来说建议大家在Producer中开启一个开关,就是sendLatencyFaultEnable。一旦打开了这个开关,那么他会有一个自动容错机制,比如如果某次访问一个Broker发现网络延迟有500ms,然后还无法访问,那么就会自动回避访问这个Broker一段时间,比如接下来3000ms内,就不会访问这个Broker了。
这样的话,就可以避免一个Broker故障之后,短时间内生产者频繁的发送消息到这个故障的Broker上去,出现较多次数的异常。而是在一个Broker故障之后,自动回避一段时间不要访问这个Broker,过段时间再去访问他。那么这样过一段时间之后,可能这个Master Broker就已经恢复好了,比如他的Slave Broker切换为了Master可以让别人访问了。