一、前言
RocketMQ的刷盘机制是一种确保消息可靠性的机制,简单来说就是Broker收到消息后,将消息存储到磁盘上。这样可以解决几个问题:
- 存储空间问题。内存空间有限,存入磁盘可以维护更多消息。
- 消息可靠性问题。消息存入磁盘后,即使断电了,重启后便可恢复消息。
二、刷盘机制原理
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配置
|
RabbitMQ | 异步持久化:根据时间段批量将内存中的数据刷新到磁盘 |
|
四、总结
本文主要介绍了RocketMQ的刷盘机制,从多个维度对比RocketMQ不同刷盘机制的区别,最后比较几种主流MQ的刷盘机制。