我之前的问题显然有一个错误的前提。我以为文件系统元数据缓存在 inode 和 dentry 缓存中,但显然不是。
当我做:
# time find . > /dev/null
real 10m4.435s
user 0m3.904s
sys 0m15.505s
# time find . > /dev/null
real 0m5.681s
user 0m1.400s
sys 0m4.224s
您可以看到第二次运行速度快了很多。但是,当我仅释放页面缓存:
echo 1 > /proc/sys/vm/drop_caches
Slabtop
删除这些缓存后仍然显示一个大缓存:
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1758897 1758713 99% 0.19K 83757 21 335028K dentry
1216908 1211861 99% 0.76K 57948 21 927168K ext3_inode_cache
无论如何,我不明白它是如何工作的,因为在删除所有缓存(echo 3 > /proc/sys/vm/drop_caches
)之后,slabtop
仍然报告很大的缓存大小:
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1288434 955168 74% 0.19K 61354 21 245416K dentry
1216908 1211861 99% 0.76K 57948 21 927168K ext3_inode_cache
那么,获取到的数据是否find
存储在页缓存中呢?我想将这些数据永久存储在缓存中,这样就不会因为日常备份而产生磁盘IO,但如果它存储在page_cache中,我就无法vfs_cache_pressure
控制它。
编辑:
当我执行 find 并 echo 2 到drop_caches
(这会删除 dentry 和 inode 缓存)时,find 仍然很快,并且/proc/meminfo
仍然显示平板使用情况:
# time find . > /dev/null
real 8m11.918s
user 0m3.888s
sys 0m15.313s
# echo 2 > /proc/sys/vm/drop_caches
# time find . > /dev/null
real 0m8.883s
user 0m1.540s
sys 0m4.724s
和内存信息:
# cat /proc/meminfo |grep -i "^cache\|Slab"
Cached: 425224 kB
Slab: 891648 kB
echo 2 > /proc/sys/vm/drop_caches
# cat /proc/meminfo |grep -i "^cache\|Slab"
Cached: 333740 kB
Slab: 793428 kB
这是 ext3 上的 ubuntu 12.04。
答案1
这是因为你的测试有缺陷。运行时find .
仅调用目录树上的 getdents() 。在这种情况下,目录只是一个包含目录条目的文件,因此存储在页面缓存中。请注意,您实际上什么也没做使用权您尝试以这种方式缓存的文件。
您的测试基本上是缓存文件系统树中的所有目录,而不是其他内容。
尝试做一个更难的任务来进行测试find
。例如强制它调用lstat
每个文件,您会看到不同的行为。
在我的测试中,该目录中有一百万个文件。
[root@home test]# echo 3 >/proc/sys/vm/drop_caches
[root@home test]# time find ./tmp -printf "%p %c\n" >/dev/null
real 0m16.443s
user 0m2.123s
sys 0m9.320s
[root@home test]# time find ./tmp -printf "%p %c\n" >/dev/null
real 0m2.704s
user 0m1.224s
sys 0m1.479s
[root@home test]# echo 1 >/proc/sys/vm/drop_caches
[root@home test]# time find ./tmp -printf "%p %c\n" >/dev/null
real 0m3.791s
user 0m1.359s
sys 0m1.756s
请注意,在最后一个测试中,它花费的时间稍长,我想这与目录“文件”本身的所有读取直接相关,而不是因为 dentry 和 inode 缓存不存在。
答案2
在我的系统(CentOS 7 x86_64)上,find . /usr/
似乎只加载 i/dentry 缓存,而不加载 pagecache。
让我们开始形成一个“干净”的状态:
echo 3 > /proc/sys/vm/drop_caches
cat /proc/meminfo | grep -i "^cache\|Slab"
Cached: 280432 kB
Slab: 66632 kB
现在,time find . /usr/ > /dev/null 2>/dev/null
real 0m5.126s
user 0m0.580s
sys 0m2.939s
cat /proc/meminfo | grep -i "^cache\|Slab"
Cached: 283308 kB
Slab: 288656 kB
只有 Slab 的尺寸增加了。现在,让我们删除 i/dcache:
echo 2 > /proc/sys/vm/drop_caches
cat /proc/meminfo | grep -i "^cache\|Slab"
Cached: 282704 kB
Slab: 66428 kB
板坯尺寸急剧减小。time find . /usr/ > /dev/null 2>/dev/null
给
real 0m5.122s
user 0m0.624s
sys 0m2.905s
与上面相同。仅删除页面缓存
echo 1 > /proc/sys/vm/drop_caches
time find . /usr/ > /dev/null 2>/dev/null
real 0m0.848s
user 0m0.256s
sys 0m0.575s
正如你所看到的,删除页面缓存只会不是影响find
速度,仍然比以前快得多。