Linux 中文件系统元数据的缓存方式和位置

Linux 中文件系统元数据的缓存方式和位置

我之前的问题显然有一个错误的前提。我以为文件系统元数据缓存在 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速度,仍然比以前快得多。

相关内容