Utilizzo insolitamente elevato della cache dentaria


34

Problema

Una macchina CentOS con kernel 2.6.32 e 128 GB di RAM fisica ha avuto problemi pochi giorni fa. L'amministratore di sistema responsabile mi dice che l'applicazione PHP-FPM non rispondeva più alle richieste in modo tempestivo a causa dello scambio, e visto freeche non era rimasta quasi memoria, ha scelto di riavviare la macchina.

So che la memoria libera può essere un concetto confuso su Linux e un riavvio forse è stata la cosa sbagliata da fare. Tuttavia, l'amministratore menzionato accusa l'applicazione PHP (di cui sono responsabile) e rifiuta di indagare ulteriormente.

Quello che ho potuto scoprire da solo è questo:

  • Prima del riavvio, la memoria libera (inclusi buffer e cache) era solo di un paio di centinaia di MB.
  • Prima del riavvio, è stato /proc/meminfosegnalato un utilizzo della memoria Slab di circa 90 GB (sì, GB).
  • Dopo il riavvio, la memoria libera era di 119 GB, scendendo a circa 100 GB in un'ora, mentre i lavoratori di PHP-FPM (circa 600 di loro) stavano tornando in vita, ognuno dei quali mostrava tra 30 e 40 MB nel Colonna RES in alto (che è stato così per mesi ed è perfettamente ragionevole data la natura dell'applicazione PHP). Non c'è nient'altro nell'elenco dei processi che consuma una quantità insolita o degna di nota di RAM.
  • Dopo il riavvio, la memoria della lastra era di circa 300 MB

Da allora ho monitorato il sistema, e in particolare la memoria Slab sta aumentando in linea retta con una velocità di circa 5 GB al giorno. Memoria libera come riportato da freee /proc/meminfodiminuisce alla stessa velocità. La lastra è attualmente a 46 GB. Secondo la slabtopmaggior parte di esso viene utilizzato per le dentryvoci:

Memoria libera:

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:

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  

Pressione cache VFS:

cat /proc/sys/vm/vfs_cache_pressure
125

swappiness:

cat /proc/sys/vm/swappiness
0

So che la memoria inutilizzata è sprecata di memoria, quindi questa non dovrebbe essere necessariamente una cosa negativa (specialmente dato che 44 GB sono indicati come SReclaimable). Tuttavia, a quanto pare la macchina ha comunque riscontrato problemi e temo che lo stesso accadrà di nuovo in pochi giorni quando Slab supera i 90 GB.

Domande

Ho queste domande:

  • Sono corretto nel pensare che la memoria Slab sia sempre RAM fisica e che il numero sia già sottratto dal valore MemFree?
  • È normale un numero così elevato di voci dentistiche? L'applicazione PHP ha accesso a circa 1,5 M file, tuttavia la maggior parte di essi sono archivi e non sono affatto accessibili per il normale traffico web.
  • Quale potrebbe essere una spiegazione del fatto che il numero di inode memorizzati nella cache è molto inferiore al numero di dentisti memorizzati nella cache, se non dovessero essere correlati in qualche modo?
  • Se il sistema ha problemi di memoria, il kernel non dovrebbe liberare automaticamente alcuni dei dentisti? Quale potrebbe essere una ragione per cui ciò non accade?
  • Esiste un modo per "esaminare" la cache dentaria per vedere cos'è tutta questa memoria (ovvero quali sono i percorsi che vengono memorizzati nella cache)? Forse questo indica un qualche tipo di perdita di memoria, loop di collegamento simbolico o, in effetti, qualcosa che l'applicazione PHP sta facendo male.
  • Il codice dell'applicazione PHP e tutti i file delle risorse sono montati tramite il file system di rete GlusterFS, potrebbe avere qualcosa a che fare con esso?

Tieni presente che non posso indagare come root, solo come utente normale e che l'amministratore rifiuta di aiutare. Non eseguirà nemmeno il echo 2 > /proc/sys/vm/drop_cachestest tipico per vedere se la memoria Slab è effettivamente recuperabile.

Qualsiasi approfondimento su cosa potrebbe succedere e su come posso indagare ulteriormente sarebbe molto apprezzato.

aggiornamenti

Alcune ulteriori informazioni diagnostiche:

Monti:

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

