容器及linux内核技术

docker容器的内存问题排查(“内存丢失”)

2019-12-20  本文已影响0人  zhangzhifei

场景描述

容器内可用内存远没有达到cgroup限制,就已经OOM(Out Of Memory Killer)。容器套餐4c8g,top看占内存最多的进程大约17m左右,总共100个,总内存也不到2g,但是memory.usage_in_bytes已经达到8g(free看也是一样),cache也只有几百兆,久而久之,cache所占内存也被耗尽,容器内进程oom,实际可用内存不到1g。在这记录下问题排查过程。

排查问题容器环境

由于达到oom的现场已经不在,现在使用下面的场景进行演示:
容器套餐4c8g,working_set内存6.8g(容器内一般用working_set来评内存使用情况,working_set=rss+活跃的cache),rss600m,cache1.7g,业务进程使用2g。目前working_set远小于rss+cache。

排查过程

  1. 进容器看看业务进程消耗资源
    docker exec进到容器top后输入M(大写M),查看消耗内存最多的进程
top - 15:12:57 up 7 days,  1:00,  1 user,  load average: 0.24, 0.08, 0.02
Tasks: 145 total,   1 running, 144 sleeping,   0 stopped,   0 zombie
Cpu(s):  1.0%us,  0.0%sy,  0.0%ni, 99.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   8192000k total,  7724968k used,   467032k free,        0k buffers
Swap:        0k total,        0k used,        0k free,  1745040k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                   204 root      20   0 2527m  19m 3140 S  0.0  0.2   0:43.40 docker-qalarm                                            
35382 nobody    20   0  306m  17m 9.8m S  0.0  0.2   0:20.51 php-fpm                                                  
35373 nobody    20   0  306m  17m 9984 S  0.0  0.2   0:20.88 php-fpm                                                  
35444 nobody    20   0  306m  17m 9964 S  0.0  0.2   0:20.55 php-fpm                                                  
35350 nobody    20   0  306m  17m 9936 S  0.0  0.2   0:20.44 php-fpm                                                  
35407 nobody    20   0  306m  17m 9976 S  0.0  0.2   0:20.22 php-fpm                                                  
35392 nobody    20   0  306m  17m 9924 S  0.0  0.2   0:20.33 php-fpm                                                  
35368 nobody    20   0  306m  17m 9916 S  0.0  0.2   0:20.22 php-fpm                                                  
35398 nobody    20   0  306m  17m 9908 S  0.0  0.2   0:20.27 php-fpm                                                  
35357 nobody    20   0  306m  17m 9912 S  0.3  0.2   0:20.94 php-fpm                                                  
35463 nobody    20   0  306m  17m 9912 S  0.0  0.2   0:20.22 php-fpm                                                  
35437 nobody    20   0  306m  17m 9900 S  0.0  0.2   0:21.09 php-fpm                                                  
35464 nobody    20   0  306m  17m 9896 S  0.0  0.2   0:20.46 php-fpm                                                  
35384 nobody    20   0  306m  17m 9888 S  0.3  0.2   0:19.90 php-fpm                                                  
35348 nobody    20   0  306m  17m 9876 S  0.0  0.2   0:20.53 php-fpm                                                  
35365 nobody    20   0  306m  17m 9880 S  0.0  0.2   0:20.71 php-fpm                                                  
35358 nobody    20   0  306m  17m 9868 S  0.0  0.2   0:20.42 php-fpm                                                  
35420 nobody    20   0  306m  17m 9892 S  0.0  0.2   0:19.88 php-fpm                                                  
35424 nobody    20   0  306m  17m 9864 S  0.0  0.2   0:20.52 php-fpm                                                  
35389 nobody    20   0  306m  17m 9872 S  0.0  0.2   0:20.18 php-fpm                                                  
35335 nobody    20   0  306m  17m 9908 S  0.0  0.2   0:20.84 php-fpm                                                  
35468 nobody    20   0  306m  17m 9912 S  0.3  0.2   0:20.58 php-fpm
[root@robot-speaker-e862e0-7c84fb65cd-whv5d /home/q/system/speaker-robot]# ps -ef | grep php-fpm|grep -v grep|wc -l
129

发现使用内存最多的php-fpm 进程用了17M,129个进程,一共使用内存2.1g。内存使用了7.4g、未使用450M、cache1.7g(我们使用了lxcfs做容器视图隔离,所以内存显示的是容器的真实情况),还有5g左右内存去哪了
2、进到内存容器cgroup

