面向面试编程:RocketMQ——持久化保存消息

316 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情

面试官:RocketMQ持久化保存消息了解过吗?

RocketMQ不只是让你写入消息或获取消息那么简单,他们本身最重要的就是提供强大的数据存储能力,可以把海量消息存储在自己服务器的磁盘上,如果不存储在磁盘上,都放在内存中,内存很有可能放不下,如果机器重启,内存中的消息就全部丢失了。

broker数据存储实际上才是MQ最核心的环节。它决定了生产者写入消息的吞吐量,决定了消息不能丢失,决定了消费者获取消息的吞吐量。

CommitLog消息顺序写入机制

当生产者的消息发送到一个broker上时,broker会把这个消息写入磁盘上的一个日志文件,叫做CommitLog。

为了让消息写入CommitLog时达到接近写内存的性能,broker引入了基于OS操作系统的pageCache和顺序写两个机制。 broker以顺序的方式将消息写入CommitLog,每次写入就是在文件末尾加一条数据,性能比随机写要提升很多。

其次broker写入CommitLog文件时,并不是直接写入底层的物理磁盘文件的,而是先进入OS的PageCache中,然后由OS的后台线程选一个时间,异步化的将缓存中的数据刷入磁盘文件。

这个策略基本上可以让消息写入CommitLog的性能跟直接写入内存差不多,可以让broker高吞吐量的处理每秒大量的消息写入。 异步刷盘虽然提高了吞吐量,但是有丢数据的风险。同步刷盘不会导致数据丢失。

ConsumeQueue

在broker中,对每个Topic下的MessageQueue都对应了一系列的ConsumeQueue文件,这个ConsumeQueue文件存储的是一条消息对应在CommitLog文件中的offset偏移量。

当Broker收到一条消息写入了CommitLog之后,其实他同时会将这条消息在CommitLog中的物理位置,也就是一个文件偏移量,就是一个offset,写入到这条消息所属的MessageQueue对应的ConsumeQueue文件中去。

所以实际上Topic的每个MessageQueue都对应了Broker机器上的多个ConsumeQueue文件,保存了这个MessageQueue的所有消息在CommitLog文件中的物理位置,也就是offset偏移量。