一、前言

        RocketMQ的刷盘机制是一种确保消息可靠性的机制,简单来说就是Broker收到消息后,将消息存储到磁盘上。这样可以解决几个问题:

  1. 存储空间问题。内存空间有限,存入磁盘可以维护更多消息。
  2. 消息可靠性问题。消息存入磁盘后,即使断电了,重启后便可恢复消息。

二、刷盘机制原理

        RocketMQ的刷盘机制原理可以参考下图。下图为官方文档的原理图,主要说明两种刷盘机制:左图是同步刷盘机制,右图是异步刷盘机制。

 

1、同步刷盘

        上面左图代表同步刷盘机制。消息从Producder端发送出去后,被Broker接收,Broker接收到消息后将消息写入内存的PageCache后,立即通知刷盘线程进行刷盘,当前线程等待刷盘线程的通知。刷盘线程开始进行刷盘操作,刷盘完毕后唤醒之前等待的线程,再返回写成功状态,最后Producer会收到消息发送成功的ACK。

2、异步刷盘

        右图代表异步刷盘机制。消息从Producder端发送出去后,被Broker接收到,Broker端接收到消息后,消息被写入PageCache后立即返回写成功给Producer端。然后另一个异步线程专门会将PageCache中的数据写到磁盘里,确保消息的持久化。

3、同步和异步刷盘的比较

        从上图的比较可以发现同步和异步刷盘的主要区别在于消息写入PageCache后是否立即返回写状态。可以从几个维度分析两者的差异:

  • 吞吐量。由于异步刷盘在写入PageCache后立即返回,没有经历IO操作,因此吞吐量比同步刷盘的高很多。
  • 可靠性。同步刷盘是在完全写磁盘成功后才算成功,而异步刷盘是写入PageCache就返回,PageCache本质就是内存,假如在异步线程写磁盘之前机器断电了,消息还是可能丢失的,因此可靠性方面同步刷盘较高。
  • 性能方面。同步刷盘写入磁盘后才算成功,而异步刷盘只需要写入内存就算成功,因此异步刷盘性能高于同步刷盘。
  • 适用场景。同步刷盘可靠性高,因此适用金融等对数据要求较高的场景。异步刷盘可靠性相对来说低一些,但是性能好,因此适合要求高吞吐和高性能的场景。

4、刷盘机制配置

        刷盘方式可以通过Broker配置文件里的flushDiskType参数设置,这个参数有两种值:

  • SYNC_FLUSH (同步刷盘)。
  • ASYNC_FLUSH (异步刷盘)。

三、主流MQ刷盘机制对比

        目前很多主流MQ都有自己的刷盘机制,可以从下表对比其中的差异。

MQ名

刷盘机制

刷盘配置

RocketMQ

同步刷盘、异步刷盘

Broker配置文件里的flushDiskType里配置

Kafka

默认异步刷盘,可以通过修改参数变成同步刷盘

Broker配置

  1. log.flush.interval.messages:多少条消息刷盘一次
  2. log.flush.interval.ms:刷盘间隔时间
  3. log.flush.scheduler.interval.ms:周期性刷盘

RabbitMQ

异步持久化:根据时间段批量将内存中的数据刷新到磁盘

  1. 队列持久化:queue_declare创建队列时声明durable=true
  2. 消息持久化:调用basic_publish方法时的属性delivery_mode=2。

四、总结

        本文主要介绍了RocketMQ的刷盘机制,从多个维度对比RocketMQ不同刷盘机制的区别,最后比较几种主流MQ的刷盘机制。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