關於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

準備工作:

[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_cachesecho 2 > /proc/sys/vm/drop_caches的區別已經很清晰了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章