Незвичайно велике використання кеш-пам'яті зубів


34

Проблема

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

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

Що я міг дізнатись сам:

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

Якщо ви відстежували систему з тих пір, і особливо це означає, що пам'ять Плити збільшується по прямій лінії зі швидкістю близько 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 --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

Я знаю, що невикористана пам'ять - це даремна пам'ять, тому це не обов'язково має бути поганим (особливо якщо врахувати, що 44 ГБ відображаються як SReclaimable). Однак, мабуть, у машини виникли проблеми, і я побоююся, що це повториться через кілька днів, коли плита перевищить 90 ГБ.

Запитання

У мене є такі питання:

  • Чи правильно я вважаю, що пам'ять Slab - це завжди фізична оперативна пам'ять, а число вже віднімається від значення MemFree?
  • Чи нормальна така велика кількість стоматологічних записів? Додаток PHP має доступ до близько 1,5 М файлів, однак більшість з них є архівами та не мають доступу до них для регулярного веб-трафіку.
  • Що може бути поясненням того факту, що кількість кешованих утворень значно менша, ніж кількість кешованих зубних рядів, чи не повинні вони якось пов’язані?
  • Якщо система стикається з проблемою пам'яті, чи не повинен ядро ​​автоматично звільняти частину зубів? Що може бути причиною того, що цього не відбувається?
  • Чи є якийсь спосіб "заглянути" в кеш-пам'ять зубів, щоб побачити, що це все за пам'ять (тобто, які шляхи кешуються)? Можливо, це вказує на якийсь витік пам’яті, цикл символьних посилань, або ж на щось, що програма PHP робить неправильно.
  • Код програми PHP, а також усі файли активів монтуються через мережеву файлову систему GlusterFS, чи може це щось із цим робити?

Зауважте, що я не можу досліджувати як root, лише як звичайний користувач, і що адміністратор відмовляється надавати допомогу. Він навіть не пройде типовий echo 2 > /proc/sys/vm/drop_cachesтест, щоб перевірити, чи справді пам’ять плити справжня.

Будемо дуже вдячні за будь-яку думку про те, що може бути далі, і як я можу далі досліджувати.

Оновлення

Деякі додаткові діагностичні відомості:

Кріплення:

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.
Метью Іфе

@MIfe Я оновив питання, обидва виходи додаються.
Вольфганг Стенгель

Моє відчуття тут, можливо, пов'язане з кешуванням зубів NFS. З інтересу можна бігти cat /etc/nfsmount.conf. Також у вас є каталоги, які містять багато файлів у його безпосередньому каталозі?
Матвій Іфе

1
Отже, оскільки vfs_cache_pressure> 100, ядро ​​повинно віддати перевагу кеш-пам'яті зубів. Це легко може бути помилкою, 2.6.32 є досить старим ядром, навіть з патчами Redport Hatport. BTW, що таке версія ядра?
poige

2
(Ваш сисадмін звучить жахливо . Це дає нам погане ім’я)
ewwhite

Відповіді:


14

Чи правильно я вважаю, що пам'ять Slab - це завжди фізична оперативна пам'ять, а число вже віднімається від значення MemFree?

Так.

Чи нормальна така велика кількість стоматологічних записів? Додаток PHP має доступ до близько 1,5 М файлів, однак більшість з них є архівами та не мають доступу до них для регулярного веб-трафіку.

Так, якщо система не знаходиться під тиском пам'яті. Він повинен використовувати для пам'яті щось, і можливо, що у вашому конкретному режимі використання це найкращий спосіб використовувати цю пам'ять.

Що може бути поясненням того факту, що кількість кешованих утворень значно менша, ніж кількість кешованих зубних рядів, чи не повинні вони якось пов’язані?

Найбільш вірогідним поясненням буде багато операцій з каталогами.

Якщо система стикається з проблемою пам'яті, чи не повинен ядро ​​автоматично звільняти частину зубів? Що може бути причиною того, що цього не відбувається?

Це повинно бути, і я не можу придумати жодної причини, яка б не була. Я не переконаний, що саме це насправді пішло не так. Я настійно пропоную оновити ваше ядро ​​або збільшити 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 для безпечного з'єднання. Незахищені запити не викликають проблему.

  • Проблема не потребує одночасних запитів на вигин. Накопичення зубного ряду відбуватиметься до тих пір, поки виклики завитків будуть досить частими, щоб перевершити зусилля ОС щодо повернення оперативної пам’яті.

  • новіша версія 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 безпосередньо. В іншому випадку підвищення тиску кешу та прийняття відповідного хіта CPU може бути найкращою ставкою для надійної роботи.
Дж. Полдінг

3
Це зафіксовано в Centos 6.6 з nss-softokn-3.14.3-17
Strahinja Kustudic

1
Просто для того, щоб зрозуміти, хто шукає швидкого виправлення: вам потрібно як оновити nss-softokenRPM, так і встановити NSS_SDB_USE_CACHE=YESenv var, щоб згортання 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

Є цифри, що показують, що ви можете очікувати, що дещо помітне повернення пам’яті для зубних протезів, коли vfs_cache_pressure встановлено набагато вище 100. Отже, 125 може бути занадто низьким, щоб це відбулося у вашому випадку.


З усього, що я прочитав, підвищення vfs_cache_pressureвище 100має сенс лише у тому випадку, якщо у вас недостатньо оперативної пам’яті для навантаження. У такому випадку, значення значення вище 100 (наприклад, 10000) звільнить деяку оперативну пам'ять. Це, однак, призведе до гіршого IO в цілому, хоча.
Мікко Ранталайнен

3

Насправді не пояснення вашої відповіді, але як користувач цієї системи цю інформацію ви надали:

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

Досить сказати мені, що це не ваша проблема, і системний адміністратор повинен відповідати цим поясненням.

Я не хочу звучати грубо тут, але;

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

Ваша відповідальність за систематизацію - виправдати або вирішити аномалію розподілу плит. Або ви не дали нам повної картини всієї саги, яка веде вас до цього (що, чесно кажучи, мене не цікавить), або ваш сисадмін поводиться безвідповідально та / або некомпетентно в тому, як він вважає вирішення цієї проблеми.

Сміливо скажіть йому, що випадковий незнайомець в Інтернеті вважає, що він не сприймає своїх обов'язків серйозно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.