消息中间件之RocketMQ为什么写文件这么快?

RocketMQ的存储涉及中,很大一部分是基于Kafka的涉及进行优化的。

PageCache

现代操作系统内核被设计为按照Page读取文件,每个Page默认4KB,
因为程序一般符合局部性原理,所以操作系统在读取一段文件内容时,会将该段内容和附件的文件内容都读取到内核Page中(预读),下次读取的内容如果命中PageCache就可以直接返回内容,不用再次读取磁盘

PageCache机制也不是完全无缺点的,当遇到操作系统进行脏回写、内存回收、内存交换等情况,就会引起较大的消息读写延迟。对于这些情况,RocketMQ采用了多种优化技术,比如内存预分配、文件预热、
mlock系统调用等,以保证再最大限度地发徽PageCache机制的优点的同时,尽可能地减少消息读写延迟。所以在生产环境部署RocketMQ的时候,尽量采用SSD独享磁盘,这样就可以最大限度地保证读写性能
在这里插入图片描述

Virtual Memory(虚拟内存)

为了保证每个程序有足够地运行空间和编程空间,可以将一些暂时不用的内存数据保存到交换区(其实是磁盘)中,这样就可以运行更多的程序,这种"内存"被称为虚拟内存(因为不是真的存在)
操作系统的可分配内存大小=虚拟内存大小+物理内存大小

零拷贝和Java文件映射

在这里插入图片描述
从文件读取流程可以看到,读取到内核态的数据会经历两次拷贝,第一次从内核态内存拷贝到用户态内存,第二次从用户态内存拷贝到Java进程的某个变量地址,这样Java变量才能读取数据。
为了提高读写文件的效率,IBM实现了零拷贝技术,它是世界上最早实现该技术的公司,后来各个厂商(如甲骨文等)也纷纷实现了该技术。
java.nio.MappedByteBuffer.java文件中实现了零拷贝技术,即Java进程映射到内核态内存,原来内核态内存与用户态内存的互相拷贝过程就消失了。在消息系统中,用户关心的往往都是最新的数据,理论上,基本的操作都在PageCache中,PageCache的操作速度和内存基本持平,所以速度非常快。当然,也存在读取历史消息而历史消息不再PageCache
中的情况,比如在流处理和批处理中,经常将消费重置到历史消息位点,以重新计算全部结果。这种情况只是在第一次拉取消息时会读取磁盘,以后可以利用磁盘预读,几乎可以做到不再直接读取磁盘,其性能与利用PageCache相比,只在第一次有差异

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coffee_babe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值