宋寶華:swappiness=0究竟意味着什麼?

本文解釋swappiness的作用,以及swappiness=0究竟意味着什麼。

內存回收

我們都知道,Linux一個進程使用的內存分爲2種:

  1. file-backed pages(有文件背景的頁面,比如代碼段、比如read/write方法讀寫的文件、比如mmap讀寫的文件;他們有對應的硬盤文件,因此如果要交換,可以直接和硬盤對應的文件進行交換),此部分頁面進page cache

  2. anonymous pages(匿名頁,如stack,heap,CoW後的數據段等;他們沒有對應的硬盤文件,因此如果要交換,只能交換到虛擬內存-swapfile或者Linux的swap硬盤分區),此部分頁面,如果系統內存不充分,可以被swap到swapfile或者硬盤的swap分區

因此,Linux在進行內存回收(memory reclaim)的時候,實際上可以從1類和2類這兩種頁面裏面進行回收,而swappiness就決定了回收這2類頁面的優先級。

swappiness越大,越傾向於回收匿名頁;swappiness越小,越傾向於回收file-backed的頁面。當然,它們的回收方法都是一樣的LRU算法。


swappiness=0的歷史與現在

在Linux的早期版本(2012年以前的版本,kernel 3.5-rc1),哪怕swappiness被設置爲0,其實匿名頁仍然有被交換出去的機會:

早先的回收權重是這樣計算的:

anon_prio = swappiness;

file_prio = 200 - anon_prio;

ap = (anon_prio + 1) * (reclaim_stat->recent_scanned[0] + 1);

fp = (file_prio + 1) * (reclaim_stat->recent_scanned[1] + 1);

由此可看出,哪怕swappiness爲0,ap也是不會爲0的,只是比較小。所以swappiness=0不意味着匿名頁就不交換。

2012年的第一場雪,比以往時候來得更晚一些

這一年,一個小小的提交,引發了蝴蝶效應,並震驚寰宇:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fe35004fbf9eaf67482b074a2e032abb9c89b1dd


它徹底改變了swappiness=0的定義。這個commit,碧血橫飛,浩氣四塞,草木爲之含悲,風雲因而變色。


它的意思再明確不過,如果swappiness=0,除非系統的內存過小nr_free + nr_filebacked < high watermark這種惡劣情況發生

都只是考慮交換file-backed的pages,就不會考慮交換匿名頁了。

它改動的代碼如下:

-ap = (anon_prio + 1) * (reclaim_stat->recent_scanned[0] + 1);

+ap = anon_prio * (reclaim_stat->recent_scanned[0] + 1);

ap /= reclaim_stat->recent_rotated[0] + 1;

-fp = (file_prio + 1) * (reclaim_stat->recent_scanned[1] + 1);

+fp = file_prio * (reclaim_stat->recent_scanned[1] + 1);

anon_prio如果爲0的話,ap也爲0了。

於是乎,現在的swappiness如果等於0的話,意味着哪怕匿名頁佔據的內存很大,哪怕swap分區還有很多的剩餘空間,除非惡劣情況發生,都不會交換匿名頁,因此這可能造成更大的OOM壓力。不像以前,平時會一直兼顧着回收page cache和匿名頁。


現在swappiness=0的情況下,天平的格局是:


一石激起千層浪,兩指彈出萬般音。相關社區的網站內容都跟着進行了更新,比如紅帽子:


特洛伊之戰中,在決定阿基琉斯和赫克托爾的命運的生死一戰中,荷馬將命運的天平放在宙斯手中:“天父取出他的那杆黃金天秤,把兩個悲慘的死亡判決放進秤盤,一個屬阿基琉斯,一個屬馴馬的赫克托爾,他提起秤桿中央,赫克托爾一側下傾,滑向哈得斯。”


跨過特洛伊木馬屠城千年的悲涼,我們看到Linux裏面兩位戰神的命運,被一個碼農輕鬆地決定。

這個修改引起了一系列的連鎖反應,而相關的文檔修改,卻是發生在2年之後:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8582cb96b0bfd6891766d8c30d759bf21aad3b4d


MEM CGroup裏面的swappiness

在使能Memory CGroup的情況下,每個memory group可以設置自己的swappiness值,如果某個group的swappiness被設置爲0,這個group的匿名頁交換會被完全禁止,從而誘發該group在無file-backed頁面可回收情況下(哪怕swap空間還很大)的OOM,這一點透過Documentation/cgroup-v1/memory.txt文檔可以看出:

 

5.3 swappiness

Overrides /proc/sys/vm/swappiness for the particular group. The tunable in the root cgroup corresponds to the global swappiness setting.

Please note that unlike during the global reclaim, limit reclaim enforces that 0 swappiness really prevents from any swapping even if there is a swap storage available. This might lead to memcg OOM killer if there are no file pages to reclaim.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章