Jay*_*ker 27 linux filesystems cache files
我知道我可以从 Linux 文件系统缓存中删除所有内容,但是有没有办法只删除一个特定文件?或者防止文件被缓存?或者告诉进程不要缓存它写入的任何文件?
我有一个进程可以读取很多小文件并写入一个大文件。我想将小文件保留在缓存中以避免磁盘搜索,我不关心缓存大文件。
slm*_*slm 24
我在 2012 年找到了一种方法,该方法在此邮件线程中讨论了对 Linux 内核的提议补丁,标题为:Re: [RFC Patch] fs:implement per-file drop caches。
摘抄Cong> 这是一个实现按文件放置缓存的补丁草案。
有趣的。那么我可以从流程外部执行此操作吗?我是一名系统管理员,所以我的 POV 是在系统处于压力下时注意到、发现和修复性能问题。
Run Code Online (Sandbox Code Playgroud)Cong> It introduces a new fcntl command F_DROP_CACHES to drop Cong> file caches of a specific file. The reason is that currently Cong> we only have a system-wide drop caches interface, it could Cong> cause system-wide performance down if we drop all page caches Cong> when we actually want to drop the caches of some huge file.
如何判断文件使用了多少缓存?在繁忙的系统上运行时,这对性能有什么影响?这个补丁给我们带来了什么,因为我认为一旦系统受到内存压力,虚拟机应该已经放弃缓存......
Cong> 下面是这个补丁的小测试用例:
该线程包括一个测试用例和 Linux 内核中几个文件的实际补丁,它为fs/drop_caches.c
调用的drop_pagecache_file(struct file *filp)
. 然后可以通过前端工具fnctl.c
通过命令访问此功能F_DROP_CACHES
。这个案例调用了这个函数:
file_drop_caches(filp, arg);
Run Code Online (Sandbox Code Playgroud)
它处理与给定文件关联的所有缓存的删除。从文件include/linux/mm.h
:
void file_drop_caches(struct file *filp, unsigned long which);
Run Code Online (Sandbox Code Playgroud)
那么这个可以用吗?
我发现没有证据表明这个补丁曾经进入主要的 Linux 内核代码存储库,所以这个选项似乎是可用的,只有当你愿意自己重新编译 Linux 内核时。
在同一线程中,另一位用户提到了一种完全不同的方法,该方法使用dd
.
测试一下这是有用的功能。虽然它不是已经提供了
以下是该补丁中的示例:POSIX_FADV_DONTNEED
吗?一年前,此功能已添加到GNU dd (8.11) 中。
建议删除整个文件的缓存
Run Code Online (Sandbox Code Playgroud)$ dd if=ifile iflag=nocache count=0
确保删除整个文件的缓存
Run Code Online (Sandbox Code Playgroud)$ dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0
删除部分文件的缓存
Run Code Online (Sandbox Code Playgroud)$ dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null
仅使用预读缓存流式传输数据
Run Code Online (Sandbox Code Playgroud)$ dd if=ifile of=ofile iflag=nocache oflag=nocache
我不是 100% 肯定如何测试这一点,但我想出了以下方法。
制作一个 100MB 的文件
$ dd if=/dev/urandom of=sample.txt bs=100M count=1
Run Code Online (Sandbox Code Playgroud)跟踪文件访问使用 fatrace
$ sudo fatrace | grep sample.txt
Run Code Online (Sandbox Code Playgroud)运行top
以便我们可以监控内存使用情况,注意空闲数量。
$ top
Run Code Online (Sandbox Code Playgroud)打开文件,注意现在的可用内存量。注意fatrace
文件的sample.txt
。
$ cat sample.txt > /dev/null
Run Code Online (Sandbox Code Playgroud)从内存中删除文件,注意现在的可用内存量。注意 的输出fatrace
。
$ sudo dd of=/home/saml/tst/162600/sample.txt \
oflag=nocache conv=notrunc,fdatasync count=0
Run Code Online (Sandbox Code Playgroud)$ dd if=/dev/urandom of=sample.txt bs=100M count=1
1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 7.37996 s, 14.2 MB/s
$ ls -l sample.txt
-rw-rw-r--. 1 saml saml 104857600 Oct 17 22:54 sample.txt
Run Code Online (Sandbox Code Playgroud)
在终端#2:
$ top
...
KiB Mem: 7968336 total, 6900956 used, 1067380 free, 267080 buffers
...
Run Code Online (Sandbox Code Playgroud)
在终端 #3:
$ sudo fatrace | grep sample.txt
Run Code Online (Sandbox Code Playgroud)
现在打开文件 ,sample.txt
并注意 RAM 量。在终端#1。
$ cat sample.txt > /dev/null
Run Code Online (Sandbox Code Playgroud)
在终端#2:
KiB Mem: 7968336 total, 7011896 used, 956440 free, 267336 buffers
Run Code Online (Sandbox Code Playgroud)
注意fatrace
终端 #3的输出:
cat(25940): R /home/saml/tst/162600/sample.txt
cat(25940): R /home/saml/tst/162600/sample.txt
cat(25940): RC /home/saml/tst/162600/sample.txt
Run Code Online (Sandbox Code Playgroud)
现在从 RAM 中删除文件,在终端 #4:
$ sudo dd of=/home/saml/tst/162600/sample.txt \
oflag=nocache conv=notrunc,fdatasync count=0
Run Code Online (Sandbox Code Playgroud)
注意fatrace
终端 #2的输出:
dd(26229): O /home/saml/tst/162600/sample.txt
dd(26229): CW /home/saml/tst/162600/sample.txt
Run Code Online (Sandbox Code Playgroud)
注意终端 #3 中的 RAM:
KiB Mem: 7968336 total, 6908364 used, 1059972 free, 267364 buffers
Run Code Online (Sandbox Code Playgroud)
因此,RAM 中的文件消耗的所有内容似乎都被释放了。
感谢@frostchutz 的评论,还有另一个工具,一个 Python 脚本,[pyadvise][4]
它提供了一个比上述dd
方法更简单的界面。此脚本使用相同的posix_fadvise(2)
接口。
$ sudo pyadvise --help
Usage:
pyadvise [options] [FILE]..
Options:
-h, --help show this help message and exit
-w, --willneed The specified files will be accessed in the near future
-s, --sequential The application expects to access the specified files
sequentially (with lower offsets read before higher ones)
-d, --dontneed The specified files will not be accessed in the near
future
-r, --random The specified files will be accessed in random order
-o, --noreuse The specified files will be accessed only once. Under
Linux, this operation is a no-op; see contrib/copyfileobj-
fadvise.py in the python-fadvise source tree for an
example on how to achieve approximately the same effect
-n, --normal Indicates that the application has no advice to give about
its access pattern for the specified files. If no advice
is given for an open file, this is the default assumption
-v, --verbose Explain what is being done
Run Code Online (Sandbox Code Playgroud)
如果我们重复上述测试并使用pyadvise
代替dd
:
$ pyadvise -d /home/saml/tst/162600/sample.txt
Run Code Online (Sandbox Code Playgroud)
我注意到当我使用dd
.
您可以使用标记打开单个文件O_DIRECT
(请参阅man 2 open
) \xe2\x80\x94 仔细阅读该联机帮助页的“NOTES”部分,并考虑您是否也想要/需要O_SYNC
.