想实现磁盘顺序写的原因:

最近在研究Kafka的过程中,发现kafka性能好的原因之一就是数据的最终落盘采用了磁盘的顺序读写,从各种博客和官方说法来看,磁盘的顺序读写的性能是磁盘的随机读写性能的几千倍,所以就在想,如果我要去开发一个中间件,最终存储也采用顺序读写有没有办法能用我熟悉的JAVA语言来实现这个东西呢。

解决问题过程:

首先我去查询了JDK1.8的api文档,查看了IO包和NIO包下的一些类,发现IO下的类的介绍几乎都是随机读写的,NIO也主要是采用通道和directBytebuffer来提升性能,没能给我灵感,突然我想到了RocketMq是借鉴了Kafka的原理然后采用JAVA编写的,而且RocketMq的存储也是文件系统,然后我去查看了RocketMq的官网以及GitHub并参考了部分博客,最终发现Java实现磁盘的顺序读写主要是两个类,一个是IO包下的RandomAccessFile类和MappedByteBuffer内存映射的类来实现的,实现方案如下:

 /***  顺序写* @param filePath* @param content* @param index* @return*/public static long fileWrite(String filePath, String content, int index) {File file = new File(filePath);RandomAccessFile randomAccessTargetFile;//  操作系统提供的一个内存映射的机制的类MappedByteBuffer map;try {randomAccessTargetFile = new RandomAccessFile(file, "rw");FileChannel targetFileChannel = randomAccessTargetFile.getChannel();map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, (long) 1024 * 1024 * 1024);map.position(index);map.put(content.getBytes());return map.position();} catch (IOException e) {e.printStackTrace();} finally {}return 0L;}/*** 顺序读* @param filePath* @param index* @return*/public static String fileRead(String filePath, long index) {File file = new File(filePath);RandomAccessFile randomAccessTargetFile;//  操作系统提供的一个内存映射的机制的类MappedByteBuffer map;try {randomAccessTargetFile = new RandomAccessFile(file, "rw");FileChannel targetFileChannel = randomAccessTargetFile.getChannel();map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, index);byte[] byteArr = new byte[10 * 1024];map.get(byteArr, 0, (int) index);return new String(byteArr);} catch (IOException e) {e.printStackTrace();} finally {}return "";}

PageCache与Mmap内存映射:

系统的所有文件I/O请求,操作系统都是通过page cache机制实现的。对于操作系统来说,磁盘文件都是由一系列的数据块顺序组成,数据块的大小由操作系统本身而决定,x86的linux中一个标准页面大小是4KB。操作系统内核在处理文件I/O请求时,首先到page cache中查找(page cache中的每一个数据块都设置了文件以及偏移量地址信息),如果未命中,则启动磁盘I/O,将磁盘文件中的数据块加载到page cache中的一个空闲块,然后再copy到用户缓冲区中。
page cache本身也会对数据文件进行预读取,对于每个文件的第一个读请求操作,系统在读入所请求页面的同时会读入紧随其后的少数几个页面。因此,想要提高page cache的命中率(尽量让访问的页在物理内存中),从硬件的角度来说肯定是物理内存越大越好。从操作系统层面来说,访问page cache时,即使只访问1k的消息,系统也会提前预读取更多的数据,在下次读取消息时, 就很可能可以命中内存。
在page cache机制的预读取作用下,磁盘读性能会比较高近乎内存,即使在有消息堆积情况下也不会影响性能。如果选择合适的系统IO调度算法,比如设置调度算法为“Noop”(此时块存储采用SSD的话),随机读的性能也会有所提升。
NIO中的FileChannel模型直接将磁盘上的物理文件直接映射到用户态的内存地址中(这种Mmap的方式减少了传统IO将磁盘文件数据在操作系统内核地址空间的缓冲区和用户应用程序地址空间的缓冲区之间来回进行拷贝的性能开销),将对文件的操作转化为直接对内存地址进行操作,从而极大地提高了文件的读写效率(这里需要注意的是,采用MappedByteBuffer这种内存映射的方式有几个限制,其中之一是一次只能映射1.5~2G 的文件至用户态的虚拟内存)。

最终总结:

学习的过程中,去触类旁通,并且去深究原理,会发现在计算机整体的架构没有改变的情况下,所有出现的第三方优秀框架和中间件的底层知识都是差不多的,只不过采用了不同的思想去应付不同的场景,所以就出现了比如缓存的优秀中间件:redis/mongDb,消息中间件的:kafka/rocketMq等等,认真学习会发现不断出现的新知识其实有没那么难了,加油/努力!

参考博客:https://www.jianshu.com/p/b73fdd893f98
参考博客:http://blog.laofu.online/2020/02/02/2020-02-02-java-io-operate/

Java实现磁盘的顺序读写相关推荐

  1. 磁盘的顺序读写与随机读写详解

    磁盘的顺序读写与随机读写详解 1.磁盘的基本概念 2.磁盘的读写方式 3.磁盘读取时间 4.顺序读写与随机读写 5 参考链接 1.磁盘的基本概念  盘片与盘面 : 一块硬盘一般有多块盘片,盘片分为上下 ...

  2. 关于磁盘随机读写与顺序读写

    今天看kafka官网的文档,关于性能方面的讨论时,又提到了磁盘随机读写和顺序读写性能方面的事,借此机会整理一下. 现在的大数据工具一般都会设计为append only的形式,既文件只能追加写,其它的删 ...

  3. java 顺序 读写 Properties 配置文件 支持中文 不乱码

    java 顺序 读写 Properties 配置文件 ,java默认提供的Properties API 继承hashmap ,不是顺序读写的. 特从网上查资料,顺序读写的代码,如下, import j ...

  4. MySQL顺序读写和随机读写磁盘_随机读写与顺序读写的深入理解

    随机读写与顺序读写的深入理解 分类:数据恢复常见问题|最后更新:2018年11月6日 关于磁盘的读写性能曾经一直是我头疼的地方,涉及研发或者测试时不清楚过程导致结果不尽人意.一起认识下关于磁盘的读写原 ...

  5. 文件随机或顺序读写原理深入浅出

    一.文件读写的用户程序.操作系统.磁盘交互原理 最近为了彻底搞懂文件读写原理,我特意查询了很多资料,包括Java读写文件的API代码.操作系统处理文件以及磁盘硬件知识等.由于网上现存技术文章,几乎没有 ...

  6. 顺序读写和随机读写区别和实现

    [背景]: 随机和顺序读写,是存储器的两种输入输出方式.存储的数据在磁盘中占据空间,对于一个新磁盘,操作系统会将数据文件依次写入磁盘,当有些数据被删除时,就会空出该数据原来占有的存储空间,时间长了,不 ...

  7. C语言---14文件操作---01文件内容的顺序读写

    文中的源码都在这里哦!!! 文中的源码都在这里哦!!! 一.文件的基本概念 一个文件通常是磁盘上一段命名的存储区 磁盘文件(通常用的文件):指一组相关数据的有序集合,通常存储在外部介质(如磁盘)上,使 ...

  8. 随机读写 vs 顺序读写

    磁盘是如何存储数据的? 信息存储在硬盘里,把它拆开也看不见里面有任何东西,只有些盘片.假设,你用显微镜把盘片放大,会看见盘片表面凹凸不平,凸起的地方被磁化,凹的地方是没有被磁化:凸起的地方代表数字1( ...

  9. MySQL日志顺序读写及数据文件随机读写原理

    MySQL在实际工作时候的两种数据读写机制: 对redo log.binlog这种日志进行的磁盘顺序读写 对表空间的磁盘文件里的数据页进行的磁盘随机读写 1 磁盘随机读 MySQL执行增删改操作时,先 ...

最新文章

  1. 冒号课堂 编程范式与OOP思想
  2. HTTP Referer 防外链
  3. php 常见的算法题,php最常见最经典的算法题(1)
  4. ftp上传当天文件的方法_五种方法将文件上传到FTP服务器
  5. MySQL的主从复制主从同步
  6. error: not found: value SparkSession
  7. html5 服务器手机编程,html5实现服务器发送事件
  8. linux常用网络命令ping和arping
  9. 通过NavMeshObstacle解决NavMesh防卡
  10. shell如何自动输入密码
  11. expect java ssh_使用expect实现自动化ssh以及执行命令
  12. centos7 编译安装 python3.5
  13. python集合set底层原理_Python进阶11_字典dict和集合set的秘密
  14. MySQL · 引擎介绍 · Sphinx源码剖析(二)
  15. 24. Django部署:项目部署
  16. 搭载敏捷飞天底座 阿里云专有云敏捷版全面升级 | 凌云时刻
  17. 抖音视频怎么下载MP4格式怎么转换为MP3
  18. python判断英文字母_python判断字符串中是否含有英文 | 张先生博客
  19. 极限编程XP 的12个最佳实践
  20. 量化投资python_量化投资与python

热门文章

  1. 2019 ICPC 南昌邀请赛 A-Attack(斯坦纳树)
  2. Python pow 函数- Python零基础入门教程
  3. 晋文源计算机考试,2021年晋文源第四次模拟考试yu
  4. ntp同步 mysql_vcenter和vdp设置ntp时间同步
  5. jtopo node.text换行_求助:jtopo node文字换行问题
  6. 逆变效率软件测试,光伏逆变器动态效率的测试方法介绍
  7. 生活中遇到的AR游戏是如何设计出来的
  8. 每日安全资讯(2022-12-02)
  9. 在Linux系统下安装NCL
  10. 电商高并发下会产生的问题——借鉴淘宝