Необычно высокое использование кеша

34

проблема

Машина CentOS с ядром 2.6.32 и 128 ГБ физической оперативной памяти столкнулась с проблемами несколько дней назад. Ответственный системный администратор говорит мне, что приложение PHP-FPM больше не отвечает на запросы своевременно из-за подкачки, и, увидев, freeчто памяти почти не осталось, он решил перезагрузить компьютер.

Я знаю, что свободная память может быть запутанным понятием в Linux, и перезагрузка, возможно, была неправильной вещью. Тем не менее, упомянутый администратор обвиняет приложение PHP (за которое я отвечаю) и отказывается проводить дальнейшие расследования.

Что я мог бы узнать самостоятельно это:

  • До перезапуска свободная память (включая буферы и кэш) составляла всего пару сотен МБ.
  • До перезагрузки /proc/meminfoсообщалось об использовании памяти Slab около 90 ГБ (да, ГБ).
  • После перезапуска объем свободной памяти составил 119 ГБ, а в течение часа он сократился до 100 ГБ, поскольку работники PHP-FPM (около 600 из них) возвращались к жизни, каждый из которых показывал от 30 до 40 МБ в Столбец RES в верхней части (что было таким образом в течение нескольких месяцев и вполне разумно, учитывая характер приложения PHP). В списке процессов нет ничего, что потребляет необычный или примечательный объем оперативной памяти.
  • После перезагрузки памяти Slab было около 300 МБ

Если с тех пор осуществлялся мониторинг системы, и, что особенно важно, объем памяти Slab увеличивается по прямой линии со скоростью около 5 ГБ в день. Свободная память как сообщается freeи /proc/meminfoуменьшается с той же скоростью. Плита в настоящее время на 46 ГБ. По 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:

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

Swappiness:

cat /proc/sys/vm/swappiness
0

Я знаю, что неиспользуемая память - это потраченная впустую память, поэтому это не обязательно должно быть плохо (особенно если учесть, что 44 ГБ показаны как SReclaimable). Тем не менее, очевидно, что у машины возникли проблемы, и я боюсь, что то же самое случится через несколько дней, когда Slab превосходит 90 ГБ.

Вопросов

У меня есть эти вопросы:

  • Правильно ли я считаю, что память Slab - это всегда физическая память, а число уже вычтено из значения MemFree?
  • Нормально ли такое большое количество записей в стоматологии? Приложение PHP имеет доступ к примерно 1,5 М файлам, однако большинство из них являются архивами и вообще не используются для обычного веб-трафика.
  • Что может быть объяснением того факта, что число кэшированных inode намного меньше, чем число кэшированных dentries, если они не связаны каким-либо образом?
  • Если в системе возникают проблемы с памятью, не должно ли ядро ​​автоматически освободить некоторые из зубных рядов? Что может быть причиной того, что этого не происходит?
  • Есть ли способ «заглянуть» в кэш Дентри, чтобы увидеть, что это за память (то есть, какие пути кешируются)? Возможно, это указывает на какую-то утечку памяти, цикл символьных ссылок или даже на то, что приложение PHP делает неправильно.
  • Код приложения PHP, а также все файлы ресурсов монтируются через сетевую файловую систему GlusterFS. Может ли это быть как-то связано с этим?

