1. 程式人生 > 其它 >Linux 伺服器程序避免 OOM 的方法

Linux 伺服器程序避免 OOM 的方法

問題描述
Linux 核心有個機制叫 OOM killer(Out-Of-Memory killer),該機制會監控那些佔用記憶體過大,尤其是瞬間很快消耗大量記憶體的程序,為了防止記憶體耗盡而核心會把該程序殺掉。典型的情況是:某天一臺機器突然 ssh 遠端登入不了,但能 ping 通,說明不是網路的故障,原因是 sshd 程序被 OOM killer 殺掉了(多次遇到這樣的假死狀況)。重啟機器後檢視系統日誌「/var/log/messages」會發現「Out of Memory: Kill process 1865(sshd)」類似的錯誤資訊。如何防止重要的系統程序觸發(OOM)機制而被殺死呢?只需要一招,就可以輕鬆避免。設定引數「/proc/PID/oom_adj為-17」,可臨時關閉 Linux 核心的 OOM 機制。核心會通過特定的演算法給每個程序計算一個分數來決定殺哪個程序,每個程序的 OOM 分數可以在「/proc/PID/oom_score」中找到。處理辦法
1. 方法一:設定引數/proc/PID/oom_adj為-17如何防止mongod被殺,可以這樣操作:(1) 編寫指令碼檔案oomadj.sh,內容如下:
  1. !/bin/bash

  2. netstat -ntlup |grep mongod |awk '{print$NF}' |awk -F '/' '{print$(NF-1)}' |while read PID;

  3. do

  4. echo -17 >/proc/$PID/oom_adj;

  5. done

(2) 設定定時計劃
  1. [root@mnkj-mongodb-01 ~]crontab -e

  2. /1    * /root/oomadj.sh

至於為什麼用-17而不用其他數值(預設值為0),這個是由linux核心定義的,檢視核心原始碼可知:以 linux-3.3.6 版本的 kernel 原始碼為例,路徑為「linux-3.6.6/include/linux/oom.h」,閱讀核心原始碼可「oom_adj」的可調值為 15 到 -16,其中 15 最大-16 最小,-17 為禁止使用OOM。「oom_score」為 2 的 N 次方計算出來的,其中 N 就是程序的「oom_adj」值,所以「oom_score」的分數越高就越會被核心優先殺掉。2. 方法二:修改核心引數禁止OOM機制
  1.  sysctl -w vm.panic_on_oom=1

  2. vm.panic_on_oom = 1 //1表示關閉,預設為0表示開啟OOM

  3.  sysctl -p

注意事項注意:
  • Kernel-2.6.26之前版本的 oomkiller 演算法不夠精確,RHEL 6.x 版本的 2.6.32 可以解決這個問題。

  • 子程序會繼承父程序的 oom_adj。

  • OOM 不適合於解決記憶體洩漏(Memory leak)的問題。

有時 free 檢視還有充足的記憶體,但還是會觸發 OOM,是因為該程序可能佔用了特殊的記憶體地址空間。OOM killer 是保證系統記憶體不被個別程序消耗殆盡非常實用的機制,但是在實際工作除了程序執行過多會造成記憶體佔用過高,還有很多其他的因素比如:訪問增多、遭受攻擊等...這時我們不僅要使用好 OOM killer,更需要關注伺服器的資源使用情況,需要完善的實時監控體系,能夠對於系統存在問題能夠及時的發現並處理,保證業務穩定執行。