7af95a9ac99dd32c8bc51aa4531f75a836d1b5e6c29]# ls
cgroup.clone_children           memory.kmem.tcp.max_usage_in_bytes  memory.oom_control
cgroup.event_control            memory.kmem.tcp.usage_in_bytes      memory.pressure_level
cgroup.procs                    memory.kmem.usage_in_bytes          memory.soft_limit_in_bytes
memory.failcnt                  memory.limit_in_bytes               memory.stat
memory.force_empty              memory.max_usage_in_bytes           memory.swappiness
memory.kmem.failcnt             memory.memsw.failcnt                memory.usage_in_bytes
memory.kmem.limit_in_bytes      memory.memsw.limit_in_bytes         memory.use_hierarchy
memory.kmem.max_usage_in_bytes  memory.memsw.max_usage_in_bytes     notify_on_release
memory.kmem.slabinfo            memory.memsw.usage_in_bytes         tasks
memory.kmem.tcp.failcnt         memory.move_charge_at_immigrate
memory.kmem.tcp.limit_in_bytes  memory.numa_stat
[root@docker123 /sys/fs/cgroup/memory/kubepods/burstable/pod6e726ccc-1d6f-11ea-851f-fa163e9a7739/45bb864dfe68379c6d2f07af95a9ac99dd32c8bc51aa4531f75a836d1b5e6c29]#
7af95a9ac99dd32c8bc51aa4531f75a836d1b5e6c29]# cat  memory.usage_in_bytes
7934582784

确实是7g多

7af95a9ac99dd32c8bc51aa4531f75a836d1b5e6c29]# cat memory.stat
cache 1806925824
rss 622092288
rss_huge 287309824
mapped_file 20508672
swap 0
pgpgin 17583007
pgpgout 17135620
pgfault 48558141
pgmajfault 1180
inactive_anon 17465344
active_anon 628965376
inactive_file 1058193408
active_file 724385792
unevictable 0
hierarchical_memory_limit 8388608000
hierarchical_memsw_limit 16777216000
total_cache 1806925824
total_rss 622092288
total_rss_huge 287309824
total_mapped_file 20508672
total_swap 0
total_pgpgin 17583007
total_pgpgout 17135620
total_pgfault 48558141
total_pgmajfault 1180
total_inactive_anon 17465344
total_active_anon 628965376
total_inactive_file 1058193408
total_active_file 724385792
total_unevictable 0

没有占用内存特别大的项,也就是远没达到top所见。另外忘记说,上边单位都是字节

7af95a9ac99dd32c8bc51aa4531f75a836d1b5e6c29]# cat memory.kmem.usage_in_bytes
5513891840

果然是5g

7af95a9ac99dd32c8bc51aa4531f75a836d1b5e6c29]# cat memory.kmem.slabinfo
slabinfo - version: 2.1
...
taskstats           1960   1960    328   49    4 : tunables    0    0    0 : slabdata     40     40      0
xfs_ili           3945336 3945336    168   48    2 : tunables    0    0    0 : slabdata  82195  82195      0
xfs_btree_cur       1560   1560    208   39    2 : tunables    0    0    0 : slabdata     40     40      0
posix_timers_cache  16071  16071    248   33    2 : tunables    0    0    0 : slabdata    487    487      0
scsi_cmd_cache      1440   1440    448   36    4 : tunables    0    0    0 : slabdata     40     40      0
xfs_log_ticket      1760   1760    184   44    2 : tunables    0    0    0 : slabdata     40     40      0
cfq_queue           1400   1400    232   35    2 : tunables    0    0    0 : slabdata     40     40      0
inode_cache         2200   2200    592   55    8 : tunables    0    0    0 : slabdata     40     40      0
radix_tree_node    35635  39984    584   28    4 : tunables    0    0    0 : slabdata   1428   1428      0
bio-2               2040   2040    320   51    4 : tunables    0    0    0 : slabdata     40     40      0
fanotify_event_info   2920   2920     56   73    1 : tunables    0    0    0 : slabdata     40     40      0
blkdev_ioc          1560   1560    104   39    1 : tunables    0    0    0 : slabdata     40     40      0
xfs_inode         3959772 3959772    960   34    8 : tunables    0    0    0 : slabdata 116478 116478      0
Acpi-ParseExt       2240   2240     72   56    1 : tunables    0    0    0 : slabdata     40     40      0
...

可以看出关于文件元数据缓存就占了4g多,上图第三列是对象数量,第四列是对象大小,所以xfs_inode占用内存=3959772 * 960 /1024/1024/1024,约等于3.5g,xfs_ili 0.7g,这已经4g多了。所以基本可以断定是业务进程操作文件多过导致

[root@robot-speaker-e862e0-7c84fb65cd-whv5d /data/php/session]# ls -lR | grep "^-"| wc -l
3941117

可见session文件数与slab中的xfs_inode基本相当,所以可以断定罪魁祸首在此

验证结果

经过与业务沟通,他们清理的大量session文件后,slab内存明显降下来了。


image.png

结论

  1. 业务应尽可能的避免这种上百万级别的小文件
  2. 更优雅的方式是限制容器内可用内核缓存的比例(还在尝试)

参考文档

https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/6/html/resource_management_guide/sec-memory
https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/memory.html
https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html

上一篇下一篇

猜你喜欢

热点阅读