Problema
Una máquina CentOS con kernel 2.6.32 y 128 GB de RAM física tuvo problemas hace unos días. El administrador del sistema responsable me dice que la aplicación PHP-FPM ya no respondía a las solicitudes de manera oportuna debido al intercambio, y al haber visto free
que casi no quedaba memoria, decidió reiniciar la máquina.
Sé que la memoria libre puede ser un concepto confuso en Linux y un reinicio tal vez fue algo incorrecto. Sin embargo, el administrador mencionado culpa a la aplicación PHP (de la que soy responsable) y se niega a investigar más a fondo.
Lo que podría descubrir por mi cuenta es esto:
- Antes del reinicio, la memoria libre (incluidos los búferes y la memoria caché) era de solo unos cientos de MB.
- Antes del reinicio,
/proc/meminfo
informó un uso de memoria Slab de alrededor de 90 GB (sí, GB). - Después del reinicio, la memoria libre era de 119 GB, bajando a alrededor de 100 GB en una hora, a medida que los trabajadores de PHP-FPM (aproximadamente 600 de ellos) volvían a la vida, cada uno de ellos mostrando entre 30 y 40 MB en el Columna RES en la parte superior (que ha sido así durante meses y es perfectamente razonable dada la naturaleza de la aplicación PHP). No hay nada más en la lista de procesos que consuma una cantidad inusual o notable de RAM.
- Después del reinicio, la memoria de losa era de aproximadamente 300 MB
Si ha estado monitoreando el sistema desde entonces, y más notablemente, la memoria Slab está aumentando en línea recta con una tasa de aproximadamente 5 GB por día. Memoria libre según lo informado por free
y /proc/meminfo
disminuye a la misma velocidad. Losa está actualmente en 46 GB. Según la slabtop
mayor parte se utiliza para dentry
entradas:
Memoria libre:
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
Losa:
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
Presión de caché VFS:
cat /proc/sys/vm/vfs_cache_pressure
125
Swappiness:
cat /proc/sys/vm/swappiness
0
Sé que la memoria no utilizada es memoria desperdiciada, por lo que esto no debería ser necesariamente algo malo (especialmente dado que 44 GB se muestran como SReclaimable). Sin embargo, aparentemente la máquina experimentó problemas, y me temo que lo mismo volverá a ocurrir en unos días cuando Slab supere los 90 GB.
Preguntas
Tengo estas preguntas:
- ¿Estoy en lo cierto al pensar que la memoria Slab es siempre RAM física y que el número ya se resta del valor MemFree?
- ¿Es normal un número tan alto de entradas de dentry? La aplicación PHP tiene acceso a alrededor de 1.5 M de archivos, sin embargo, la mayoría de ellos son archivos y no se accede a ellos para el tráfico web regular.
- ¿Cuál podría ser una explicación del hecho de que el número de inodos almacenados en caché es mucho menor que el número de dentries almacenados en caché, no deberían estar relacionados de alguna manera?
- Si el sistema tiene problemas de memoria, ¿el núcleo no debería liberar algunas de las dentries automáticamente? ¿Cuál podría ser una razón por la que esto no sucede?
- ¿Hay alguna forma de "mirar" el caché de dentry para ver qué es toda esta memoria (es decir, cuáles son las rutas que se almacenan en caché)? Quizás esto apunta a algún tipo de pérdida de memoria, bucle de enlace simbólico o, de hecho, a algo que la aplicación PHP está haciendo mal.
- El código de la aplicación PHP, así como todos los archivos de activos, se montan a través del sistema de archivos de red GlusterFS, ¿podría eso tener algo que ver con eso?
Tenga en cuenta que no puedo investigar como root, solo como un usuario normal, y que el administrador se niega a ayudar. Ni siquiera ejecutará la echo 2 > /proc/sys/vm/drop_caches
prueba típica para ver si la memoria Slab es realmente recuperable.
Cualquier idea sobre lo que podría estar sucediendo y cómo puedo investigar más sería muy apreciada.
Actualizaciones
Alguna información de diagnóstico adicional:
Monturas:
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
Información de montaje:
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
Configuración de 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 /proc/self/mounts
y (tal vez bastante largo)cat /proc/self/mountinfo
.cat /etc/nfsmount.conf
. ¿También tiene algún directorio que contenga muchos archivos en su directorio inmediato?Respuestas:
Sí.
Sí, si el sistema no está bajo presión de memoria. Tiene que usar la memoria para algo, y es posible que en su patrón particular de uso, esta sea la mejor manera de usar esa memoria.
Muchas operaciones de directorio serían la explicación más probable.
Debería, y no puedo pensar en ninguna razón por la que no lo haría. No estoy convencido de que esto sea lo que realmente salió mal. Sugeriría encarecidamente actualizar su kernel o aumentar vfs_cache_pressure aún más.
No creo que haya. Buscaría cualquier directorio con un número absurdamente grande de entradas o estructuras de directorios muy profundas que se buscan o recorren.
Definitivamente podría ser un problema del sistema de archivos. Es posible que se produzca un error en el sistema de archivos que hace que no se publiquen dentries.
fuente
Solución confirmada
Para cualquiera que pueda encontrarse con el mismo problema. Los chicos del centro de datos finalmente lo descubrieron hoy. El culpable era una biblioteca NSS (Network Security Services) incluida con Libcurl. Una actualización a la versión más nueva resolvió el problema.
Un informe de error que describe los detalles está aquí:
https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=1044666
Aparentemente, para determinar si alguna ruta es local o en una unidad de red, NSS estaba buscando un archivo inexistente y midiendo el tiempo que le tomó al sistema de archivos informar. Si tiene un número suficientemente grande de solicitudes Curl y suficiente memoria, todas estas solicitudes se almacenan en caché y se apilan.
fuente
Me encontré con este problema exacto, y aunque Wolfgang tiene razón sobre la causa, faltan algunos detalles importantes.
Este problema afecta a las solicitudes SSL realizadas con curl o libcurl, o cualquier otro software que utilice Mozilla NSS para una conexión segura. Las solicitudes no seguras no desencadenan el problema.
El problema no requiere solicitudes de curl concurrentes. La acumulación de negación ocurrirá mientras las llamadas curl sean lo suficientemente frecuentes como para superar los esfuerzos del sistema operativo para recuperar RAM.
la versión más nueva de NSS, 3.16.0, incluye una solución para esto. sin embargo, no obtiene la solución de forma gratuita al actualizar NSS, y no tiene que actualizar todo NSS. solo tiene que actualizar nss-softokn (que tiene una dependencia requerida en nss-utils) como mínimo. y para obtener el beneficio, debe establecer la variable de entorno NSS_SDB_USE_CACHE para el proceso que usa libcurl. La presencia de esa variable de entorno es lo que permite omitir las costosas comprobaciones de archivos inexistentes.
FWIW, escribí una entrada de blog con un poco más de antecedentes / detalles, en caso de que alguien lo necesite.
fuente
nss-softoken
RPM y configurar laNSS_SDB_USE_CACHE=YES
variable de entorno para que las llamadas curvilíneas https dejen de inundar su caché de dentry.Ver 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
Hay números que muestran que puede esperar una recuperación de memoria de dentry notable cuando vfs_cache_pressure se establece en una forma superior a 100. Entonces 125 puede ser demasiado bajo para que suceda en su caso.
fuente
vfs_cache_pressure
encima100
solo tiene sentido si no tienes suficiente RAM para tu carga de trabajo. En ese caso, tener un valor muy superior a 100 (por ejemplo, 10000) liberará algo de RAM. Sin embargo, eso dará como resultado un peor IO en general.No es realmente una explicación a su respuesta, pero como usuario de este sistema, esta información que proporcionó:
Es suficiente para decirme que este no es su problema y es responsabilidad del administrador del sistema proporcionar una explicación adecuada.
No quiero sonar grosero aquí pero;
Es su responsabilidad de los administradores de sistemas justificar o resolver la anomalía de asignación de losas. O no nos ha dado una imagen completa de toda la saga que lo llevó a esto (que francamente no me interesa) o su administrador de sistemas se está comportando de manera irresponsable o incompetente en la forma en que considera manejar este problema.
Siéntase libre de decirle que algún extraño al azar en Internet cree que no se está tomando en serio sus responsabilidades.
fuente