如何控制Linux清理cache機制?
我有一台線上伺服器, 上面有IO密集型服務, 平時基本把cache打滿的狀態. (內存使用率99%, 大部分為cache)
但是, 這台伺服器有時在白天業務高峰時, 突然操作系統cache被清理了很大一部分 (內存使用率降到50%左右, cache基本都沒有了), 導致大量缺頁和換頁, IO飆升, 從而影響服務性能. 我知道可以通過echo 3 &> /proc/sys/vm/drop_caches 來手工觸發cache的清理. 但是, 我查了一下操作日誌沒有找到相關操作. 我不清楚還有什麼情況會自動觸發cache的如此大規模清理. 如果自動大規模清理cache這個操作是操作系統自己完成的, 有沒有什麼機制可以控制它呢? 比如, 我想讓操作系統在白天業務高峰時段禁止做清理cache, 到晚上業務低谷時我們自己手工觸發.
那我來自己回答一下吧. 後來我已經找到原因了.
先說結論: 內存突降的原因是因為內存碎片過多, 內核發生了memory compaction
整個分析過程
首先, 我對伺服器出現問題的時間點前後的sar日誌進行了分析.
當時得到的現象是這樣子的:
- 分析內存變化情況(使用sar -r), 發現內存突降, 而且突降之後, 系統的內存並沒有馬上回升, 而是維持在一個低位很久
- 同時, 觀察到內存低位, 系統卡頓這段時間的換頁和swap情況 (使用sar -B -S), 發現:
- pageout數據基本沒有變化
- 沒有大量的swap換進換出操作
- pagein這時候突增, 並且維持在高位, major fault突增
- pgscank 這個數值保持高位, %vmeff 保持在100%.
其中, paging的信息給了我線索. 通過查資料, 發現pgscank表示的是Linux當中的負責內存回收的線程kswapd掃描的頁的數量, 而%vmeff表示被kswapd掃描的頁當中, 有多少頁的數據被踢出去了換成其他頁數據了(這個有個術語叫page steal, 在sar -B裡面的pgsteal/s就表示這個值) .
這說明當時, 應該是kswapd自身觸發了內存的突降, 並且它在不斷掃面現有的page, 並換入新的page.
此時, 其實還是沒有實質性進展. 直到有一次, 我們幸運地正好遇到了內存突降的時間窗口. 於是我們趕緊上線分析
- 使用sar -r 和 sar -B -S 和之前的現象一致
- 查看top, 我發現系統kswapd的線程CPU佔用率100%, 說明當時kswapd在不停努力工作中, 這個和之前的分析相吻合
- 然後, 直接查看kswapd進程對應的函數調用的時間佔比, (使用perf top), 這時候, 我發現了原因, 此時kswapd線程大部分時間都在做compact memory !
然後我進一步看了一下memory compaction的觸發條件, 主要是Linux內存分配使用的buddy algorithm 在新分配內存一個較大的內存時, 找不到符合條件的連續頁, 於是觸發了memory compaction. 這個可以通過cat /proc/buddyinfo 進行查看.
解決方法
那剩下的問題就是如何限制系統減少出現memory compaction的概率. 查閱資料後, 發現Linux有一個參數是控制這個的: /proc/sys/vm/extfrag_threshold
這個參數是一個0 ~ 1000的整數. 如果出現內存不夠用的情況, Linux會為當前系統的內存碎片情況打一個分, 如果超過了extfrag_threshold這個值, kswapd就會觸發memory compaction . 所以, 這個值設置接近1000, 說明系統在內存碎片的處理傾向於把舊的頁換出, 以符合申請的需要; 而設置接近0, 表示系統在內存碎片的處理傾向於做memory compaction.
由於這台機器在做memory compaction的時候對性能造成的影響太大, 於是我把extfrag_threshold這個值從系統默認的500設置到了最大1000 設置完了之後, 這台機器就再也沒出現過類似問題, 問題解決.
剩下的疑問
我只是通過現象觀察到做memory compaction的時候系統IO增高, 但是我還是不是很理解為什麼做memory compaction會涉及到大量的pagein操作, 並且維持時間如此之久?
其他說明
如果真的出現了memory compaction, 導致系統卡頓的情況, 可以通過下面2步手工縮短處理過程:
echo 1 &> /proc/sys/vm/drop_caches
echo 1 &> /proc/sys/vm/compact_memory
這個實質就是減少memory compaction的內存總量, 然後手工去整理. 測試發現效果不錯
參考
- http://ftp.dei.uc.pt/pub/linux/kernel/people/andrea/patches/v2.6/2.6.34/transparent_hugepage-24/memory-compaction-extfrag_threshold
- https://serverfault.com/a/746067
- https://www.kernel.org/doc/Documentation/sysctl/vm.txt
1 Linux下內存佔用多的原因
當linux第一次讀取一個文件運行時,一份放到一片內存中cache起來,另一份放入運行程序的內存中,正常運行,當程序運行完,關閉了,cache中的那一分卻沒有釋放,第二次運行的時候,系統先看看在內存中是否有一地次運行時存起來的cache中的副本,如果有的話,直接從內存中讀取,那樣,速度就快多了。說明這種情況的很典型的例子是啟動firefox,由於firefox程序很大,因此第一次讀取運行的時候很慢,尤其在速度不快的機器上,但是當你徹底關閉了firefox,ps看不到一個firefox進程,第二次再啟動的時候就比第一次明顯快很多,這是由於這次系統是直接從cache中讀取的firefox來運行,並不是從磁碟上讀取的。
再有一個例子:我們頻繁使用的ls命令等基本命令,你運行的時候根本看不到硬碟燈閃,因為這些常用的命令都是再第一次運行後就保存在cache中的,以後就一直從內存中讀出來運行。
如果cache佔用的內存過多了,影響正常運行程序需要的內存,那麼會釋放掉一部分cache內存,但是總量會保持一個很高的值,所以,linux總是能最大限度的使用內存,就算加到16G,32G內存,也會隨著不斷的IO操作,內存的free值會慢慢減少到只有幾M,想要內存不發生這種情況,只有一個辦法:把內存加到比硬碟大。2 手動釋放方法2.1 使用free查看一下當前內存使用情況(可略過):[root@*** ~]# free -m
total used free shared buffers cachedMem: 512 488 23 0 57 157-/+ buffers/cache: 273 238 Swap: 1055 0 10552.2 執行sync同步數據[root@*** ~]# sync2.3 清理cache[root@*** ~]#echo 3 &> /proc/sys/vm/drop_caches2.4 drop_cache的詳細文檔如下,以便查閱Writing to this will cause the kernel to drop clean caches, dentries and inodes from memory, causing that memory to become free.To free pagecache:* echo 1 &> /proc/sys/vm/drop_cachesTo free dentries and inodes:* echo 2 &> /proc/sys/vm/drop_caches
To free pagecache, dentries and inodes:* echo 3 &> /proc/sys/vm/drop_cachesAs this is a non-destructive operation, and dirty objects are notfreeable, the user should run "sync" first in order to make sure allcached objects are freed.This tunable was added in 2.6.16.回答pagein的問題
應該是因為文件頁面不像匿名頁做remap而是直接丟掉重新讀
具體可見 compact_zone-&>migrate_pages
解決 另外把預讀大一點連續點減少點碎頁?
我覺得核心還是內存不能滿足你的業務需求 雖然可調整招還不少 不過那麼辛苦折騰不如加點內存來的省力不容易出問題啊
最後再多說幾句 這幾年IO的節省挺重要的 而去年mapping-&>a_ops-&>migratepage的介面已經就位(現在主要用戶是zsmalloc) 是不是可以給file cache增加migrate的來節省IO是一個不錯的點子?
cache是因為對帶文件系統的介質進行讀寫引起的。是內核做的頁緩存。可以通過vmtouch工具去定位是哪些文件占的cache,從而查到對應的服務進程。
最簡單的echo 1 &>/proc/sys/vm/drop_caches
可通過調節 min_free_kbytes 來達到類似目的
用selinux鎖掉dropcache和其他懷疑項,誰碰誰進log
推薦閱讀:
※Linux 是否被過譽了?
※scp如何跨過中轉主機直接傳輸文件?
※怎麼給電腦裝系統?
※在使用Multiplexed I/O的情況下,還有必要使用Non Blocking I/O么 ?
※超級計算機的組成:一個系統還是多個系統協同合作?