Linux - 怎么实现大文件传输

一 前言

博文《PageCache》中介绍了 PageCache 的优缺点,其实在处理大文件中 PageCache 作用反而没有那么好。所以本文介绍 Linux 是怎么处理大文件的。

二 起因

首先看一下一个 read() 系统调用流程发生了什么,如下图:

在这里插入图片描述

  1. 当调用 read 方法时,会阻塞着,此时内核会向磁盘发起 I/O 请求。
  2. 磁盘收到请求后,便会寻址,当磁盘数据准备好后,就会向内核发起 I/O 中断,告知内核磁盘数据已经准备好。
  3. 内核收到 I/O 中断后,就将数据从磁盘控制器缓冲区拷贝到 PageCache 里。
  4. 最后,内核再把 PageCache 中的数据拷贝到用户缓冲区,于是 read 调用返回。

从上图不难发现两个问题:1,这是一个同步 I/O;2,数据多次拷贝。通常分别采用 异步 I/O 和 直接 I/O 来优化上面的问题。

三 异步 I/O、 直接 I/O

异步 I/O 是指发起 I/O 请求后,不再阻塞等待。而是先去处理其他任务,当拷贝完成后再进行处理。

异步 I/O 并没有涉及到 PageCache,所以使用异步 I/O 就意味着要绕开 PageCache。
绕开 PageCache 的 I/O 叫直接 I/O,使用 PageCache 的 I/O 则叫缓存 I/O。通常,对于磁盘,异步 I/O 只支持直接 I/O。

如下图:
在这里插入图片描述

  1. 内核向磁盘发起读请求,但是可以不等待数据就位就可以返回,于是进程此时可以处理其他任务。
  2. 当内核将磁盘中的数据拷贝到进程缓冲区后,进程将接收到内核的通知,再去处理数据。

四 总结

针对大文件的传输的方式,应该使用「异步 I/O + 直接 I/O」来替代零拷贝技术。常见的两种 直接 I/O 应用场景:

  1. 如在 MySQL 数据库中,是使用直接 I/O的。应用程序已经实现了磁盘数据的缓存,那么可以不需要 PageCache 再次缓存,减少额外的性能损耗。
  2. 传输大文件的时候,由于大文件难以命中 PageCache 缓存,而且会占满 PageCache 导致「热点」文件无法充分利用缓存,从而增大了性能开销,因此,这时应该使用直接 I/O。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

mooddance

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

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

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

打赏作者

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

抵扣说明:

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

余额充值