服务器总内存16G,所有进程占用内存4G,slab占用7G,其中dentry占用6G,一直无法释放。导致服务器内存持续在80%以上。
dentry的作用是目录项缓存,当打开一个文件时,系统会分配一部分dentry给这个文件,便于下次打开更快。
最终排查发现是由于curl时,会打开/usr/local/lib
下的*.so
文件,但这个路径下没有这些文件,于是打开时报错No such file or directory
,导致占用了很多dentry,由于打开失败,只有open
操作,没有close
操作,dentry无法及时释放,显示还是ACTIVE
状态,最终越积累越多,导致内存占满。
处理方式,将/lib64/*.so
、/usr/lib64/*.so
中的文件复制到/usr/local/lib
中,dentry就释放掉了。
收到阿里云报警,内存超过80%。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4232 www 20 0 6681m 534m 5572 S 0.0 3.3 249:54.28 java -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1g -Xmx1g -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -jar -D
13183 root 10 -10 209m 89m 4652 S 5.7 0.6 3665:27 /usr/local/aegis/aegis_client/aegis_10_85/AliYunDun
16022 www 20 0 275m 46m 8920 S 7.1 0.3 0:28.12 php
28688 www 20 0 274m 46m 9188 S 0.0 0.3 0:02.68 php
28784 www 20 0 272m 44m 9192 S 1.4 0.3 0:02.82 php
28542 www 20 0 272m 44m 9020 S 2.8 0.3 0:02.84 php
28574 www 20 0 272m 44m 9020 S 0.0 0.3 0:02.90 php
28578 www 20 0 272m 44m 9020 S 0.0 0.3 0:02.66 php
28788 www 20 0 272m 44m 9020 S 1.4 0.3 0:02.87 php
28820 www 20 0 272m 44m 9020 S 2.8 0.3 0:02.75 php
28824 www 20 0 272m 44m 9020 S 2.8 0.3 0:03.01 php
28538 www 20 0 272m 44m 9020 S 1.4 0.3 0:02.68 php
28720 www 20 0 272m 44m 9020 S 4.3 0.3 0:02.76 php
28684 www 20 0 272m 44m 9020 S 4.3 0.3 0:02.94 php
28614 www 20 0 272m 44m 9020 S 2.8 0.3 0:02.80 php
28610 www 20 0 272m 43m 9020 S 2.8 0.3 0:02.85 php
28725 www 20 0 272m 43m 9020 S 4.3 0.3 0:02.81 php
26947 www 20 0 263m 33m 7672 S 1.4 0.2 0:03.17 php
26951 www 20 0 263m 33m 7672 S 2.8 0.2 0:03.02 php
23616 www 20 0 263m 32m 6880 S 0.0 0.2 0:02.04 php-fpm: pool www
31608 www 20 0 263m 31m 7672 S 2.8 0.2 0:01.20 php
23647 www 20 0 261m 31m 7040 S 0.0 0.2 0:01.10 php-fpm: pool www
23658 www 20 0 262m 30m 5872 S 0.0 0.2 0:01.64 php-fpm: pool www
23615 www 20 0 259m 29m 7008 S 0.0 0.2 0:01.21 php-fpm: pool www
23607 www 20 0 259m 29m 7012 S 0.0 0.2 0:01.23 php-fpm: pool www
23683 www 20 0 260m 29m 5868 S 0.0 0.2 0:01.71 php-fpm: pool www
23656 www 20 0 260m 29m 5796 S 0.0 0.2 0:02.36 php-fpm: pool www
没有找到占用大内存的进程。
[root@192.168.1.218 ~]# free -m
total used free shared buffers cached
Mem: 15950 14448 1502 0 206 1675
-/+ buffers/cache: 12566 3384
Swap: 9897 159 9738
-/+ buffers/cache
的第一列代表当前已使用(used - buffer - cache),第二列表示剩余可用内存(free + buffer + cache)。
能看出系统已用内存12G。
[root@192.168.1.218 ~]# grep Pss /proc/[1-9]*/smaps | awk '{total+=$2}; END {print total}'
4138253
[root@192.168.1.218 ~]
发现所有进程只占用4G内存。还剩8G内存不知道被谁占了。
[root@192.168.1.218 ~]#cat /proc/meminfo
MemTotal: 16333736 kB
MemFree: 2746984 kB
Buffers: 104976 kB
Cached: 1207308 kB
Slab: 8375144 kB
SReclaimable: 6610836 kB
SUnreclaim: 1764308 kB
可以看到,slab占用了8G左右。其中可释放SReclaimable
6G多。
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
26144880 26143568 99% 0.19K 130724420 5228976K dentry
25382036 25381364 99% 0.06K 43020459 1720816K size-64
1319488 1319281 99% 0.99K 3298724 1319488K ext4_inode_cache
404151 275805 68% 0.10K 1092337 43692K buffer_head
52899 42371 80% 0.05K 68777 2748K anon_vma_chain
43092 34580 80% 0.20K 226819 9072K vm_area_struct
41818 26036 62% 0.55K 59747 23896K radix_tree_node
28428 16609 58% 0.04K 30992 1236K anon_vma
可以看出slab占用了5G多。
[root@192.168.1.218 ~]# cat /proc/sys/fs/dentry-state
26191771 26140830 45 0 0 0
[root@192.168.1.218 ~]#
第一列表示申请的dentry数量,第二列表示可以未使用的数量,可以看到未使用数量很高,但是没释放。
先查看php进程是否有频繁打开不存在的文件,发现有打开关闭文件,但不是不存在的文件。
[root@192.168.1.218 ~]# strace -fp 31234 -e trace=stat,open,close,unlink
网上查到有说是curl的版本有问题,会创建很多临时文件,排查下curl
[root@192.168.1.218 ~]# strace -f -e trace=open,unlink,close curl "https://www.baidu.com"
发现没有打开临时文件,但是有很多.so文件不存在,打开失败了,初步确定就是这个引起的*
No such file or directory
报错,使用slabtop查看dentry,发现已经在下降了,大概3分钟后下降至正常水平。cp libcrypto.so.10 /usr/local/lib/libcrypto.so.10
cp libz.so.1 /usr/local/lib/libz.so.1
cp librt.so.1 /usr/local/lib/librt.so.1
cp libpthread.so.0 /usr/local/lib/libpthread.so.0
cp libc.so.6 /usr/local/lib/libc.so.6
cp libldap-2.4.so.2 /usr/local/lib/libldap-2.4.so.2
cp libgssapi_krb5.so.2 /usr/local/lib/libgssapi_krb5.so.2
cp libkrb5.so.3 /usr/local/lib/libkrb5.so.3
cp libcom_err.so.2 /usr/local/lib/libcom_err.so.2
cp libk5crypto.so.3 /usr/local/lib/libk5crypto.so.3
cp libdl.so.2 /usr/local/lib/libdl.so.2
cp liblber-2.4.so.2 /usr/local/lib/liblber-2.4.so.2
cp libresolv.so.2 /usr/local/lib/libresolv.so.2
cp libsasl2.so.2 /usr/local/lib/libsasl2.so.2
cp libssl3.so /usr/local/lib/libssl3.so
cp libsmime3.so /usr/local/lib/libsmime3.so
cp libnss3.so /usr/local/lib/libnss3.so
cp libnssutil3.so /usr/local/lib/libnssutil3.so
cp libplds4.so /usr/local/lib/libplds4.so
cp libplc4.so /usr/local/lib/libplc4.so
cp libnspr4.so /usr/local/lib/libnspr4.so
cp libkrb5support.so.0 /usr/local/lib/libkrb5support.so.0
cp libkeyutils.so.1 /usr/local/lib/libkeyutils.so.1
cp libcrypt.so.1 /usr/local/lib/libcrypt.so.1
cp libselinux.so.1 /usr/local/lib/libselinux.so.1
cp libfreebl3.so /usr/local/lib/libfreebl3.so
cp libssl.so.10 /usr/local/lib/libssl.so.10
cp libnss_files.so.2 /usr/local/lib/libnss_files.so.2
cp libnss_dns.so.2 /usr/local/lib/libnss_dns.so.2
dentry降到1G了,属于正常范围。
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
5650780 5650584 99% 0.19K 282539 20 1130156K dentry
2389323 1066827 44% 0.06K 40497 59 161988K size-64
89432 80871 90% 0.99K 22358 4 89432K ext4_inode_cache
93972 92969 98% 0.64K 15662 6 62648K proc_inode_cache
内存使用已降到6G以内了。
[root@192.168.1.218 ~]# free -m
total used free shared buffers cached
Mem: 15950 8189 7761 0 1428 1010
-/+ buffers/cache: 5749 10200
Swap: 9897 492 9405
[root@192.168.1.218 ~]#
修改 vm.min_free_kbytes 和 vm.extra_free_kbytes,增加slab回收阈值
sysctl -w vm.extra_free_kbytes=836787
sysctl -w vm.min_free_kbytes=836787