RocketMQ的刷盘机制有哪些?
1 个回答
不必太张扬,是花自然香。kettyRocketMQ 拥有海量的消息积压能力,主要是因为它支持消息的持久化,Broker 接收到消息后,会将消息写入 CommitLog 文件。但是,磁盘 IO 的效率较低,为了保证性能和吞吐量,RocketMQ 通过顺序写、内存映射和零拷贝、异步刷盘等一系列手段来优化性能。 首先是 Linux 系统的高速页缓存(PageCache),通过将一部分内存用作 PageCache,写数据时先写到 Cache,再由异步线程将脏页数据同步到磁盘,顺序写的性能几乎等于写内存。读数据时先读到 Cache,再次读就能命中缓存,而且在 PageCache 预读机制下,顺序读的性能几乎也等于读内存。所以,只要能保证顺序读写,在 PageCache 的加持下,磁盘 IO 读写并不是性能瓶颈。 再是内存映射跟零拷贝,为了减少内存复制,提高磁盘 IO 的性能,RocketMQ 使用「内存映射」技术来读写文件,通过将磁盘上的物理文件直接映射到应用程序的虚拟内存地址空间,减少了数据在用户态和内核态之间来回复制的开销,应用程序看似在读写自己的内存,其实是在读写内核缓冲区的内存。 综上所述,提升磁盘 IO 性能,不过是将原本要写入磁盘的数据先暂存到内存里,不管是应用程序缓冲区还是内核缓冲区,它都是在内存里,只要数据在内存里,就意味着机器断电数据就丢了。要想保证消息不丢,就只有每次发消息都进行一次刷盘,副作用就是性能会受到较大影响。鱼和熊掌不可兼得,但是用户可以根据自己的实际场景选择适合自己的刷盘策略。 RocketMQ 支持三种刷盘策略:  同步刷盘时,只有消息被真正持久化到磁盘才会响应 ACK,可靠性非常高,但是性能会受到较大影响,适用于金融业务。异步刷盘时,消息写入 PageCache 就会响应 ACK,然后由后台线程异步将 PageCache 里的内容持久化到磁盘,降低了读写延迟,提高了性能和吞吐量。服务宕机消息不丢失,机器断电少量消息丢失。异步刷盘+缓冲区,消息先写入直接内存缓冲区,然后由后台线程异步将缓冲区里的内容持久化到磁盘,性能最好。但是最不可靠,服务宕机和机器断电都会丢失消息。 RocketMQ 默认采用第二种方案,异步刷盘,只有机器断电才可能导致少量消息丢失,兼顾了性能和可靠性。 编辑于 2022-03-13 22:26 •IP属地 云南举报评论收藏1
公众号进入网站体验更佳