Informazioni sul montaggio:

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

Configurazione di 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

Fornisci l'output di cat /proc/self/mountse (forse abbastanza a lungo) cat /proc/self/mountinfo.
Matthew Ife,

@MIfe Ho aggiornato la domanda, entrambi gli output sono stati aggiunti.
Wolfgang Stengel,

La mia sensazione qui è probabilmente legata alla memorizzazione nella cache dentaria NFS. Per interesse puoi correre cat /etc/nfsmount.conf. Inoltre hai delle directory che contengono molti file nella sua directory immediata?
Matthew Ife,

1
Bene, poiché vfs_cache_pressure> 100, il kernel dovrebbe preferire recuperare la memoria cache di dentrie. Questo può facilmente essere un bug, 2.6.32 è un kernel piuttosto vecchio, anche con le patch di backport di RedHat. A proposito, qual è la versione esatta del kernel?
poige

2
(Il tuo amministratore di sistema sembra terribile . Ci dà un brutto nome)
ewwhite

Risposte:


14

Sono corretto nel pensare che la memoria Slab sia sempre RAM fisica e che il numero sia già sottratto dal valore MemFree?

Sì.

È normale un numero così elevato di voci dentistiche? L'applicazione PHP ha accesso a circa 1,5 M file, tuttavia la maggior parte di essi sono archivi e non sono affatto accessibili per il normale traffico web.

Sì, se il sistema non è sotto pressione della memoria. Deve usare la memoria per qualcosa ed è possibile che nel tuo particolare modello di utilizzo, questo sia il modo migliore per usare quella memoria.

Quale potrebbe essere una spiegazione del fatto che il numero di inode memorizzati nella cache è molto inferiore al numero di dentisti memorizzati nella cache, se non dovessero essere correlati in qualche modo?

Molte operazioni di directory sarebbero la spiegazione più probabile.

Se il sistema ha problemi di memoria, il kernel non dovrebbe liberare automaticamente alcuni dei dentisti? Quale potrebbe essere una ragione per cui ciò non accade?

Dovrebbe, e non riesco a pensare a nessun motivo. Non sono convinto che questo sia ciò che è effettivamente andato storto. Consiglio vivamente di aggiornare il kernel o aumentare ulteriormente vfs_cache_pressure.

Esiste un modo per "esaminare" la cache dentaria per vedere cos'è tutta questa memoria (ovvero quali sono i percorsi che vengono memorizzati nella cache)? Forse questo indica un qualche tipo di perdita di memoria, loop di collegamento simbolico o, in effetti, qualcosa che l'applicazione PHP sta facendo male.

Non credo ci sia. Cercherei tutte le directory con un numero assurdamente elevato di voci o strutture di directory molto profonde che vengono cercate o attraversate.

Il codice dell'applicazione PHP e tutti i file delle risorse sono montati tramite il file system di rete GlusterFS, potrebbe avere qualcosa a che fare con esso?

Sicuramente potrebbe essere un problema con il filesystem. Un bug del filesystem che impedisce di rilasciare dentries, ad esempio, è una possibilità.


Grazie per aver risposto alle mie domande individualmente. La pressione della cache è stata infine aumentata ulteriormente e l'incremento della cache dentaria è stato interrotto.
Wolfgang Stengel,

Non sono ancora riuscito a rintracciare il programma responsabile. Se ne scopro di più, riporterò indietro per chiunque abbia questo problema.
Wolfgang Stengel,

1
Grazie! La grande directory (file da 0,25 mil) era la causa del problema nel mio caso, ogni volta che qualcosa interagiva con esso 2 GB di RAM scomparivano nella cache.
Alcuni Linux Nerd

20

Soluzione confermata

A chiunque possa imbattersi nello stesso problema. I ragazzi del data center lo hanno finalmente capito oggi. Il colpevole era una biblioteca NSS (Network Security Services) in bundle con Libcurl. Un aggiornamento alla versione più recente ha risolto il problema.

Una segnalazione di bug che descrive i dettagli è qui:

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

Apparentemente, al fine di determinare se un percorso è locale o su un'unità di rete, NSS stava cercando un file inesistente e misurava il tempo impiegato dal file system per riportare indietro! Se hai un numero sufficiente di richieste Curl e memoria sufficiente, queste richieste sono tutte memorizzate nella cache e impilate.


