Pod中進程內存緩存問題


背景

環境:openshift3.11

開發反映部署在容器中的java應用內存持續增長,只升不降,具體為:

java應用部署在容器中,配置的jvm參數為-Xms1024m -Xmx1024m,容器memory request為1G, memory limit為4G,通過openshift的Pod metrics監控發現,應用消耗內存達到99%(只剩下3M),但是Pod處於Running狀態,沒有發生OOM,Pod容器java進程正常接收出了請求。增加容器memory limit至8G,內存依然消耗至99%。

 

排查過程

容器為單進程模型,其中只運行了一個java進程。通過docker stats containerId查看容器消耗的內存為1.735g,通過top命令查看到得java進程的res值為1.7g

查看容器的內存使用信息:

#進入cgroup工作目錄
cd /sys/fs/cgroup/memory/

#查找容器id
docker ps | grep {name}

#通過容器id查找Pod slice目錄,如下
systemd-cgls | grep -C3 contianerId
│   └─kubepods-burstable-pod2df5422b_fed3_11e9_be3c_5254008ade6c.slice
│     ├─docker-b9f2ce762cdc8435167bff21eb2cd31d9e1214ad75f2326bffba5e2f1d46422d.scope #業務容器
│     │ ├─32014 tini -- /run.sh
│     │ └─32584 java -jar /deployments/test.jar
│     └─docker-77fde00b840ba03d4d2d52dd0e08ff2a2db7c85e0233bf2847aaa8fa2250b657.scope #根容器
│       └─28520 /usr/bin/pod

#查看內存信息相關目錄如下
cat /sys/fs/cgroup/memory/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod2df5422b_fed3_11e9_be3c_5254008ade6c.slice/docker-b9f2ce762cdc8435167bff21eb2cd31d9e1214ad75f2326bffba5e2f1d46422d.scope/memory.usage_in_bytes

cat /sys/fs/cgroup/memory/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod2df5422b_fed3_11e9_be3c_5254008ade6c.slice/docker-b9f2ce762cdc8435167bff21eb2cd31d9e1214ad75f2326bffba5e2f1d46422d.scope/memory.stat
memory.usage_in_bytes文件中的值即為metrics監控中的值
memory.stat文件中cahce字段的值就是這個容器用於cache的內存

 

看來metrics監控中的值就是取自memory.usage_in_bytes,而這個值是包含memory.stat中的cache的

那應用為什么會消耗大量cache?

#查看java應用的log4j2配置,發現其中配置了最大保留兩個歸檔文件,每個歸檔文件大小為2GB,也就是說日志量最大為6GB左右,查看pod中的日志也確實達到了最大的量。做以下步驟驗證
1.取消日志輸出到文件,metrics監控到得值與dokcer stats或top中的值相近
2.配置最大保留兩個歸檔文件,每個歸檔文件大小為100M,查看memory.stat中的cache值為350M左右

也就是說log42配置的日志輸出到文件會緩存到內存

 

這個緩存對容器有什么影響嗎?

#是沒有任何影響的,java進程只消耗內存1.7G左右,剩余的內存是被log4j用於緩存以充分利用內存提高讀寫效率,當java進程實例消耗內存增加,cache也會相應的釋放,這應該是linux的內存機制決定的
Linux has this basic rule: a page of free RAM is wasted RAM. RAM is used for a lot more than just user application data. It also stores data for the kernel itself and, most importantly, can mirror data stored on the disk for super-fast access, this is reported usually as “buffers/cache”, “disk cache” or “cached” by top. Cached memory is essentially free, in that it can be replaced quickly if a running (or newly starting) program needs the memory.

 

所以在prometheus監控告警中也應該去掉cache這一部分

 

參考:

http://trustmeiamadeveloper.com/2016/03/18/where-is-my-memory-java/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM