我们知道,既然有同步 IO,就一定有异步 IO 来解决阻塞的问题 。异步 IO 的工作方式如下图所示:
- 应用程序发起 read 系统调用,用户进程开始进行阻塞等待结果返回 。
- 此时内核会向磁盘发起 I/O 请求,磁盘收到请求后,开始寻址 。当磁盘数据准备好后,就会向内核发起 I/O 中断,告知内核磁盘数据已经准备好 。
- 内核收到中断信号后,将数据从磁盘控制器缓存区拷贝到 pageCache 缓冲区 。
- 最后,内核会将 pageCache 中的数据再次拷贝到用户缓冲区,也就是用户态的内存中,然后 read 调用返回 。
文章插图
图片
它将读操作分为两个部分:
- 第一部分是用户进程发起 IO 请求给内核,然后进程就不再关心该 IO 操作,而是继续处理其他任务 。
- 第二部分是当内核接收到中断信号后,将数据直接拷贝到用户缓冲区,并通知用户进程操作成功 。然后用户进程开始处理数据 。
正如前面所提到的,对于大文件的传输,不应该使用 PageCache,因为这可能会导致 PageCache 被大文件占据,从而使得"热点"小文件无法充分利用 PageCache 的优势 。
因此,在高并发的场景下,对于大文件传输,我们应该采用"异步 I/O + 直接 I/O"的方式来代替零拷贝技术 。
直接 I/O 有两种常见的应用场景:
- 首先,如果应用程序已经实现了磁盘数据的缓存,就不需要再次使用 PageCache 进行缓存,这样可以减少额外的性能损耗 。例如,在 MySQL 数据库中,可以通过参数设置来开启直接 I/O,避免重复的缓存操作,默认情况下是不开启的 。
- 其次,在传输大文件时,由于大文件很难命中 PageCache 的缓存,而且会占满 PageCache 导致"热点"文件无法充分利用缓存,增加了性能开销 。因此,在这种情况下,应该使用直接 I/O 来绕过 PageCache 的缓存,以提高性能 。
- 首先,内核的 I/O 调度算法会在 PageCache 中缓存尽可能多的 I/O 请求,然后将它们合并成一个更大的 I/O 请求发送给磁盘,以减少磁盘的寻址操作 。
- 其次,内核会预读后续的 I/O 请求并将其放入 PageCache 中,同样是为了减少对磁盘的操作 。这些优化在直接 I/O 中无法享受到 。
因此,在文件传输过程中,我们可以根据文件的大小来选择不同的优化方式,以提高传输效率 。对于大文件,使用异步 I/O 和直接 I/O 可以避免 PageCache 的影响;而对于小文件,则可以使用零拷贝技术来减少数据拷贝次数,提高传输速度 。
在 Nginx 中,我们可以通过以下配置来根据文件的大小选择不同的优化方式:
location /video/ {sendfile on;AIo on;directio 1024m; }
在这个配置中,我们开启了 sendfile 选项,这允许 Nginx 使用零拷贝技术来传输文件 。同时,我们也启用了 aio 选项,这使得 Nginx 可以使用异步 I/O 来提高文件传输的效率 。而通过设置 directio 参数为 1024m,我们告诉 Nginx 当文件大小超过 1024MB 时,使用直接 I/O 来进行文件传输 。这意味着在传输大文件时,Nginx 将使用异步 I/O 和直接 I/O 的组合来实现无阻塞的文件读取,避免了 PageCache 的影响 。而对于小文件,Nginx 将继续使用零拷贝技术,以减少数据拷贝次数,提高传输速度 。
/ 总结 /至此,我们的计算机基础专栏就结束了,不知道大家有没有发现,操作系统底层提供了丰富的解决方案来支持应用程序的复杂性和可扩展性 。对于任何工作中遇到的问题,我们都可以从操作系统的角度寻找解决方法 。
推荐阅读
- 怎样吃零食才健康?
- 一年有多少个星期 一年有多少个星期零多少天
- 小零食小袋子制作方法图片 小零食小袋子制作方法
- 求职不易!2023年大学生找工作难,但成功并非无望
- 从零开始了解抖音直播:100个行业术语,迅速成为专家
- 利智摊牌承认,赌王之子何超欣何猷邦并非亲生,李连杰欣喜若狂!
- 零零后职场新人神器,整顿职场的雷蛇23款灵刃14笔记本
- 混凝土零下几度会冻坏 混凝土零下多少度怕冻
- 高圆圆夫妇合体逛街,甜蜜投喂老公零食,满面油光小肚隆起疑怀孕
- 出道多年零绯闻,演技好还不油腻,一家子幸福,今45岁成人生赢家