Пожалуйста, имейте в виду, что я не могу исследовать как root, только как обычный пользователь, и что администратор отказывается помочь. Он даже не будет запускать типичный 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 /proc/self/mountsи (может быть, довольно долго) cat /proc/self/mountinfo.
Мэтью Ифе
@ МИФ Я обновил вопрос, оба вывода прилагаются.
Вольфганг Стенгель
Мое чувство здесь, вероятно, связано с кэшированием NFS dentry. Из интереса можешь бежать cat /etc/nfsmount.conf. Также у вас есть какие-либо каталоги, которые содержат много файлов в своем непосредственном каталоге?
Мэтью Ифе
1
Ну, так как vfs_cache_pressure> 100, ядро ​​должно предпочесть вернуть кэш-память dentrie. Это легко может быть ошибкой, 2.6.32 - довольно старое ядро, даже с патчами для бэкпорта RedHat. Кстати, какова точная версия ядра?
Пой
2
(Ваш сисадмин звучит ужасно . Это дает нам дурную
славу

Ответы:

14

Правильно ли я считаю, что память Slab - это всегда физическая память, а число уже вычтено из значения MemFree?

Да.

Нормально ли такое большое количество записей в стоматологии? Приложение PHP имеет доступ к примерно 1,5 М файлам, однако большинство из них являются архивами и вообще не используются для обычного веб-трафика.

Да, если система не находится под давлением памяти. Он должен использовать память для чего-то, и вполне возможно, что в вашем конкретном образце использования это лучший способ использовать эту память.

Что может быть объяснением того факта, что число кэшированных inode намного меньше, чем число кэшированных dentries, если они не связаны каким-либо образом?

Множество операций с каталогами было бы наиболее вероятным объяснением.

Если в системе возникают проблемы с памятью, не должно ли ядро ​​автоматически освободить некоторые из зубных рядов? Что может быть причиной того, что этого не происходит?

Так и должно быть, и я не могу придумать ни одной причины, по которой это не так. Я не уверен, что это то, что на самом деле пошло не так. Я настоятельно рекомендую обновить ваше ядро ​​или увеличить vfs_cache_pressure.

Есть ли способ «заглянуть» в кэш Дентри, чтобы увидеть, что это за память (то есть, какие пути кешируются)? Возможно, это указывает на какую-то утечку памяти, цикл символьных ссылок или даже на то, что приложение PHP делает неправильно.

Я не верю, что есть. Я бы искал любые каталоги с абсурдно большим количеством записей или очень глубокими структурами каталогов, которые ищутся или просматриваются.

Код приложения PHP, а также все файлы ресурсов монтируются через сетевую файловую систему GlusterFS. Может ли это быть как-то связано с этим?

Определенно это может быть проблема файловой системы. Например, возможна ошибка файловой системы, приводящая к тому, что зубные зубы не будут освобождены.

Дэвид Шварц
источник
Спасибо, что ответили на мои вопросы индивидуально. Наконец, давление в кеше еще больше увеличилось, и увеличение кеша в дентри остановилось.
Вольфганг Стенгель
Я не мог отследить ответственную программу еще. Если я узнаю больше, я сообщу обо всех, кто столкнулся с этой проблемой.
Вольфганг Стенгель
1
Благодарность! Большой каталог (0,25 млн. Файлов) был полностью причиной проблемы в моем случае, каждый раз, когда что-то с ним взаимодействовало, 2 ГБ ОЗУ исчезали в кеше.
Немного Linux Nerd
20

Подтвержденное решение

Для тех, кто может столкнуться с той же проблемой. Ребята из дата-центра наконец-то поняли это сегодня. Виновником была библиотека NSS (Network Security Services) в комплекте с Libcurl. Обновление до последней версии решило проблему.

Отчет об ошибке, который описывает детали здесь:

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

Очевидно, чтобы определить, является ли какой-либо путь локальным или находится на сетевом диске, NSS искала несуществующий файл и измерила время, которое требуется файловой системе, чтобы сообщить! Если у вас достаточно большое количество запросов Curl и достаточно памяти, все эти запросы кэшируются и складываются.

Вольфганг Стенгель
источник
15

Я столкнулся с этой конкретной проблемой, и хотя Вольфганг прав в отношении причины, некоторые важные детали упущены.

  • Эта проблема влияет на запросы SSL, выполняемые с помощью curl, libcurl или любого другого программного обеспечения, которое использует Mozilla NSS для безопасного соединения. Незащищенные запросы не вызывают проблему.

  • Проблема не требует одновременных запросов curl. Накопление дентри будет происходить до тех пор, пока вызовы curl достаточно часты, чтобы опередить усилия ОС по восстановлению ОЗУ.

  • более новая версия NSS, 3.16.0, содержит исправление для этого. однако, вы не получаете исправления бесплатно, обновляя NSS, и вам не нужно обновлять все NSS. вам нужно только обновить nss-softokn (который имеет обязательную зависимость от nss-utils) как минимум. и чтобы получить выгоду, вам нужно установить переменную среды NSS_SDB_USE_CACHE для процесса, который использует libcurl. наличие этой переменной среды позволяет пропускать дорогостоящие несуществующие проверки файлов.

FWIW, я написал запись в блоге с немного большим количеством фона / деталей, на случай, если кому-то это понадобится.

Дж. Полдинг
источник
Спасибо за хороший пост в блоге, но я хотел бы отметить, что nss-softokn до сих пор не обновлен до версии 3.16 в CentOS / RHEL. Вероятно, это будет исправлено в версии 6.6.
Страхиня Кустудич
1
Спасибо за примечание. Возможно, Amazon вышел впереди этого (возможно, даже по нашей просьбе?) Для своих управляемых репо. В более старых версиях (3.14-3.15) вы по-прежнему получаете половину выгоды, устанавливая соответствующие переменные среды. Если у вас есть ноу-хау, вы можете собрать v3.16 напрямую. В противном случае, повышение давления в кэш-памяти и принятие соответствующего удара ЦП может быть лучшим выбором для надежной производительности.
Дж. Полдинг
3
Это исправлено в Centos 6.6 с помощью nss-softokn-3.14.3-17
Страхиня Кустудич,
1
Просто чтобы быть понятным людям, которые ищут быстрое решение: вам нужно как обновить nss-softokenRPM, так и установить NSS_SDB_USE_CACHE=YESenv var, чтобы вызовы curl https перестали заполнять ваш кэш.
Стив Кехлет
4

См. 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

Есть цифры, показывающие, что вы можете ожидать некоторого заметного восстановления памяти dentry, когда vfs_cache_pressure установлен более чем на 100. Таким образом, 125 может быть слишком низким, чтобы это произошло в вашем случае.

poige
источник
Из всего, что я прочитал, повышение vfs_cache_pressureвыше 100имеет смысл, только если вам не хватает оперативной памяти для вашей рабочей нагрузки. В этом случае значение выше 100 (например, 10000) освободит некоторое количество оперативной памяти. Это приведет к худшему IO в целом, хотя.
Микко Ранталайнен
3

Не совсем объяснение вашего ответа, но как пользователь этой системы вы предоставили эту информацию:

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

Достаточно сказать мне, что это не ваша проблема, а системный администратор обязан дать адекватное объяснение.

Я не хочу показаться грубым здесь, но;

  • Вам не хватает конкретной информации о роли этого хоста.
  • То, как хост должен расставлять приоритеты для ресурсов, находится вне вашей компетенции.
  • Вы не знакомы или не участвовали в разработке и развертывании хранилища на этом хосте.
  • Вы не можете предложить определенный вывод системы, поскольку вы не являетесь пользователем root.

Ваша системная обязанность состоит в том, чтобы оправдать или устранить аномалию размещения плит. Либо вы не дали нам полную картину всей саги, которая привела вас к этому (что, честно говоря, мне не интересно), либо ваш сисадмин ведет себя безответственно и / или некомпетентно в том, как он рассматривает решение этой проблемы.

Не стесняйтесь сказать ему, что какой-то случайный незнакомец в Интернете думает, что он не воспринимает свои обязанности всерьез.

Мэтью Ифе
источник