문제
커널 2.6.32 및 128GB 물리적 RAM이있는 CentOS 시스템은 며칠 전에 문제가 발생했습니다. 담당 시스템 관리자는 PHP-FPM 응용 프로그램이 스와핑으로 인해 더 이상 요청에 적시에 응답 free
하지 않았으며 메모리가 거의 남아 있지 않다는 것을 알고 기계를 재부팅하기로 결정했습니다.
여유 메모리는 Linux에서 혼란스러운 개념이 될 수 있으며 재부팅은 아마도 잘못된 일이라는 것을 알고 있습니다. 그러나 언급 된 관리자는 PHP 응용 프로그램 (내 책임)을 비난하고 더 이상 조사를 거부합니다.
내가 스스로 알아낼 수있는 것은 이것입니다 :
- 다시 시작하기 전에 사용 가능한 메모리 (버퍼 및 캐시 포함)는 수백 MB에 불과했습니다.
- 다시 시작하기 전에
/proc/meminfo
약 90GB (예, GB)의 Slab 메모리 사용량을보고했습니다. - 다시 시작한 후, 사용 가능한 메모리는 119GB로, 한 시간 내에 약 100GB로 줄어 듭니다. RES 열이 맨 위에 있습니다 (PHP 응용 프로그램의 특성상 몇 달 동안이 방법을 사용하는 것이 합리적입니다). 프로세스 목록에 비정상적이거나 주목할만한 양의 RAM을 소비하는 다른 것은 없습니다.
- 다시 시작한 후 Slab 메모리는 약 300MB였습니다.
그 이후로 시스템을 모니터링 해 왔으며, 특히 Slab 메모리는 하루 약 5GB의 속도로 직선으로 증가하고 있습니다. 에 의해보고 된 여유 메모리 free
와 /proc/meminfo
같은 비율로 감소한다. 슬래브는 현재 46GB입니다. slabtop
대부분에 따르면 dentry
항목에 사용됩니다 .
여유 메모리 :
free -m
total used free shared buffers cached
Mem: 129048 76435 52612 0 144 7675
-/+ buffers/cache: 68615 60432
Swap: 8191 0 8191
Meminfo :
cat /proc/meminfo
MemTotal: 132145324 kB
MemFree: 53620068 kB
Buffers: 147760 kB
Cached: 8239072 kB
SwapCached: 0 kB
Active: 20300940 kB
Inactive: 6512716 kB
Active(anon): 18408460 kB
Inactive(anon): 24736 kB
Active(file): 1892480 kB
Inactive(file): 6487980 kB
Unevictable: 8608 kB
Mlocked: 8608 kB
SwapTotal: 8388600 kB
SwapFree: 8388600 kB
Dirty: 11416 kB
Writeback: 0 kB
AnonPages: 18436224 kB
Mapped: 94536 kB
Shmem: 6364 kB
Slab: 46240380 kB
SReclaimable: 44561644 kB
SUnreclaim: 1678736 kB
KernelStack: 9336 kB
PageTables: 457516 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 72364108 kB
Committed_AS: 22305444 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 480164 kB
VmallocChunk: 34290830848 kB
HardwareCorrupted: 0 kB
AnonHugePages: 12216320 kB
HugePages_Total: 2048
HugePages_Free: 2048
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 5604 kB
DirectMap2M: 2078720 kB
DirectMap1G: 132120576 kB
석판 :
slabtop --once
Active / Total Objects (% used) : 225920064 / 226193412 (99.9%)
Active / Total Slabs (% used) : 11556364 / 11556415 (100.0%)
Active / Total Caches (% used) : 110 / 194 (56.7%)
Active / Total Size (% used) : 43278793.73K / 43315465.42K (99.9%)
Minimum / Average / Maximum Object : 0.02K / 0.19K / 4096.00K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
221416340 221416039 3% 0.19K 11070817 20 44283268K dentry
1123443 1122739 99% 0.41K 124827 9 499308K fuse_request
1122320 1122180 99% 0.75K 224464 5 897856K fuse_inode
761539 754272 99% 0.20K 40081 19 160324K vm_area_struct
437858 223259 50% 0.10K 11834 37 47336K buffer_head
353353 347519 98% 0.05K 4589 77 18356K anon_vma_chain
325090 324190 99% 0.06K 5510 59 22040K size-64
146272 145422 99% 0.03K 1306 112 5224K size-32
137625 137614 99% 1.02K 45875 3 183500K nfs_inode_cache
128800 118407 91% 0.04K 1400 92 5600K anon_vma
59101 46853 79% 0.55K 8443 7 33772K radix_tree_node
52620 52009 98% 0.12K 1754 30 7016K size-128
19359 19253 99% 0.14K 717 27 2868K sysfs_dir_cache
10240 7746 75% 0.19K 512 20 2048K filp
VFS 캐시 압력 :
cat /proc/sys/vm/vfs_cache_pressure
125
교환 :
cat /proc/sys/vm/swappiness
0
사용하지 않는 메모리가 메모리 낭비라는 것을 알고 있으므로 이것이 반드시 나쁜 것은 아닙니다 (특히 44GB가 SReclaimable로 표시되는 경우). 그럼에도 불구하고 분명히 기계는 문제를 겪었고, Slab이 90GB를 초과 할 때 며칠 안에 같은 일이 다시 일어날 것을 두려워합니다.
질문
다음과 같은 질문이 있습니다.
- 슬래브 메모리가 항상 실제 RAM이고 그 숫자가 MemFree 값에서 이미 뺀다 고 생각하는 것이 맞습니까?
- 그런 많은 수의 치 열기 항목이 정상입니까? PHP 응용 프로그램은 약 1.5M 파일에 액세스 할 수 있지만 대부분은 아카이브이며 일반 웹 트래픽을 위해 전혀 액세스하지 않습니다.
- 캐시 된 inode의 수가 캐시 된 덴 트리의 수보다 훨씬 적다는 사실에 대한 설명은 무엇일까요?
- 시스템에 메모리 문제가 발생하면 커널이 일부 덴 트리를 자동으로 해제하지 않아야합니까? 이것이 일어나지 않는 이유는 무엇입니까?
- 이 모든 메모리가 무엇인지 (즉, 캐시되는 경로가 무엇인지) 덴 트리 캐시를 "찾아 보는"방법이 있습니까? 아마도 이것은 일종의 메모리 누수, symlink 루프 또는 실제로 PHP 응용 프로그램이 잘못하고있는 것을 가리 킵니다.
- 모든 애셋 파일뿐만 아니라 PHP 응용 프로그램 코드도 GlusterFS 네트워크 파일 시스템을 통해 마운트됩니다.
루트 사용자는 일반 사용자로만 조사 할 수 없으며 관리자는 도움을 거부한다는 점을 명심하십시오. 그는 echo 2 > /proc/sys/vm/drop_caches
Slab 메모리가 실제로 회수 가능한지 확인하기 위해 일반적인 테스트를 수행하지도 않습니다 .
무슨 일이 일어나고 있는지, 더 조사 할 수있는 방법에 대한 통찰력이 있으면 대단히 감사하겠습니다.
업데이트
몇 가지 추가 진단 정보 :
마운트 :
cat /proc/self/mounts
rootfs / rootfs rw 0 0
proc /proc proc rw,relatime 0 0
sysfs /sys sysfs rw,relatime 0 0
devtmpfs /dev devtmpfs rw,relatime,size=66063000k,nr_inodes=16515750,mode=755 0 0
devpts /dev/pts devpts rw,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /dev/shm tmpfs rw,relatime 0 0
/dev/mapper/sysvg-lv_root / ext4 rw,relatime,barrier=1,data=ordered 0 0
/proc/bus/usb /proc/bus/usb usbfs rw,relatime 0 0
/dev/sda1 /boot ext4 rw,relatime,barrier=1,data=ordered 0 0
tmpfs /phptmp tmpfs rw,noatime,size=1048576k,nr_inodes=15728640,mode=777 0 0
tmpfs /wsdltmp tmpfs rw,noatime,size=1048576k,nr_inodes=15728640,mode=777 0 0
none /proc/sys/fs/binfmt_misc binfmt_misc rw,relatime 0 0
cgroup /cgroup/cpuset cgroup rw,relatime,cpuset 0 0
cgroup /cgroup/cpu cgroup rw,relatime,cpu 0 0
cgroup /cgroup/cpuacct cgroup rw,relatime,cpuacct 0 0
cgroup /cgroup/memory cgroup rw,relatime,memory 0 0
cgroup /cgroup/devices cgroup rw,relatime,devices 0 0
cgroup /cgroup/freezer cgroup rw,relatime,freezer 0 0
cgroup /cgroup/net_cls cgroup rw,relatime,net_cls 0 0
cgroup /cgroup/blkio cgroup rw,relatime,blkio 0 0
/etc/glusterfs/glusterfs-www.vol /var/www fuse.glusterfs rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072 0 0
/etc/glusterfs/glusterfs-upload.vol /var/upload fuse.glusterfs rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072 0 0
sunrpc /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0
172.17.39.78:/www /data/www nfs rw,relatime,vers=3,rsize=65536,wsize=65536,namlen=255,hard,proto=tcp,port=38467,timeo=600,retrans=2,sec=sys,mountaddr=172.17.39.78,mountvers=3,mountport=38465,mountproto=tcp,local_lock=none,addr=172.17.39.78 0 0
마운트 정보 :
cat /proc/self/mountinfo
16 21 0:3 / /proc rw,relatime - proc proc rw
17 21 0:0 / /sys rw,relatime - sysfs sysfs rw
18 21 0:5 / /dev rw,relatime - devtmpfs devtmpfs rw,size=66063000k,nr_inodes=16515750,mode=755
19 18 0:11 / /dev/pts rw,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=000
20 18 0:16 / /dev/shm rw,relatime - tmpfs tmpfs rw
21 1 253:1 / / rw,relatime - ext4 /dev/mapper/sysvg-lv_root rw,barrier=1,data=ordered
22 16 0:15 / /proc/bus/usb rw,relatime - usbfs /proc/bus/usb rw
23 21 8:1 / /boot rw,relatime - ext4 /dev/sda1 rw,barrier=1,data=ordered
24 21 0:17 / /phptmp rw,noatime - tmpfs tmpfs rw,size=1048576k,nr_inodes=15728640,mode=777
25 21 0:18 / /wsdltmp rw,noatime - tmpfs tmpfs rw,size=1048576k,nr_inodes=15728640,mode=777
26 16 0:19 / /proc/sys/fs/binfmt_misc rw,relatime - binfmt_misc none rw
27 21 0:20 / /cgroup/cpuset rw,relatime - cgroup cgroup rw,cpuset
28 21 0:21 / /cgroup/cpu rw,relatime - cgroup cgroup rw,cpu
29 21 0:22 / /cgroup/cpuacct rw,relatime - cgroup cgroup rw,cpuacct
30 21 0:23 / /cgroup/memory rw,relatime - cgroup cgroup rw,memory
31 21 0:24 / /cgroup/devices rw,relatime - cgroup cgroup rw,devices
32 21 0:25 / /cgroup/freezer rw,relatime - cgroup cgroup rw,freezer
33 21 0:26 / /cgroup/net_cls rw,relatime - cgroup cgroup rw,net_cls
34 21 0:27 / /cgroup/blkio rw,relatime - cgroup cgroup rw,blkio
35 21 0:28 / /var/www rw,relatime - fuse.glusterfs /etc/glusterfs/glusterfs-www.vol rw,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072
36 21 0:29 / /var/upload rw,relatime - fuse.glusterfs /etc/glusterfs/glusterfs-upload.vol rw,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072
37 21 0:30 / /var/lib/nfs/rpc_pipefs rw,relatime - rpc_pipefs sunrpc rw
39 21 0:31 / /data/www rw,relatime - nfs 172.17.39.78:/www rw,vers=3,rsize=65536,wsize=65536,namlen=255,hard,proto=tcp,port=38467,timeo=600,retrans=2,sec=sys,mountaddr=172.17.39.78,mountvers=3,mountport=38465,mountproto=tcp,local_lock=none,addr=172.17.39.78
GlusterFS 설정 :
cat /etc/glusterfs/glusterfs-www.vol
volume remote1
type protocol/client
option transport-type tcp
option remote-host 172.17.39.71
option ping-timeout 10
option transport.socket.nodelay on # undocumented option for speed
# http://gluster.org/pipermail/gluster-users/2009-September/003158.html
option remote-subvolume /data/www
end-volume
volume remote2
type protocol/client
option transport-type tcp
option remote-host 172.17.39.72
option ping-timeout 10
option transport.socket.nodelay on # undocumented option for speed
# http://gluster.org/pipermail/gluster-users/2009-September/003158.html
option remote-subvolume /data/www
end-volume
volume remote3
type protocol/client
option transport-type tcp
option remote-host 172.17.39.73
option ping-timeout 10
option transport.socket.nodelay on # undocumented option for speed
# http://gluster.org/pipermail/gluster-users/2009-September/003158.html
option remote-subvolume /data/www
end-volume
volume remote4
type protocol/client
option transport-type tcp
option remote-host 172.17.39.74
option ping-timeout 10
option transport.socket.nodelay on # undocumented option for speed
# http://gluster.org/pipermail/gluster-users/2009-September/003158.html
option remote-subvolume /data/www
end-volume
volume replicate1
type cluster/replicate
option lookup-unhashed off # off will reduce cpu usage, and network
option local-volume-name 'hostname'
subvolumes remote1 remote2
end-volume
volume replicate2
type cluster/replicate
option lookup-unhashed off # off will reduce cpu usage, and network
option local-volume-name 'hostname'
subvolumes remote3 remote4
end-volume
volume distribute
type cluster/distribute
subvolumes replicate1 replicate2
end-volume
volume iocache
type performance/io-cache
option cache-size 8192MB # default is 32MB
subvolumes distribute
end-volume
volume writeback
type performance/write-behind
option cache-size 1024MB
option window-size 1MB
subvolumes iocache
end-volume
### Add io-threads for parallel requisitions
volume iothreads
type performance/io-threads
option thread-count 64 # default is 16
subvolumes writeback
end-volume
volume ra
type performance/read-ahead
option page-size 2MB
option page-count 16
option force-atime-update no
subvolumes iothreads
end-volume
cat /etc/nfsmount.conf
. 또한 직접 디렉토리에 많은 파일을 포함하는 디렉토리가 있습니까?
cat /proc/self/mounts
및 (아마도 길어질 수 있음) 의 출력을 제공하십시오cat /proc/self/mountinfo
.