15

Ho riscontrato questo problema esatto e, sebbene Wolfgang abbia ragione sulla causa, mancano alcuni dettagli importanti.

  • Questo problema influisce sulle richieste SSL eseguite con curl o libcurl o qualsiasi altro software che utilizza mozilla NSS per una connessione sicura. Le richieste non sicure non innescano il problema.

  • Il problema non richiede richieste di arricciatura simultanee. L'accumulo di odontoiatria avverrà fino a quando le chiamate di arricciatura sono abbastanza frequenti da superare gli sforzi del sistema operativo per recuperare la RAM.

  • la versione più recente di NSS, 3.16.0, include una correzione per questo. tuttavia, non si ottiene la correzione gratuitamente aggiornando NSS e non è necessario aggiornare tutto NSS. devi solo aggiornare nss-softokn (che ha una dipendenza obbligatoria da nss-utils) come minimo. e per ottenere il vantaggio, è necessario impostare la variabile di ambiente NSS_SDB_USE_CACHE per il processo che utilizza libcurl. la presenza di quella variabile d'ambiente è ciò che consente di saltare i costosi controlli di file inesistenti.

FWIW, ho scritto un post sul blog con un po 'più di background / dettagli, nel caso qualcuno ne avesse bisogno.


Grazie per un bel post sul blog, ma vorrei menzionare che nss-softokn non è ancora stato aggiornato alla versione 3.16 su CentOS / RHEL. Probabilmente verrà risolto nella versione 6.6.
Strahinja Kustudic,

1
Grazie per la nota. Forse Amazon è uscito prima di questo (forse anche su nostra richiesta?) Per i loro repository gestiti. Nelle versioni precedenti (3.14-3.15), si ottiene ancora metà del vantaggio impostando le variabili di ambiente appropriate. Se hai il know-how, potresti essere in grado di creare direttamente v3.16. Altrimenti, aumentare la pressione della cache e subire il successo della CPU associata potrebbe essere la soluzione migliore per prestazioni affidabili.
J. Paulding,

3
Questo è stato risolto in Centos 6.6 con nss-softokn-3.14.3-17
Strahinja Kustudic,

1
Giusto per essere chiari per chi cerca una soluzione rapida: è necessario sia l'aggiornamento del nss-softokennumero di giri e impostare NSS_SDB_USE_CACHE=YESl'env var avere ricciolo https chiama fermata inondando la cache dentry.
Steve Kehlet,

4

Vedi 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

Ci sono numeri che mostrano che ci si può aspettare un notevole recupero della memoria dentaria quando vfs_cache_pressure è impostato su un valore superiore a 100. Quindi 125 può essere troppo basso perché ciò accada nel tuo caso.


Da quanto ho letto, aumentare vfs_cache_pressuresopra 100ha senso solo se non si dispone di RAM sufficiente per il carico di lavoro. In tal caso, avere un valore molto superiore a 100 (ad es. 10000) libererà un po 'di RAM. Ciò comporterà però un peggioramento dell'IO nel complesso.
Mikko Rantalainen,

3

Non proprio una spiegazione alla tua risposta, ma come utente di questo sistema queste informazioni che hai fornito:

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

È sufficiente per dirmi che questo non è un tuo problema ed è responsabilità dell'amministratore di sistema fornire una spiegazione adeguata.

Non voglio sembrare maleducato qui ma;

  • Mancano informazioni specifiche sul ruolo di questo host.
  • Il modo in cui si presume che l'host dia priorità alle risorse non rientra nell'ambito di applicazione.
  • Non hai familiarità o hai partecipato alla progettazione e alla distribuzione dell'archiviazione su questo host.
  • Non puoi offrire un determinato output di sistema perché non sei root.

È responsabilità dei vostri amministratori di sistema giustificare o risolvere l'anomalia di allocazione delle lastre. O non ci hai fornito un quadro completo dell'intera saga che ti ha portato a questo (che sinceramente non mi interessa) o il tuo amministratore di sistema si sta comportando in modo irresponsabile e / o incompetente nel modo in cui considera gestire questo problema.

Sentiti libero di dirgli che uno sconosciuto a caso su Internet pensa di non prendere sul serio le sue responsabilità.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.