當 Linux 系統內存不足時,內核會找出一個進程 kill 掉它釋放內存,旨在保障整個系統不至于崩潰。如果 ES 按照最佳實踐去實施部署,會保留一半的內存,不至于發生此類事情。但事情總有例外,有的朋友可能 ES 和其他的程序部署在一起,當主機內存不足時,那么 ES 很有可能會被內核 Kill 掉。
關于 OOM Killer
Linux 內核根據系統上運行的應用程序需求分配內存。由于許多應用程序預先分配內存,并且通常不使用分配的內存,因此內核設計為能夠超額使用內存以提高內存使用效率。這種超額提交模型允許內核分配的內存多于其實際可用的內存。如果進程實際使用了分配給它的內存,則內核會將這些資源提供給應用程序。當太多應用程序開始使用它們分配的內存時,超額提交模型有時會出現問題,內核必須開始終止進程才能保持系統運行。內核用于恢復系統內存的機制稱為內存不足終止程序或簡稱 OOM Killer。
找出進程被 Kill 的原因
在對應用程序被 OOM Killer 終止的問題進行故障排除時,有幾條線索可能會表明進程被終止的方式和原因。在以下示例中,我們將查看操作系統的日志,看看是否可以找到問題的根源。由于內存不足的情況,Elasticsearch 進程被 OOM Killer 程序終止。Killed 中的大寫 K 表示該進程被 -9 信號終止,這通常是一個兆頭,表明 OOM Killer 可能是罪魁禍首。
grep -i kill /var/log/messages*
host kernel: Out of Memory: Killed process 2592 (elasticsearch).
OOM Killer 選擇機制
OOM Killer 是 Linux 系統中用于內存管理的一個重要機制。當系統內存不足時,OOM Killer 會遍歷所有進程,綜合考慮進程占用的內存和配置的 oom_score_adj 值來計算每個進程的 oom_score,最終選擇得分最高的進程進行終止。如果多個進程得分相同,則優先終止最先被掃描到的進程。
你可以通過查看 /proc/[pid]/oom_score 文件來獲取每個進程的 oom_score 值,該值會根據進程內存使用情況的變化而實時更新。當前得分最高的進程將在下一次 OOM 事件中被優先終止。
如果你希望某個進程在內存不足時避免被優先終止,可以通過調整該進程的 oom_score_adj 值來降低其 oom_score。
oom_adj 是一個舊的接口參數,其功能類似 oom_score_adj ,為了兼容,目前仍然保留這個參數,當操作這個參數的時候,kernel 實際上是會換算成 oom_score_adj 。
配置進程 oom_score_adj
通過上面的講解可知,我們可以通過配置進程的 oom_score_adj 或 oom_adj 來避免其在系統內存不足時被終止的風險。
如果我們想降低 PID 為 2592 進程被 OOM Killer 終止的可能性,我們可以執行以下操作:
# 新接口
echo -500 > /proc/2592/oom_score_adj# 老接口
echo -15 > /proc/2592/oom_adj
如果我們想提高 PID 為 2592 進程被 OOM Killer 終止的可能性,我們可以執行以下操作:
# 新接口
echo 500 > /proc/2592/oom_score_adj# 老接口
echo 10 > /proc/2592/oom_adj
如果你希望某個關鍵進程絕對不能被終止,可以執行以下操作:
# 新接口
echo -1000 > /proc/2592/oom_score_adj# 老接口
echo -17 > /proc/2592/oom_adj
希望對多程序混合部署的小伙伴有所幫助。