我就是認真:Linux SWAP 深度解讀(必須收藏)
http://mp.weixin.qq.com/s?__biz=MzA4Nzg5Nzc5OA==&mid=2651660097&idx=1&sn=a3d38e3af2c9d8d431c46fe7680b428d&scene=2&srcid=0606f21oK1jm1IKMwEyi6aNz&from=timeline&isappinstalled=0#wechat_redirect
作者簡介
鄒立巍
Linux系統技術專家。目前在騰訊SNG社交網絡運營部 計算資源平台組,負責內部私有雲平台的建設和架構規划設計。
曾任新浪動態應用平台系統架構師,負責微博、新浪博客等重點業務的內部私有雲平台架構設計和運維管理工作。
編者的話
鄒老師關於Linux研究的技術文章向來入木三分,如果本文您讀起來感覺費解,那么可以先收藏,然后側重了解這些內容:
swap、swappiness及kswapd原理,swap分區優先級的妙用。
真可謂一文在手,SWAP從此不再憂愁。敬請笑納。
概述
本文討論的swap基於Linux4.4內核代碼。Linux內存管理是一套非常復雜的系統,而swap只是其中一個很小的處理邏輯。
希望本文能讓讀者了解Linux對swap的使用大概是什么樣子。閱讀完本文,應該可以幫你解決以下問題:
1、swap到底是干嘛的?
2、swappiness到底是用來調節什么的?
3、kswapd什么時候會進行swap操作?
4、什么是內存水位標記?
5、swap分區的優先級(priority)有啥用?
1、什么是SWAP,到底是干嘛的?
我們一般所說的swap,指的是一個交換分區或文件。在Linux上可以使用swapon -s命令查看當前系統上正在使用的交換空間有哪些,以及相關信息:
[zorro@zorrozou-pc0 linux-4.4]$ swapon -s
Filename Type Size Used Priority
/dev/dm-4 partition 33554428 0 -1
從功能上講,交換分區主要是在內存不夠用的時候,將部分內存上的數據交換到swap空間上,以便讓系統不會因內存不夠用而導致oom或者更致命的情況出現。
所以,當內存使用存在壓力,開始觸發內存回收的行為時,就可能會使用swap空間。
內核對swap的使用實際上是跟內存回收行為緊密結合的。那么關於內存回收和swap的關系,我們需要思考以下幾個問題:
為什么要進行內存回收?
哪些內存可能會被回收呢?
回收的過程中什么時候會進行交換呢?
具體怎么交換?
下面我們就從這些問題出發,一個一個進行分析。
為什么要進行內存回收?
內核之所以要進行內存回收,主要原因有兩個:
內核需要為任何時刻突發到來的內存申請提供足夠的內存。所以一般情況下保證有足夠的free空間對於內核來說是必要的。
另外,Linux內核使用cache的策略雖然是不用白不用,內核會使用內存中的page cache對部分文件進行緩存,以便提升文件的讀寫效率。
所以內核有必要設計一個周期性回收內存的機制,以便cache的使用和其他相關內存的使用不至於讓系統的剩余內存長期處於很少的狀態。
當真的有大於空閑內存的申請到來的時候,會觸發強制內存回收。
所以,內核在應對這兩類回收的需求下,分別實現了兩種不同的機制:
一個是使用kswapd進程對內存進行周期檢查,以保證平常狀態下剩余內存盡可能夠用。
另一個是直接內存回收(directpagereclaim),就是當內存分配時沒有空閑內存可以滿足要求時,觸發直接內存回收。
這兩種內存回收的觸發路徑不同:
一個是由內核進程kswapd直接調用內存回收的邏輯進行內存回收;
參見mm/vmscan.c中的kswapd()主邏輯
另一個是內存申請的時候進入slow path的內存申請邏輯進行回收。
參見內核代碼中的mm/page_alloc.c中的__alloc_pages_slowpath方法
這兩個方法中實際進行內存回收的過程殊途同歸,最終都是調用shrink_zone()方法進行針對每個zone的內存頁縮減。
這個方法中會再調用shrink_lruvec()這個方法對每個組織頁的鏈表進程檢查。找到這個線索之后,我們就可以清晰的看到內存回收操作究竟針對的page有哪些了。
這些鏈表主要定義在mm/vmscan.c一個enum中:
根據這個enum可以看到,內存回收主要需要進行掃描的鏈表有如下4個:
anon的inactive
anon的active
file的inactive
file的active
就是說,內存回收操作主要針對的就是內存中的文件頁(file cache)和匿名頁。
關於活躍(active)還是不活躍(inactive)的判斷內核會使用lru算法進行處理並進行標記,我們這里不詳細解釋這個過程。
整個掃描的過程分幾個循環:
首先掃描每個zone上的cgroup組;
然后再以cgroup的內存為單元進行page鏈表的掃描;
內核會先掃描anon的active鏈表,將不頻繁的放進inactive鏈表中,然后掃描inactive鏈表,將里面活躍的移回active中;
進行swap的時候,先對inactive的頁進行換出;
如果是file的文件映射page頁,則判斷其是否為臟數據,如果是臟數據就寫回,不是臟數據可以直接釋放。
這樣看來,內存回收這個行為會對兩種內存的使用進行回收:
一種是anon的匿名頁內存,主要回收手段是swap;
另一種是file-backed的文件映射頁,主要的釋放手段是寫回和清空。
因為針對filebased的內存,沒必要進行交換,其數據原本就在硬盤上,回收這部分內存只要在有臟數據時寫回,並清空內存就可以了,以后有需要再從對應的文件讀回來。
內存對匿名頁和文件緩存一共用了四條鏈表進行組織,回收過程主要是針對這四條鏈表進行掃描和操作。
2、swappiness到底是用來調節什么的?
很多人應該都知道/proc/sys/vm/swappiness這個文件,是個可以用來調整跟swap相關的參數。這個文件的默認值是60,可以的取值范圍是0-100。
這很容易給大家一個暗示:我是個百分比哦!
那么這個文件具體到底代表什么意思呢?我們先來看一下說明:
======
swappiness
This control is used to define how aggressive the kernel will swap memory pages. Higher values will increase agressiveness, lower values decrease the amount of swap.
A value of 0 instructs the kernel not to initiate swap until the amount of free and file-backed pages is less than the high water mark in a zone.
The default value is 60.
======
這個文件的值用來定義內核使用swap的積極程度:
值越高,內核就會越積極的使用swap;
值越低,就會降低對swap的使用積極性。
如果這個值為0,那么內存在free和file-backed使用的頁面總量小於高水位標記(high water mark)之前,不會發生交換。
在這里我們可以理解file-backed這個詞的含義了,實際上就是上文所說的文件映射頁的大小。
那么這個swappiness到底起到了什么作用呢?
我們換個思路考慮這個事情。假設讓我們設計一個內存回收機制,要去考慮將一部分內存寫到swap分區上,將一部分file-backed的內存寫回並清空,剩余部分內存出來,我們將怎么設計?
我想應該主要考慮這樣幾個問題:
如果回收內存可以有兩種途徑(匿名頁交換和file緩存清空),那么我應該考慮在本次回收的時候,什么情況下多進行file寫回,什么情況下應該多進行swap交換。說白了就是平衡兩種回收手段的使用,以達到最優。
如果符合交換條件的內存較長,是不是可以不用全部交換出去?比如可以交換的內存有100M,但是目前只需要50M內存,實際只要交換50M就可以了,不用把能交換的都交換出去。
分析代碼會發現,Linux內核對這部分邏輯的實現代碼在get_scan_count()這個方法中,這個方法被shrink_lruvec()調用。
get_sacn_count()就是處理上述邏輯的,swappiness是它所需要的一個參數,這個參數實際上是指導內核在清空內存的時候,是更傾向於清空file-backed內存還是更傾向於進行匿名頁的交換的。
當然,這只是個傾向性,是指在兩個都夠用的情況下,更願意用哪個,如果不夠用了,那么該交換還是要交換。
簡單看一下get_sacn_count()函數的處理部分代碼,其中關於swappiness的第一個處理是:
這里注釋的很清楚:
如果swappiness設置為100,那么匿名頁和文件將用同樣的優先級進行回收。
很明顯,使用清空文件的方式將有利於減輕內存回收時可能造成的IO壓力。
因為如果file-backed中的數據不是臟數據的話,那么可以不用寫回,這樣就沒有IO發生,而一旦進行交換,就一定會造成IO。
所以系統默認將swappiness的值設置為60,這樣回收內存時,對file-backed的文件cache內存的清空比例會更大,內核將會更傾向於進行緩存清空而不是交換。
這里的swappiness值如果是60,那么是不是說內核回收的時候,會按照60:140的比例去做相應的swap和清空file-backed的空間呢?並不是。
在做這個比例計算的時候,內核還要參考當前內存使用的其他信息。對這里具體是怎么處理感興趣的人,可以自己詳細看get_sacn_count()的實現,本文就不多解釋了。
我們在此要明確的概念是:swappiness的值是用來控制內存回收時,回收的匿名頁更多一些還是回收的file cache更多一些。
swappiness設置為0的話,是不是內核就根本不會進行swap了呢?這個答案也是否定的。
首先是內存真的不夠用的時候,該swap的話還是要swap。
其次在內核中還有一個邏輯會導致直接使用swap,內核代碼是這樣處理的:
這里的邏輯是說,如果觸發的是全局回收,並且zonefile + zonefree <= high_wmark_pages(zone)條件成立時,就將scan_balance這個標記置為SCAN_ANON。
后續處理scan_balance的時候,如果它的值是SCAN_ANON,則一定會進行針對匿名頁的swap操作。
要理解這個行為,我們首先要搞清楚什么是高水位標記(high_wmark_pages)。
3、kswapd什么時候會進行swap操作?
我們回到kswapd周期檢查和直接內存回收的兩種內存回收機制。
直接內存回收比較好理解,當申請的內存大於剩余內存的時候,就會觸發直接回收。
那么kswapd進程在周期檢查的時候觸發回收的條件是什么呢?
還是從設計角度來看,kswapd進程要周期對內存進行檢測,達到一定閾值的時候開始進行內存回收。
這個所謂的閾值可以理解為內存目前的使用壓力,就是說,雖然我們還有剩余內存,但是當剩余內存比較小的時候,就是內存壓力較大的時候,就應該開始試圖回收些內存了,這樣才能保證系統盡可能的有足夠的內存給突發的內存申請所使用。
4、什么是內存水位標記?(watermark)
那么如何描述內存使用的壓力呢?
Linux內核使用水位標記(watermark)的概念來描述這個壓力情況。
Linux為內存的使用設置了三種內存水位標記:high、low、min。他們所標記的含義分別為:
剩余內存在high以上表示內存剩余較多,目前內存使用壓力不大;
high-low的范圍表示目前剩余內存存在一定壓力;
low-min表示內存開始有較大使用壓力,剩余內存不多了;
min是最小的水位標記,當剩余內存達到這個狀態時,就說明內存面臨很大壓力。
小於min這部分內存,內核是保留給特定情況下使用的,一般不會分配。
內存回收行為就是基於剩余內存的水位標記進行決策的:
當系統剩余內存低於watermark[low]的時候,內核的kswapd開始起作用,進行內存回收。直到剩余內存達到watermark[high]的時候停止。
如果內存消耗導致剩余內存達到了或超過了watermark[min]時,就會觸發直接回收(direct reclaim)。
明白了水位標記的概念之后,zonefile + zonefree <= high_wmark_pages(zone)這個公式就能理解了。
這里的zonefile相當於內存中文件映射的總量,zonefree相當於剩余內存的總量。
內核一般認為,如果zonefile還有的話,就可以盡量通過清空文件緩存獲得部分內存,而不必只使用swap方式對anon的內存進行交換。
整個判斷的概念是說,在全局回收的狀態下(有global_reclaim(sc)標記),如果當前的文件映射內存總量+剩余內存總量的值評估小於等於watermark[high]標記的時候,就可以進行直接swap了。
這樣是為了防止進入cache陷阱,具體描述可以見代碼注釋。
這個判斷對系統的影響是,swappiness設置為0時,有剩余內存的情況下也可能發生交換。
那么watermark相關值是如何計算的呢?
所有的內存watermark標記都是根據當前內存總大小和一個可調參數進行運算得來的,這個參數是:/proc/sys/vm/min_free_kbytes
首先這個參數本身決定了系統中每個zone的watermark[min]的值大小。
然后內核根據min的大小並參考每個zone的內存大小分別算出每個zone的low水位和high水位值。
想了解具體邏輯可以參見源代碼目錄下的該文件:
mm/page_alloc.c
在系統中可以從/proc/zoneinfo文件中查看當前系統的相關的信息和使用情況。
我們會發現以上內存管理的相關邏輯都是以zone為單位的,這里zone的含義是指內存的分區管理。
Linux將內存分成多個區,主要有:
直接訪問區(DMA)
一般區(Normal)
高端內存區(HighMemory)
內核對內存不同區域的訪問因為硬件結構因素會有尋址和效率上的差別。如果在NUMA架構上,不同CPU所管理的內存也是不同的zone。
相關參數設置
zone_reclaim_mode:
zone_reclaim_mode模式是在2.6版本后期開始加入內核的一種模式,可以用來管理當一個內存區域(zone)內部的內存耗盡時,是從其內部進行內存回收還是可以從其他zone進行回收的選項,我們可以通過/proc/sys/vm/zone_reclaim_mode文件對這個參數進行調整。
在申請內存時(內核的get_page_from_freelist()方法中),內核在當前zone內沒有足夠內存可用的情況下,會根據zone_reclaim_mode的設置來決策是從下一個zone找空閑內存還是在zone內部進行回收。這個值為0時表示可以從下一個zone找可用內存,非0表示在本地回收。
這個文件可以設置的值及其含義如下:
echo 0 > /proc/sys/vm/zone_reclaim_mode:意味着關閉zone_reclaim模式,可以從其他zone或NUMA節點回收內存。
echo 1 > /proc/sys/vm/zone_reclaim_mode:表示打開zone_reclaim模式,這樣內存回收只會發生在本地節點內。
echo 2 > /proc/sys/vm/zone_reclaim_mode:在本地回收內存時,可以將cache中的臟數據寫回硬盤,以回收內存。
echo 4 > /proc/sys/vm/zone_reclaim_mode:可以用swap方式回收內存。
不同的參數配置會在NUMA環境中對其他內存節點的內存使用產生不同的影響,大家可以根據自己的情況進行設置以優化你的應用。
默認情況下,zone_reclaim模式是關閉的。這在很多應用場景下可以提高效率,比如文件服務器,或者依賴內存中cache比較多的應用場景。
這樣的場景對內存cache速度的依賴要高於進程進程本身對內存速度的依賴,所以我們寧可讓內存從其他zone申請使用,也不願意清本地cache。
如果確定應用場景是內存需求大於緩存,而且盡量要避免內存訪問跨越NUMA節點造成的性能下降的話,則可以打開zone_reclaim模式。
此時頁分配器會優先回收容易回收的可回收內存(主要是當前不用的page cache頁),然后再回收其他內存。
打開本地回收模式的寫回可能會引發其他內存節點上的大量的臟數據寫回處理。如果一個內存zone已經滿了,那么臟數據的寫回也會導致進程處理速度收到影響,產生處理瓶頸。
這會降低某個內存節點相關的進程的性能,因為進程不再能夠使用其他節點上的內存。但是會增加節點之間的隔離性,其他節點的相關進程運行將不會因為另一個節點上的內存回收導致性能下降。
除非針對本地節點的內存限制策略或者cpuset配置有變化,對swap的限制會有效約束交換只發生在本地內存節點所管理的區域上。
min_unmapped_ratio:
這個參數只在NUMA架構的內核上生效。這個值表示NUMA上每個內存區域的pages總數的百分比。
在zone_reclaim_mode模式下,只有當相關區域的內存使用達到這個百分比,才會發生區域內存回收。
在zone_reclaim_mode設置為4的時候,內核會比較所有的file-backed和匿名映射頁,包括swapcache占用的頁以及tmpfs文件的總內存使用是否超過這個百分比。
其他設置的情況下,只比較基於一般文件的未映射頁,不考慮其他相關頁。
page-cluster:
page-cluster是用來控制從swap空間換入數據的時候,一次連續讀取的頁數,這相當於對交換空間的預讀。這里的連續是指在swap空間上的連續,而不是在內存地址上的連續。
因為swap空間一般是在硬盤上,對硬盤設備的連續讀取將減少磁頭的尋址,提高讀取效率。
這個文件中設置的值是2的指數。就是說,如果設置為0,預讀的swap頁數是2的0次方,等於1頁。如果設置為3,就是2的3次方,等於8頁。
同時,設置為0也意味着關閉預讀功能。文件默認值為3。我們可以根據我們的系統負載狀態來設置預讀的頁數大小。
swap的相關操縱命令
可以使用mkswap將一個分區或者文件創建成swap空間。swapon可以查看當前的swap空間和啟用一個swap分區或者文件。swapoff可以關閉swap空間。
我們使用一個文件的例子來演示一下整個操作過程:
制作swap文件:
啟用swap文件:
關閉swap空間:
5、swap分區的優先級(priority)有啥用?
在使用多個swap分區或者文件的時候,還有一個優先級的概念(Priority)。
在swapon的時候,我們可以使用-p參數指定相關swap空間的優先級,值越大優先級越高,可以指定的數字范圍是-1到32767。
內核在使用swap空間的時候總是先使用優先級高的空間,后使用優先級低的。
當然如果把多個swap空間的優先級設置成一樣的,那么兩個swap空間將會以輪詢方式並行進行使用。
如果兩個swap放在兩個不同的硬盤上,相同的優先級可以起到類似RAID0的效果,增大swap的讀寫效率。
另外,編程時使用mlock()也可以將指定的內存標記為不會換出,具體幫助可以參考man 2 mlock。
最后
關於swap的使用建議,針對不同負載狀態的系統是不一樣的。有時我們希望swap大一些,可以在內存不夠用的時候不至於觸發oom-killer導致某些關鍵進程被殺掉,比如數據庫業務。
也有時候我們希望不要swap,因為當大量進程爆發增長導致內存爆掉之后,會因為swap導致IO跑死,整個系統都卡住,無法登錄,無法處理。
這時候我們就希望不要swap,即使出現oom-killer也造成不了太大影響,但是不能允許服務器因為IO卡死像多米諾骨牌一樣全部死機,而且無法登陸。跑cpu運算的無狀態的apache就是類似這樣的進程池架構的程序。
所以:
swap到底怎么用?
要還是不要?
設置大還是小?
相關參數應該如何配置?
是要根據我們自己的生產環境的情況而定的。
閱讀完本文后希望大家可以明白一些swap的深層次知識。
Q&A:
一個內存剩余還比較大的系統中,是否有可能使用swap?
A: 有可能,如果運行中的某個階段出發了這個條件”zonefile+zonefree<=high_wmark_pages(zone)“,就可能會swap。
swappiness設置為0就相當於關閉swap么?
A: 不是的,關閉swap要使用swapoff命令。swappiness只是在內存發生回收操作的時候用來平衡cache回收和swap交換的一個參數,調整為0意味着,盡量通過清緩存來回收內存。
A: swappiness設置為100代表系統會盡量少用剩余內存而多使用swap么?
不是的,這個值設置為100表示內存發生回收時,從cache回收內存和swap交換的優先級一樣。就是說,如果目前需求100M內存,那么較大機率會從cache中清除50M內存,再將匿名頁換出50M,把回收到的內存給應用程序使用。但是這還要看cache中是否能有空間,以及swap是否可以交換50m。內核只是試圖對它們平衡一些而已。
kswapd進程什么時候開始內存回收?
A: kswapd根據內存水位標記決定是否開始回收內存,如果標記達到low就開始回收,回收到剩余內存達到high標記為止。
如何查看當前系統的內存水位標記?
A: cat /proc/zoneinfo。
cat /proc/sys/vm/min_free_kbytes
67584
[steven@GZ-DBAMonitor ~]$ cat /proc/zoneinfo
Node 0, zone DMA
pages free 3661
min 29
low 36
high 43
scanned 0
spanned 4080
present 3563
nr_free_pages 3661
nr_inactive_anon 0
nr_active_anon 0
nr_inactive_file 0
nr_active_file 0
nr_unevictable 0
nr_mlock 0
nr_anon_pages 0
nr_mapped 0
nr_file_pages 0
nr_dirty 0
nr_writeback 0
nr_slab_reclaimable 0
nr_slab_unreclaimable 0
nr_page_table_pages 0
nr_kernel_stack 0
nr_unstable 0
nr_bounce 0
nr_vmscan_write 0
nr_writeback_temp 0
nr_isolated_anon 0
nr_isolated_file 0
nr_shmem 0
numa_hit 1
numa_miss 0
numa_foreign 0
numa_interleave 0
numa_local 1
numa_other 0
nr_anon_transparent_hugepages 0
protection: (0, 3896, 8062, 8062)
pagesets
cpu: 0
count: 0
high: 0
batch: 1
vm stats threshold: 6
cpu: 1
count: 0
high: 0
batch: 1
vm stats threshold: 6
cpu: 2
count: 0
high: 0
batch: 1
vm stats threshold: 6
cpu: 3
count: 0
high: 0
batch: 1
vm stats threshold: 6
all_unreclaimable: 1
prev_priority: 12
start_pfn: 16
inactive_ratio: 1
Node 0, zone DMA32
pages free 23509
min 8150
low 10187
high 12225
scanned 0
spanned 1044480
present 997416
nr_free_pages 23509
nr_inactive_anon 85429
nr_active_anon 230397
nr_inactive_file 197266
nr_active_file 197111
nr_unevictable 0
nr_mlock 0
nr_anon_pages 16079
nr_mapped 3958
nr_file_pages 397771
nr_dirty 15
nr_writeback 0
nr_slab_reclaimable 18356
nr_slab_unreclaimable 834
nr_page_table_pages 1636
nr_kernel_stack 18
nr_unstable 0
nr_bounce 0
nr_vmscan_write 41089
nr_writeback_temp 0
nr_isolated_anon 0
nr_isolated_file 0
nr_shmem 2982
numa_hit 1958783047
numa_miss 0
numa_foreign 0
numa_interleave 0
numa_local 1958783047
numa_other 0
nr_anon_transparent_hugepages 579
protection: (0, 0, 4166, 4166)
pagesets
cpu: 0
count: 56
high: 186
batch: 31
vm stats threshold: 36
cpu: 1
count: 108
high: 186
batch: 31
vm stats threshold: 36
cpu: 2
count: 98
high: 186
batch: 31
vm stats threshold: 36
cpu: 3
count: 147
high: 186
batch: 31
vm stats threshold: 36
all_unreclaimable: 0
prev_priority: 12
start_pfn: 4096
inactive_ratio: 5
Node 0, zone Normal
pages free 9437
min 8715
low 10893
high 13072
scanned 0
spanned 1081344
present 1066560
nr_free_pages 9437
nr_inactive_anon 62693
nr_active_anon 62938
nr_inactive_file 77437
nr_active_file 77643
nr_unevictable 0
nr_mlock 0
nr_anon_pages 24111
nr_mapped 6987
nr_file_pages 160469
nr_dirty 7
nr_writeback 0
nr_slab_reclaimable 3250
nr_slab_unreclaimable 6629
nr_page_table_pages 3579
nr_kernel_stack 313
nr_unstable 0
nr_bounce 0
nr_vmscan_write 111479
nr_writeback_temp 0
nr_isolated_anon 0
nr_isolated_file 0
nr_shmem 3743
numa_hit 418047423
numa_miss 0
numa_foreign 0
numa_interleave 20188
numa_local 418047423
numa_other 0
nr_anon_transparent_hugepages 188
protection: (0, 0, 0, 0)
pagesets
cpu: 0
count: 1
high: 186
batch: 31
vm stats threshold: 42
cpu: 1
count: 175
high: 186
batch: 31
vm stats threshold: 42
cpu: 2
count: 99
high: 186
batch: 31
vm stats threshold: 42
cpu: 3
count: 66
high: 186
batch: 31
vm stats threshold: 42
all_unreclaimable: 0
prev_priority: 12
start_pfn: 1048576
inactive_ratio: 6
ps aux |grep swap
root 72 0.0 0.0 0 0 ? S May05 0:24 [kswapd0] kernel swap daemon
值為0、1、60、100時的效果
0 Linux3.5或以上,寧願用OOM Killer也不用swap
Linux3.4或之前,寧願用swap也不用OOM Killer
1 Linux3.5或以上,寧願用swap也不用OOM Killer
60 默認值
100 操作系統主動使用swap
redis開發與運維 P367
為了不被OOM Killer
centos7或以上,大於1即可
centos6或以下,值越少,越不會OOM Killer
Red Hat Enterprise Linux 7
Release General Availability Date redhat-release Errata Date* Kernel Version
RHEL 7.2 2015-11-19 2015-11-19 RHEA-2015:2461 3.10.0-327
RHEL 7.1 2015-03-05 2015-03-05 RHEA-2015:0524 3.10.0-229
RHEL 7.0 GA 2014-06-09 - 3.10.0-123
Codename: Maipo (based on a mix of Fedora 19, Fedora 20, and several modifications)
Red Hat Enterprise Linux 6
Release General Availability Date redhat-release Errata Date* Kernel Version
RHEL 6.8 TBA TBA TBA
RHEL 6.7 2015-07-22 2015-07-22 RHEA-2015:1423 2.6.32-573
RHEL 6.6 2014-10-14 2014-10-13 RHEA-2014:1608 2.6.32-504
RHEL 6.5 2013-11-21 2013-11-20 RHSA-2013:1645-2 2.6.32-431
OOM Killer進程會為每個用戶進程設置一個權重,這個權重越高,被下手的概率越高,反之越低,每個進程的權重存放在/proc/進程號/oom_score中,這個值受/proc/進程號/oom_adj控制,oom_adj在不同Linux發行版最小值不同,當oom_adj設置為最小值時,該進程不會被OOM Killer殺掉
ll /proc/891/oom*
-rw-r--r-- 1 root root 0 Mar 8 00:06 /proc/891/oom_adj
-r--r--r-- 1 root root 0 Mar 8 00:06 /proc/891/oom_score
-rw-r--r-- 1 root root 0 Mar 8 00:06 /proc/891/oom_score_adj
可以將某個進程的oom_adj設置為最低值,減少被OM Killer殺掉幾率
for redis_pid in $(pgrep -f "redis-server")
do
echo -17 >/proc/${redis_pid}/oom_adj
done
如果swap都是0kb或4kb,則是正常現象,否則說明該進程的內存已經被交換出去了
smaps:記錄了當前進程所對應的內存映像信息
cat /proc/進程號/smaps |grep -i swap
Swap: 0 kB
Swap: 0 kB
Swap: 0 kB
Swap: 0 kB
Swap: 0 kB
比如redis的進程號是889,redis不能使用swap,否則性能會有影響
cat /proc/889/smaps |grep -i swap
Swap: 0 kB
Swap: 0 kB
Swap: 0 kB
Swap: 0 kB
Swap: 0 kB