JAVA IO专题四:java顺序IO原理以及对应的应用场景

其他相关专题

JAVA IO专题一:java InputStream和OutputStream读取文件并通过socket发送,到底涉及几次拷贝
JAVA IO专题二:java NIO读取文件并通过socket发送,最少拷贝了几次?堆外内存和所谓的零拷贝到底是什么关系
JAVA IO专题三:java的内存映射和应用场景
JAVA IO专题四:java顺序IO原理以及对应的应用场景

顺序I/O和随机I/O基本概念

本次 I/O 给出的初始扇区地址和上一次 I/O 的结束扇区地址是完全连续或者相隔不多的,则算作顺序 I/O。反之,如果相差很大,则算作一次随机 I/O

硬件层面理解一、机械硬盘

影响机械硬盘的性能因素主要由寻道时间、旋转延迟和数据传输时间三部分构成。

  1. 寻道时间

指将读写磁头移动至正确的磁道上所需要的时间。寻道时间越短,I/O操作越快,目前磁盘的平均寻道时间一般在3-15ms。

  1. 旋转延迟

指盘片旋转将请求数据所在的扇区移动到读写磁盘下方所需要的时间。旋转延迟取决于磁盘转速,通常用磁盘旋转一周所需时间> 的1/2表示。比如:7200rpm的磁盘平均旋转延迟大约为60*1000/7200/2 = 4.17ms,而转速为15000rpm的磁盘其平均旋转延迟为2ms。

  1. 数据传输时间

指完成传输所请求的数据所需要的时间,它取决于数据传输率,其值等于数据大小除以数据传输率。目前IDE/ATA能达到
133MB/s,SATA II可达到300MB/s的接口数据传输率,数据传输时间通常远小于前两部分消耗时间。简单计算时可忽略。

机械硬盘的顺序写性能之所以很好,主要是因为磁头移动到正确的磁道上需要时间,顺序读写时,磁头基本不需要移动。

硬件层面理解二、固态硬盘

固态硬盘是一块随机寻址芯片,它不存在寻道时间和旋转延迟。但是固态的每次数据更新并不是直接操作原来的位置,而是在一块新的位置写入数据,再将旧的位置删除,长此以往则会产生很多磁盘碎片,而固态硬盘实现了类似jvm gc一样的垃圾回收器,随机写越多,垃圾越多,垃圾回收消耗越大,因此顺序写相对而言效率就比较高。

顺序IO在操作系统层面的表现

操作系统对磁盘的读操作做了优化,即对磁盘数据做了缓存(linux的Page Cache和Buffer Cache),磁盘Cache有个预读功能,预读的具体过程是:

对于每个文件的第一个读请求,系统读入所请求的页面并读入紧随其后的少数几个页面,这时的预读称为同步预读。对于第二次读请求,如果所读页面不在Cache中,即不在前次预读的页中,则表明文件访问不是顺序访问,系统继续采用同步预读;如果所读页面在Cache中,则表明前次预读命中,操作系统把预读页的大小扩大一倍,此时预读过程是异步的。

因此如果是顺序读,则能够更好地利用异步预读,提高IO的响应速度。

java中的随机IO和顺序IO

  • 随机IO
    java中常见的apichannel.read/write,outputStream/inputStream,都是随机IO,其工作模式都是先分配内存,往内存中写数据,将内存丢给操作系统去读写,没有显式地指定读写的位置,操作系统会随机分配写入的位置。
  • 顺序IO
    java中可以利用MappedByteBuffer 实现顺序IO,与随机IO的区别在于,事先分配一段连续的文件空间,每次在这个空间中写完后,记录最后的偏移量,下次写的时候从该位置开始继续写,通过 MappedByteBuffer 提供的api,指定写入的位置,从而实现顺序IO。

示例代码,顺序写:

public static int write(String path) throws IOException {
    //要写入的数据
        List<String> lines = Lists.newArrayList("第一行\n", "第二行\n", "第三行\n");
    //打开文件通道,并赋予读写权限
        FileChannel targetFileChannel = FileChannel.open(Paths.get(path), StandardOpenOption.WRITE, 
        StandardOpenOption.READ);
        //映射文件buffer
        MappedByteBuffer map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 64);
        for (String line : lines) {
            byte[] bytes = line.getBytes(StandardCharsets.UTF_8);
            //不需要指定位置,默认会写在文件尾部并更新position,当然也可以通过map.put(bytes, position, len)来指定写入的位置
            map.put(bytes);
        }
        //返回偏移量
        return map.position();
}

因此在代码层面,调用 inputStream.write 这类不指定具体位置的方法,会让操作系统去随机判断写入的位置,可以理解为随机写。
用MappedByteBuffer的方式实现开辟一块内存映射,并按顺序追加的方式,称为顺序写。当然如果你分配多个MappedByteBuffer并随机指定位置写入,那么就属于顺序写。因此笔者理解顺序写并不是操作系统或者某个已有的函数直接帮我们完成的,关键在于我们自己实现的方式。

顺序IO的应用场景

场景的消息队列都用到了顺序IO来提高吞吐量,如kafka、rocketMQ、QMQ,这里简单看一下QMQ对于顺序IO的应用(RocketMQ我还没看过),关于QMQ怎么实现顺序写可以看笔者另一篇文章JAVA IO专题三:java的内存映射和应用场景

参考文章

磁盘I/O那些事-美团技术团队

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,817评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,329评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,354评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,498评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,600评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,829评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,979评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,722评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,189评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,519评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,654评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,940评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,762评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,993评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,382评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,543评论 2 349

推荐阅读更多精彩内容