태그 보관물: centos

centos

비정상적으로 높은 dentry 캐시 사용량 0

문제

커널 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_cachesSlab 메모리가 실제로 회수 가능한지 확인하기 위해 일반적인 테스트를 수행하지도 않습니다 .

무슨 일이 일어나고 있는지, 더 조사 할 수있는 방법에 대한 통찰력이 있으면 대단히 감사하겠습니다.

업데이트

몇 가지 추가 진단 정보 :

마운트 :

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



답변

슬래브 메모리가 항상 실제 RAM이고 그 숫자가 MemFree 값에서 이미 뺀다 고 생각하는 것이 맞습니까?

예.

그런 많은 수의 치 열기 항목이 정상입니까? PHP 응용 프로그램은 약 1.5M 파일에 액세스 할 수 있지만 대부분은 아카이브이며 일반 웹 트래픽을 위해 전혀 액세스하지 않습니다.

예, 시스템에 메모리가 부족하지 않은 경우 그것은 무언가를 위해 메모리를 사용해야하며, 특정 사용 패턴에서 이것이 해당 메모리를 사용하는 가장 좋은 방법 일 수 있습니다.

캐시 된 inode의 수가 캐시 된 덴 트리의 수보다 훨씬 적다는 사실에 대한 설명은 무엇일까요?

많은 디렉토리 조작이 가장 가능성있는 설명입니다.

시스템에 메모리 문제가 발생하면 커널이 일부 덴 트리를 자동으로 해제하지 않아야합니까? 이것이 일어나지 않는 이유는 무엇입니까?

그것은해야하며, 그렇게하지 않을 이유를 생각할 수 없습니다. 이것이 실제로 잘못되었다는 것을 확신하지 못합니다. 커널을 업그레이드하거나 vfs_cache_pressure를 더 높이는 것이 좋습니다.

이 모든 메모리가 무엇인지 (즉, 캐시되는 경로가 무엇인지) 덴 트리 캐시를 “찾아 보는”방법이 있습니까? 아마도 이것은 일종의 메모리 누수, symlink 루프 또는 실제로 PHP 응용 프로그램이 잘못하고있는 것을 가리 킵니다.

나는 믿지 않는다. 터무니없이 많은 항목이 있거나 디렉토리가 검색되거나 탐색되는 디렉토리 구조가 깊은 디렉토리를 찾습니다.

모든 애셋 파일뿐만 아니라 PHP 응용 프로그램 코드도 GlusterFS 네트워크 파일 시스템을 통해 마운트됩니다.

확실히 파일 시스템 문제 일 수 있습니다. 예를 들어, 덴트 리가 해제되지 않는 파일 시스템 버그가있을 수 있습니다.


답변

확인 된 솔루션

같은 문제가 발생할 수 있습니다. 데이터 센터 직원들은 오늘 마침내 그것을 알아 냈습니다. 범인은 Libcurl과 함께 번들로 제공되는 NSS (Network Security Services) 라이브러리였습니다. 최신 버전으로 업그레이드하면 문제가 해결되었습니다.

세부 사항을 설명하는 버그 보고서는 다음과 같습니다.

https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=1044666

분명히 어떤 경로가 로컬 또는 네트워크 드라이브에 있는지 확인하기 위해 NSS는 존재하지 않는 파일을 찾고 파일 시스템이 다시보고하는 데 걸리는 시간을 측정했습니다! Curl 요청이 많고 메모리가 충분하면 이러한 요청이 모두 캐시되어 쌓입니다.


답변

나는이 정확한 문제에 부딪 쳤고 볼프강은 원인에 대해 정확하지만 중요한 세부 사항이 누락되었습니다.

  • 이 문제는 curl 또는 libcurl로 수행 된 SSL 요청 또는 보안 연결을 위해 mozilla NSS를 사용하는 다른 소프트웨어에 영향을줍니다. 비보안 요청은 문제를 유발하지 않습니다.

  • 이 문제에는 동시 컬 요청이 필요하지 않습니다. 컬 호출이 RAM을 회수하려는 OS의 노력을 능가 할만큼 자주 발생하는 한, 치열 축적이 발생합니다.

  • NSS의 최신 버전 인 3.16.0에는 이에 대한 수정 사항이 포함되어 있습니다. 그러나 NSS를 업그레이드해도 무료로 수정 사항을 얻을 수 없으며 모든 NSS를 업그레이드 할 필요는 없습니다. 최소한 nss-utilokn (nss-utils에 대한 필수 종속성) 만 업그레이드하면됩니다. 그리고 이점을 얻으려면 libcurl을 사용중인 프로세스에 환경 변수 NSS_SDB_USE_CACHE를 설정해야합니다. 해당 환경 변수가 존재하면 값 비싼 존재하지 않는 파일 검사를 건너 뛸 수 있습니다.

FWIW, 나는 누군가가 그것을 필요로 할 경우를 대비하여 조금 더 배경 / 세부 사항이 있는 블로그 항목 을 작성 했습니다.


답변

https://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.7/2.6.7-mm1/broken-out/vfs-shrinkage-tuning.patch를 참조 하십시오.

vfs_cache_pressure가 100보다 높은 방법으로 설정되면 눈에 띄는 dentry 메모리 회수가 예상된다는 것을 보여주는 숫자가 있습니다. 따라서 125가 너무 낮아서 귀하의 경우에는 발생할 수 없습니다.


답변

답변에 대한 설명은 아니지만이 시스템의 사용자로서이 정보를 제공했습니다.

cat /proc/meminfo
MemTotal:       132145324 kB
...
SReclaimable:   44561644 kB
SUnreclaim:      1678736 kB

이것이 귀하의 문제아니며 적절한 설명을 제공하는 sysadmin의 책임 이 아님 을 알려주기에 충분합니다 .

나는 무례하게 들리고 싶지 않지만;

  • 이 호스트의 역할에 대한 특정 정보가 부족합니다.
  • 호스트가 리소스 우선 순위를 정하는 방법은 범위를 벗어납니다.
  • 이 호스트에서 스토리지의 설계 및 배포에 익숙하지 않거나 관련이 없습니다.
  • 루트가 아니기 때문에 특정 시스템 출력을 제공 할 수 없습니다.

슬래브 할당 이상을 정당화하거나 해결하는 것은 시스템 관리자의 책임 입니다. 당신이 우리에게이 사실을 알리는 전체 사가에 대한 완전한 그림을 제공하지 않았거나 (솔직히 내가 관심이없는) 시스템 관리자 가이 문제를 처리하는 방식에 무책임하고 무능하게 행동하고 있습니다.

인터넷상에서 임의의 낯선 사람이 자신의 책임을 진지하게 받아들이지 않는다고 생각한다고 자유롭게 말하십시오.


답변