读取文件而不从OS页面缓存中删除

时间:2012-03-14 22:44:16

标签: file-io linux-kernel posix

(这适用于Linux,或者理想的任何POSIX系统。)

我正在寻找一种方法来读取大量文件(其中任何一个文件本身可能高达1GB),具有以下特征,当我阅读以下页面时:

  • 如果相关的磁盘页面已经在文件系统缓存中,则使用该磁盘页面。
  • 如果相关页面不在磁盘缓存中,则从磁盘获取,但不会驱逐任何现有的缓存磁盘页。

我们的想法是能够在不污染磁盘缓存或驱逐当前工作集的情况下读取所有这些文件。

任何指导?

4 个答案:

答案 0 :(得分:3)

在Linux上,您可以试用O_DIRECT open()标记。 man open(2)

   O_DIRECT (Since Linux 2.4.10)
          Try  to minimize cache effects of the I/O to and from this file.
          In general this will degrade performance, but it  is  useful  in
          special  situations,  such  as  when  applications  do their own
          caching.  File I/O is done directly to/from user space  buffers.
          The O_DIRECT flag on its own makes at an effort to transfer data
          synchronously, but does not give the guarantees  of  the  O_SYNC
          that  data and necessary metadata are transferred.  To guarantee
          synchronous I/O the O_SYNC must be used in addition to O_DIRECT.
          See NOTES below for further discussion.

答案 1 :(得分:2)

执行此操作的最佳方式可能是posix_fadvise()。在阅读之前将POSIX_FADV_NOREUSE标志应用于整个文件似乎是最合适的;不幸的是,这个标志对当前的内核没有任何作用。

你可以尝试的是从文件中读取一大块数据,然后立即通过POSIX_FADV_DONTNEED标志告诉内核你不再需要那个块{.1}}。 p>

答案 2 :(得分:1)

  

使用posix_fadvise可以提示操作系统应该从缓存中删除某些文件块。与来自mincore的信息一起告诉我们当前缓存了哪些块,我们可以在不干扰缓冲区缓存的情况下改变应用程序的工作。

详细描述了[un]实现的内核功能的令人愉快的解决方法:

http://insights.oetiker.ch/linux/fadvise/

[编辑]内核预读的含义

要获得完整的阅读效果,您应该确保只删除您已阅读的页面。否则你将删除内核有用的页面提前删除:)。 (我认为这应该被检测为预读错误预测,这将禁用它并至少避免大量浪费的IO。但是预读非常有用,所以你想避免禁用它。)

另外,我打赌如果你在上次阅读之前测试页面,那么它们总是显示为核心内容。它不会告诉你是否有其他人在使用它们。所有它将显示内核预读正在工作:)。

链接的rsync补丁中的代码应该没问题(忽略所有fds的#34;数组" hack)。它在第一次读取之前测试整个文件。这是合理的,因为它只需要每4kB文件页面一个字节的内核分配。

答案 3 :(得分:0)

页面缓存大小根据系统中发生的各种进程,I / O回写等请求的内存动态变化。您可以做的是tune / proc / sys / vm / swappiness值。