- 上一篇 Linux系统缓存知识整理 中提到几个测试用例,这里补充一下详细的测试数据和结论。
LRU缓存回收策略的验证
环境信息:
[root~]# uname -r
2.6.32-431.el6.x86_64
[root~]# cat /etc/redhat-release
CentOS release 6.5 (Final)
[root~]# free -g
total used free shared buffers cached
Mem: 62 10 52 0 0 2
-/+ buffers/cache: 7 55
Swap: 31 0 31
准备工作:
- 构造两个32GB大小的文本文件(即:让文件大小超过缓存最大大小的一半)
- 这个用例主要是验证网上讲到的一个问题: 使用大数据时,别忘了关注Linux内存管理器
[root]# ls -lhtr
total 64G
-rw-r--r-- 1 root root 32G May 3 14:36 file1.csv
-rw-r--r-- 1 root root 32G May 3 14:45 file2.csv
操作步骤:
第一组测试
- 先多次执行time wc -l file1.csv,观察每次执行所用时间
- 在不清理缓存情况下,多次执行time wc -l file2.csv,观察每次执行所用时间。
- 同时使用linux-fincore工具查看file1和file2这两个文件的cache情况(关于这个工具也请参考上一篇博文的介绍)
测试数据:
- 先多次(大约六七次) wc -l file1.csv, 可以看到file1.csv被完全cache住:
# 第一次执行耗时5分钟多
[root]# time wc -l file1.csv
107746446 file1.csv
real 5m8.501s
user 0m5.280s
sys 0m16.962s
# 第二次执行只用了22秒
[root]# time wc -l file1.csv
107746446 file1.csv
real 0m22.138s
user 0m2.133s
sys 0m8.252s
# 第三次执行只用了9秒,且之后都是9秒左右。
[root@192-168-19-124 cache_test]# time wc -l file1.csv
107746446 file1.csv
real 0m9.550s
user 0m2.168s
sys 0m6.785s
# 第三次执行之后,查看file1的缓存情况:
[root]# ./linux-fincore --pages=false --summarize --only-cached /home/cache_test/*
filename size total_pages min_cached page cached_pages cached_size cached_perc
-------- ---- ----------- --------------- ------------ ----------- -----------
/home/cache_test/file1.csv 33,792,286,436 8,250,070 0 8,250,070 33,792,286,720 100.00
---
total cached size: 33,792,286,720
- 不清理缓存,直接执行
wc -l file2.csv。同样耗时5分多。但通过fincore查看,直到命令被执行完、且通过free看到系统内存几乎耗尽,file2被cache的大小也只占到 33.8%,而file1.csv仍然被cache 98.7%
[root]# time wc -l file2.csv
102468691 file2.csv
real 5m23.170s
user 0m4.718s
sys 0m20.965s
[root]# free -g Fri May 4 15:11:54 2018
total used free shared buffers cached
Mem: 62 60 2 0 0 45
-/+ buffers/cache: 15 47
Swap: 31 0 31
[root]# ./linux-fincore --pages=false --summarize --only-cached /home/cache_test/*
filename size total_pages min_cached page cached_pages cached_size cached_perc
-------- ---- ----------- --------------- ------------ ----------- -----------
/home/cache_test/file1.csv 33,792,286,436 8,250,070 106,991 8,143,079 33,354,051,584 98.70
/home/cache_test/file2.csv 34,073,762,786 8,318,790 1,786,282 2,811,795 11,517,112,320 33.80
---
total cached size: 44,871,163,904
- 第二次执行
wc -l file2.csv,仍然耗时5分钟多,比第一次略快,完毕后可以看到file1的cache减少,file2的cache增加。
[root]# time wc -l file2.csv
102468691 file2.csv
real 5m19.290s
user 0m4.718s
sys 0m20.965s
[root]# ./linux-fincore --pages=false --summarize --only-cached /home/cache_test/*
filename size total_pages min_cached page cached_pages cached_size cached_perc
-------- ---- ----------- --------------- ------------ ----------- -----------
/home/cache_test/file1.csv 33,792,286,436 8,250,070 1,226,576 6,611,513 27,080,757,248 80.14
/home/cache_test/file2.csv 34,073,762,786 8,318,790 1,052,496 4,326,571 17,721,634,816 52.01
---
total cached size: 44,802,392,064
- 第三次执行
wc -l file2.csv
[root]# time wc -l file2.csv
102468691 file2.csv
real 4m18.372s
user 0m4.540s
sys 0m19.338s
[root]# ./linux-fincore --pages=false --summarize --only-cached /home/cache_test/*
filename size total_pages min_cached page cached_pages cached_size cached_perc
-------- ---- ----------- --------------- ------------ ----------- -----------
/home/cache_test/file1.csv 33,792,286,436 8,250,070 1,226,576 5,457,623 22,354,423,808 66.15
/home/cache_test/file2.csv 34,073,762,786 8,318,790 0 5,257,364 21,534,162,944 63.20
---
total cached size: 43,888,586,752
- 大约六七次执行之后,可以看到file2已经完全在cache中。之后再次执行
wc -l file2.csv速度就很快了
[root]# time wc -l file2.csv
102468691 file2.csv
real 1m56.612s
user 0m2.953s
sys 0m13.424s
[root]# ./linux-fincore --pages=false --summarize --only-cached /home/cache_test/*
filename size total_pages min_cached page cached_pages cached_size cached_perc
-------- ---- ----------- --------------- ------------ ----------- -----------
/home/cache_test/file1.csv 33,792,286,436 8,250,070 1,226,576 2,328,421 9,537,212,416 28.22
/home/cache_test/file2.csv 34,073,762,786 8,318,790 0 8,318,790 34,073,763,840 100.00
---
total cached size: 43,610,976,256
[root]# time wc -l file2.csv
102468691 file2.csv
real 0m8.339s
user 0m2.002s
sys 0m6.336s
第二组测试
- 为了验证file1访问次数和后面file1的cache被淘汰速度之间的关系,我们执行
echo 3 > /proc/sys/vm/drop_caches清理所有缓存后,重新做一次测试。 初始状态仅执行一次wc -l file1.csv,将file1完全加载到缓存。
[root]# ./linux-fincore --pages=false --summarize --only-cached /home/cache_test/*
filename size total_pages min_cached page cached_pages cached_size cached_perc
-------- ---- ----------- --------------- ------------ ----------- -----------
/home/cache_test/file1.csv 33,792,286,436 8,250,070 35,544 8,214,526 33,646,698,496 99.57
---
total cached size: 33,646,698,496
- 然后执行一次
wc -l file2.csv,可以看到file2已经被100% cache,而file1大部分内容已被逐出缓存。
[root]# ./linux-fincore --pages=false --summarize --only-cached /home/cache_test/*
filename size total_pages min_cached page cached_pages cached_size cached_perc
-------- ---- ----------- --------------- ------------ ----------- -----------
/home/cache_test/file1.csv 33,792,286,436 8,250,070 3,286,806 4,298,896 17,608,278,016 52.11
/home/cache_test/file2.csv 34,073,762,786 8,318,790 0 8,318,790 34,073,763,840 100.00
---
total cached size: 51,682,041,856
结论
- 第一组测试与网上提到的修复方案描述一致: 即系统会记录file2对应页面的累积访问次数,尽管file1占据active缓存队列时,file2只能在inactive中,且由于无法全部加载到内存,file2加载到尾部时其头部的缓存页面已经被淘汰。但作为修复方案,系统仍然会记录其最近访问计数,并在计数达到一定次数后将其移动到active队列,并逐出file1对应的缓存页面。
- 需要注意这与我们普通理解的LRU仍然有一些不同:并非file2被访问一次之后就完全被cache住!!!事实上,第一次访问后,file2仅有一小部分在cache2中,随着其访问次数的增加,在逐渐将file1逐出cache。
- 第二组测试中,由于file1最初仅被访问一次,所以这和我们理解的LRU是一样的:file2访问一次之后就完全被cache,file1的大部分内容被从缓存中逐出,以给file2“腾”出空间。
/proc/sys/vm/drop_caches取值1和2的区别
echo 1 > /proc/sys/vm/drop_caches是清理数据缓存。例如上面的例子中,echo
1 和 echo 3 效果基本差不多,因为主要是数据缓存,元数据很少。echo 2 > /proc/sys/vm/drop_caches是清理目录和inode缓存。在目录、文件数量很多情况下,可以使用这个命令。
测试验证
准备条件
- 创建一个/home/test目录,在test目录下创建约3.2万个子目录,每个子目录下100个文件。即总共约320万个文件
操作步骤
- 执行find命令查找test目录下所有文件,第一次执行耗时5分多,之后由于缓存,只需要10秒以内。
# 第一次执行
[root@localhost home]# time find /home/cache_test -name file* | wc -l
3125400
real 5m30.465s
user 0m11.033s
sys 0m34.133s
# 第二次执行
[root@localhost home]# time find /home/cache_test -name file* | wc -l
3125400
real 0m18.615s
user 0m2.489s
sys 0m5.287s
# 第三次执行
[root@localhost home]# time find /home/cache_test -name file* | wc -l
3125400
real 0m3.374s
user 0m1.421s
sys 0m1.930s
- 执行
echo 1 > /proc/sys/vm/drop_caches之后再次执行find命令,速度仍然很快。可见目录和文件inode缓存仍在。
[root@localhost home]# echo 1 > /proc/sys/vm/drop_caches
[root@localhost home]# time find /home/cache_test -name file* | wc -l
3125400
real 0m3.554s
user 0m1.424s
sys 0m1.949s
- 执行
echo 2 > /proc/sys/vm/drop_caches之后再次执行find命令,速度很慢。可见 缓存已经被清理掉了。但再次执行,由于前面已经缓存过,速度又变快。
[root@localhost home]# echo 2 > /proc/sys/vm/drop_caches
# 由于缓存被清理,这次执行耗时8分钟多
[root@localhost home]# time find /home/cache_test -name file* | wc -l
3125400
real 8m22.344s
user 0m11.845s
sys 0m51.035s
# 再次执行,又有了缓存,速度很快
[root@localhost home]# time find /home/cache_test -name file* | wc -l
3125400
real 0m3.375s
user 0m1.361s
sys 0m1.913s
- 执行
echo 3 > /proc/sys/vm/drop_caches之后在测试,针对这个场景,效果和echo 2 一样:
[root@localhost home]# echo 3 > /proc/sys/vm/drop_caches
[root@localhost home]# time find /home/cache_test -name file* | wc -l
3125400
real 8m22.845s
user 0m11.121s
sys 0m49.958s
[root@localhost home]# time find /home/cache_test -name file* | wc -l
3125400
real 0m3.294s
user 0m1.422s
sys 0m1.852s
总结
- 通过上面这些例子,
echo 1 > /proc/sys/vm/drop_caches和echo 2 > /proc/sys/vm/drop_caches的区别已经很清晰了。

本文详述了Linux系统缓存测试的过程,包括LRU缓存回收策略的验证,通过测试数据展示了缓存行为。第一组测试表明系统会记录文件访问次数并逐步替换缓存内容。第二组测试验证了不同访问频率下文件缓存的变化。此外,还探讨了`drop_caches`参数中1和2的区别,涉及数据缓存和目录缓存的清理,以及它们对性能的影响。

1322

被折叠的 条评论
为什么被折叠?



