drop_caches 的简单学习
背景
最近一段时间一直在学习内存相关的知识
Linux系统里面的内存管理还是非常复杂的.
我这边理解 Linux从宏观层次的 段页式内存管理
到细节的buddy和slab 以及大页内存分配
以及page cache 和buffers的缓存等设置.
最近因为遇到了CentOS6和CentOS7 free 显示内存不一致的问题
耗费了自己很大的精力.
自己这边有CentOS7的环境, 所以想使用CentOS7进行一下验证
TLDR版本的结论
1. drop_caches 是有时间成本的. 清理缓存并不能够达到DDR宣称的带宽与速度.
DDR号称的带宽可以有 2.4G*8*2 至少 51.2GB/S的带宽 (双通道,DDR 2400频率)
但是实际验证最多也就15GB/S左右的卸载速度. 说明还是有很多其他损耗的.
2. linux内核里面有很多dirty相关的参数, 但是他仅是负责buffer 脏页的回写等处理.
并不会影响只读的page caches
只有内存遇到瓶颈. Linux才会使用LRU的策略清理page cache.
没有压力的情况下系统几乎不会做任何处理.
3. 系统内核有一个 min free 相关的参数, 可能会影响 page caches的回收时机
但是非常不建议修改过大的数值,可能会导致系统崩溃.
vm.min_free_kbytes 仅好看, 实际效益非常低.
验证
cat onefile > filenew
缓存数据量为: 11.815G
time echo 3 >/proc/sys/vm/drop_caches
real 0m0.780s
user 0m0.000s
sys 0m0.767s
消耗时间为 0.78秒
[root@oracle12c ~]# free -m
total used free shared buff/cache available
Mem: 47005 13798 382 20 32825 32733
Swap: 8079 14 8065
这次的驱逐时间为:
缓存数据量为: 31.532G
time echo 3 >/proc/sys/vm/drop_caches
real 0m2.163s
user 0m0.000s
sys 0m2.124s
说明cache 太大的情况下进行内存驱逐的时间也是比较久的
并不是没有成本的.
虚拟化的情况下 1秒钟大约可以卸载从pagecache中 15G的内存.
进行了多次验证, 时间基本上符合2S左右的区间.
缓存的使用的驱逐
+----------------------------+----------------+-------------+----------------+-------------+---------+
| Name | Size │ Pages │ Cached Size │ Cached Pages│ Percent │
|----------------------------+----------------+-------------+----------------+-------------+---------|
| /root/all.dump | 5.156G | 1351552 | 5.156G | 1351552 | 100.000 |
| /root/xxxxxx301_9999.dump | 5.907G | 1548592 | 5.144G | 1348480 | 87.078 |
| /root/xxxxxx301_9999.dump2 | 5.907G | 1548592 | 0B | 0 | 0.000 |
| /root/xxxxxx301_9999.dump3 | 5.907G | 1548592 | 0B | 0 | 0.000 |
| /root/xxxxxx301_9999.dump4 | 5.907G | 1548592 | 0B | 0 | 0.000 |
| /root/xxxxxx301_9999.dump5 | 5.907G | 1548592 | 0B | 0 | 0.000 |
|----------------------------+----------------+-------------+----------------+-------------+---------|
│ Sum │ 34.693G │ 9094512 │ 10.300G │ 2700032 │ 29.689 │
+----------------------------+----------------+-------------+----------------+-------------+---------+
最开始使用第一个文件读入缓存
内存范围内可以使用时都是100%
+----------------------------+----------------+-------------+----------------+-------------+---------+
| Name | Size │ Pages │ Cached Size │ Cached Pages│ Percent │
|----------------------------+----------------+-------------+----------------+-------------+---------|
| /root/all.dump | 12.334G | 3233248 | 12.334G | 3233248 | 100.000 |
| /root/xxxxxx301_9999.dump2 | 5.907G | 1548592 | 5.907G | 1548592 | 100.000 |
| /root/xxxxxx301_9999.dump | 5.907G | 1548592 | 5.907G | 1548592 | 100.000 |
| /root/xxxxxx301_9999.dump3 | 5.907G | 1548592 | 515.500M | 131968 | 8.522 |
| /root/xxxxxx301_9999.dump4 | 5.907G | 1548592 | 0B | 0 | 0.000 |
| /root/xxxxxx301_9999.dump5 | 5.907G | 1548592 | 0B | 0 | 0.000 |
|----------------------------+----------------+-------------+----------------+-------------+---------|
│ Sum │ 41.871G │ 10976208 │ 24.652G │ 6462400 │ 58.876 │
+----------------------------+----------------+-------------+----------------+-------------+---------+
内存有压力的情况下, 第一个读入缓存的内容开始减少 符合LRU的特点
+----------------------------+----------------+-------------+----------------+-------------+---------+
| Name | Size │ Pages │ Cached Size │ Cached Pages│ Percent │
|----------------------------+----------------+-------------+----------------+-------------+---------|
| /root/all.dump | 15.948G | 4180779 | 15.773G | 4134853 | 98.901 |
| /root/xxxxxx301_9999.dump2 | 5.907G | 1548592 | 5.907G | 1548592 | 100.000 |
| /root/xxxxxx301_9999.dump | 5.907G | 1548592 | 5.752G | 1507760 | 97.363 |
| /root/xxxxxx301_9999.dump3 | 5.907G | 1548592 | 4.138G | 1084800 | 70.051 |
| /root/xxxxxx301_9999.dump4 | 5.907G | 1548592 | 0B | 0 | 0.000 |
| /root/xxxxxx301_9999.dump5 | 5.907G | 1548592 | 0B | 0 | 0.000 |
|----------------------------+----------------+-------------+----------------+-------------+---------|
│ Sum │ 45.485G │ 11923739 │ 31.570G │ 8276005 │ 69.408 │
+----------------------------+----------------+-------------+----------------+-------------+---------+
第一个文件读入的文件 卸载了缓存之后 开始卸载第二个读入的文件
+----------------------------+----------------+-------------+----------------+-------------+---------+
| Name | Size │ Pages │ Cached Size │ Cached Pages│ Percent │
|----------------------------+----------------+-------------+----------------+-------------+---------|
| /root/all.dump | 22.097G | 5792528 | 15.729G | 4123232 | 71.182 |
| /root/xxxxxx301_9999.dump3 | 5.907G | 1548592 | 5.907G | 1548592 | 100.000 |
| /root/xxxxxx301_9999.dump2 | 5.907G | 1548592 | 5.463G | 1432089 | 92.477 |
| /root/xxxxxx301_9999.dump4 | 5.907G | 1548592 | 4.382G | 1148800 | 74.184 |
| /root/xxxxxx301_9999.dump | 5.907G | 1548592 | 0B | 0 | 0.000 |
| /root/xxxxxx301_9999.dump5 | 5.907G | 1548592 | 0B | 0 | 0.000 |
|----------------------------+----------------+-------------+----------------+-------------+---------|
│ Sum │ 51.634G │ 13535488 │ 31.482G │ 8252713 │ 60.971 │
+----------------------------+----------------+-------------+----------------+-------------+---------+
最终情况 第一个 第二个读入的完全卸载了内存 第三个卸载了一部分 合并形成的那文件也只有一部分在内存里面.
+----------------------------+----------------+-------------+----------------+-------------+---------+
| Name | Size │ Pages │ Cached Size │ Cached Pages│ Percent │
|----------------------------+----------------+-------------+----------------+-------------+---------|
| /root/all.dump | 29.537G | 7742960 | 15.770G | 4133969 | 53.390 |
| /root/xxxxxx301_9999.dump4 | 5.907G | 1548592 | 5.907G | 1548592 | 100.000 |
| /root/xxxxxx301_9999.dump5 | 5.907G | 1548592 | 5.907G | 1548592 | 100.000 |
| /root/xxxxxx301_9999.dump3 | 5.907G | 1548592 | 3.947G | 1034672 | 66.814 |
| /root/xxxxxx301_9999.dump | 5.907G | 1548592 | 0B | 0 | 0.000 |
| /root/xxxxxx301_9999.dump2 | 5.907G | 1548592 | 0B | 0 | 0.000 |
|----------------------------+----------------+-------------+----------------+-------------+---------|
│ Sum │ 59.074G │ 15485920 │ 31.532G │ 8265825 │ 53.376 │
+----------------------------+----------------+-------------+----------------+-------------+---------+
内核参数的验证
sysctl -a |grep min |grep free
vm.min_free_kbytes = 27729
修改默认值之前的 free -m 结果 free 最小值为 359MB
total used free shared buff/cache available
Mem: 47005 13795 359 20 32850 32736
Swap: 8079 13 8066
echo 4096000 >/proc/sys/vm/min_free_kbytes
将最小的可用内存修改为4GB 再次观察
[root@oracle12c ~]# free -m
total used free shared buff/cache available
Mem: 47005 13783 5397 20 27824 21958
Swap: 8079 18 8061
内存在靠近4GB free的时候就开始 回收page caches 了
但是感觉这个参数意义不大, 只是监控效果好看. 并且会造成内存资源的浪费.
修改之前和之后 文件缓存的最大比率为:
修改之前 53.376% 修改之后 43.016%
之后的结果为:
+----------------------------+----------------+-------------+----------------+-------------+---------+
| Name | Size │ Pages │ Cached Size │ Cached Pages│ Percent │
|----------------------------+----------------+-------------+----------------+-------------+---------|
| /root/all.dump | 29.537G | 7742960 | 12.712G | 3332341 | 43.037 |
| /root/xxxxxx301_9999.dump5 | 5.907G | 1548592 | 5.907G | 1548592 | 100.000 |
| /root/xxxxxx301_9999.dump4 | 5.907G | 1548592 | 5.907G | 1548592 | 100.000 |
| /root/xxxxxx301_9999.dump3 | 5.907G | 1548592 | 905.688M | 231856 | 14.972 |
| /root/xxxxxx301_9999.dump | 5.907G | 1548592 | 0B | 0 | 0.000 |
| /root/xxxxxx301_9999.dump2 | 5.907G | 1548592 | 0B | 0 | 0.000 |
|----------------------------+----------------+-------------+----------------+-------------+---------|
│ Sum │ 59.074G │ 15485920 │ 25.411G │ 6661381 │ 43.016 │
+----------------------------+----------------+-------------+----------------+-------------+---------+