背景
最近發現集群主節點總有進程宕機,定位了大半天才找到原因,分享一下
排查過程
查詢hiveserver2和namenode日志,都是正常的,突然日志就不記錄了,直到我重啟之后又恢復工作了。
排查各種日志都是正常的,直到查看Grafana,發現內存滿了
在這個節點下已無內存資源可用,在服務宕掉的節點內存使用突然下降,猜測是linux內核的杰作,故查詢系統日志
grep "Out of memory" /var/log/messages
果然存在因OOM被殺掉的進程
進程被殺的原因
Linux 內核有個機制叫OOM killer,全稱為 Out Of Memory killer,很形象的一個名字——內存溢出殺手,這個機制會監控那些占用內存過大,尤其是瞬間占用內存很快的進程,為防止機器內存耗盡而主動把該進程殺掉。
當內核檢測到系統內存不足、挑選并殺掉某個進程的過程可以參考內核源代碼 linux/mm/oom_kill.c(2023-4-4 23:24:07確認了此文件存在),當系統內存不足的時候,out_of_memory() 函數被觸發,然后調用 select_bad_process() 函數選擇一個進程殺掉,這個選擇的過程是通過調用 oom_badness() 函數實現的,挑選的算法和想法都暴力但樸實:就是找到最占用內存的進程。
出現問題的原因
最近剛剛增加了sentry和hivemetastore內存大小,導致機器內存不夠了。
解決方案
1.調整機器進程分布,確保機器不會出現內存超用
2.可以通過設置/proc/sys/vm/overcommit_memory為不同的值來調整OverCommit策略。
overcommit_memory可以取3個值:
- 0:默認值,由Linux內核通過一些啟發式算法來決定是否超售和超售的大小,一般允許輕微的超售,拒絕一些明顯不可能提供的請求,同時做一些規則限制,比如不同用戶overcommit的大小也不一樣。
- 1:允許,不做限制的超售,當然這個也不是無限大,還受到尋址空間的限制,32位系統最大可能只有4G,64位系統大概16T左右。
- 2:禁止,禁止超售,系統能夠分配的內存不會超過swap+實際物理內存*overcommit_ratio,該值可以通過/proc/sys/vm/overcommit_ratio設置,默認50%。
vi /etc/sysctl.conf
-- 添加
vm.overcommit_memory=1
-- 重啟生效
sysctl -p
總結
如果你發現運行了一段時間的進程突然不見了,那可能是內核嫉妒生恨把它給干掉了
查詢內存溢出被殺掉的進程可以直接通過系統日志來查 grep “Out of memory” /var/log/messages
也可以通過專門的命令查找 dmesg -T | grep “Out of memory”