Як діагностувати високе споживання пам’яті в Linux
Shared FAQ page chrome (breadcrumb, dates, read time, «Читати далі», enquiry block, category labels): see INDEX-AND-CHROME.md. Translate once.
Body
Як знайти, що споживає пам’ять на сервері Linux, і які параметри overcommit ядра цим керують.
Виявлення ситуації «Out of Memory».
Коли ви дивитеся, тиск на пам’ять може вже минути, тому спочатку перевірте журнал ядра на наявність OOM-завершень: ядро Linux керує пам’яттю сервера, завершуючи завдання чи процеси за певними критеріями, і звільняє пам’ять, яку займав завершений процес.
Для кожного процесу, завершеного ядром, створюється запис у журналі; журнали зазвичай містяться в /var/log/.
Наведеною нижче командою grep можна пошукати помилку out of memory в усіх файлах журналів у /var/log/.
grep -i -r 'out of memory' /var/log/
Mar 1 01:24:05 srv kernel: [3966348.114233] Out of memory: Kill process 48305 (php-cgi) score 21 or sacrifice child
Mar 1 01:24:08 srv kernel: [3966350.061954] Out of memory: Kill process 48318 (php-cgi) score 21 or sacrifice child
Поточне використання:
root@srv:~# free -m
total used free shared buff/cache available
Mem: 1981 720 319 138 940 916
Swap: 524 84 440
Історію використання пам’яті за день можна отримати командою «sar».
root@server [~]# sar -r
Linux (server.example.com) 03/05/2019 _x86_64_ (2 CPU)
12:00:01 AM kbmemfree kbmemused %memused kbbuffers kbcached kbcommit %commit
12:10:01 AM 1672764 1407160 45.69 100356 749140 1618364 44.90
12:20:01 AM 1289208 1790716 58.14 106580 1130096 1599588 44.38
12:30:01 AM 1248100 1831824 59.48 109184 1144680 1621332 44.98
12:40:01 AM 1267972 1811952 58.83 111460 1155828 1604104 44.51
12:50:01 AM 1254556 1825368 59.27 113888 1159632 1599480 44.38
01:00:01 AM 1092296 1987628 64.53 116020 1164540 1802228 50.00
01:10:01 AM 1212168 1867756 60.64 118204 1169516 1633940 45.33
...
Average: kbmemfree kbmemused %memused kbbuffers kbcached kbcommit %commit
Average: 1465222 1614702 52.43 179213 834889 1655342 45.93
Оновлення RAM є необхідним, якщо сервер показує стабільно високе використання пам’яті або середнє використання за день перевищує 90%, оскільки таке високе використання часом може вичерпати доступну вільну пам’ять на завантаженому сервері. На віртуальній машині тривалий тиск на пам’ять вирішується більшою кількістю RAM або виправленням застосунку, ніколи не swap.
Ще один зручний інструмент для виявлення процесів, що споживають пам’ять, це команда «top», яка дає змогу сортувати запущені процеси за використанням ресурсів.
root@server [~]# top -c
top - 18:41:45 up 109 days, 18:03, 5 users, load average: 1.30, 1.24, 1.24
Tasks: 544 total, 2 running, 541 sleeping, 0 stopped, 1 zombie
Cpu(s): 8.3%us, 1.4%sy, 0.2%ni, 89.8%id, 0.3%wa, 0.0%hi, 0.1%si, 0.0%st
Mem: 12296096k total, 11531800k used, 764296k free, 586732k buffers
Swap: 16777212k total, 209160k used, 16568052k free, 2471072k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2376001 root 20 0 230m 101m 4588 R 31.4 0.8 1:22.06 spamd child
2448741 root 30 10 19472 1056 792 S 2.6 0.0 0:00.08 /usr/sbin/lveps -c 1 -p -d -n -o id:10,ep:10,pno:10,pid:15,tno:5,tid:15,cpu:7,mem:15,com:256
953572 mysql 20 0 17.5g 5.3g 5336 S 1.7 44.9 102:38.10 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=server
844549 root 30 10 424m 59m 4532 S 1.3 0.5 52:13.20 /opt/alt/python27/bin/python2.7 /usr/share/lve-stats/lvestats-server.py start --pidfile /var/run/lvestats.pid
1351883 root 20 0 1127m 638m 1768 S 1.3 5.3 37:37.24 /usr/local/cpanel/3rdparty/bin/clamd
844526 root 30 10 462m 35m 1204 S 1.0 0.3 30:54.20 /opt/alt/python27/bin/python2.7 /usr/share/lve-stats/lvestats-server.py start --pidfile /var/run/lvestats.pid
3109 nscd 20 0 2725m 3956 2260 S 0.7 0.0 188:08.43 /usr/sbin/nscd
2243573 nobody 20 0 189m 78m 1140 S 0.7 0.7 4:22.20 litespeed (lshttpd - #01)
2448384 mailnull 20 0 78756 7736 3348 S 0.7 0.1 0:00.06 /usr/sbin/exim -bd -q1h -oP /var/spool/exim/exim-daemon.pid
Щоб відсортувати процеси за використанням пам’яті, скористайтеся такою послідовністю клавіш.
Введіть команду top. Натисніть SHIFT+o, щоб відкрити опції команди top. Натисніть N і Enter.
Виявлення витоків пам’яті
Можна знайти час сервера, коли було зафіксовано «out of memory»; тут це “Mar 1 01:24:05”. Пошукайте цю позначку часу командою grep у файлах журналів ваших серверів застосунків, таких як Apache, MySQL тощо.
На сервері cPanel командою grep можна пошукати в журналах доступу сайтів будь-який підозрілий або зловмисний доступ до сайту, який спричинив вичерпання ресурсів.
grep -ir “01/Mar/2019:01:2” /usr/local/apache/domlogs/
Деякі підозрілі дії, які видно в журналах доступу:
- Велика кількість звернень з конкретних IP-адрес.
- Велика кількість звернень до відсутніх ресурсів або файлів.
- Велика кількість запитів HTTP POST.
- Велика кількість невдалих спроб доступу, наприклад входу.
Командою mysqladmin proc stat можна виявити запити MySQL, які зависли надовго і через це споживають багато пам’яті.
root@server [~]# mysqladmin proc stat
+--------+------+-----------+----+---------+------+-------+------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+--------+------+-----------+----+---------+------+-------+------------------+----------+
| 137324 | root | localhost | | Query | 0 | init | show processlist | 0.000 |
+--------+------+-----------+----+---------+------+-------+------------------+----------+
Uptime: 370827 Threads: 1 Questions: 20484133 Slow queries: 0 Opens: 1456 Flush tables: 1 Open tables: 747 Queries per second avg: 55.239
Перевірте стовпці Time, db, State, знайдіть запити з великим значенням «Time» і розгляньте їх разом із розробником вашого сайту.
Увімкніть «журнал повільних запитів» у MySQL і виправте довгі запити разом із розробником вашого сайту.
Memory Overcommit
Зазвичай сервер Linux дозволяє зарезервувати для процесу більше пам’яті, ніж йому фактично потрібно, виходячи з припущення, що жоден процес не використає всю дозволену йому пам’ять, яку можна віддати іншим процесам. Поведінку системи Linux щодо overcommit пам’яті можна налаштувати, і робиться це утилітою sysctl.
Усі параметри sysctl можна вивести командою sysctl -a; параметр, який нас цікавить, це vm.overcommit_memory.
[root@srv ~]# sysctl -a | grep vm.overcommit_memory
vm.overcommit_memory = 0
vm.overcommit_memory може мати 3 значення: 0, 1 і 2.
- 0 Дозволяти overcommit за оцінкою «якщо RAM достатньо»
- 1 Завжди дозволяти overcommit
- 2 Відмовляти в overcommit, якщо в системі немає пам’яті.
Ще один параметр sysctl, який варто врахувати, це overcommit_ratio: він визначає, який відсоток фізичної пам’яті на додаток до простору swap можна враховувати, дозволяючи процесам overcommit.
Розгляньмо випадок, коли vm.overcommit_memory встановлено в 2: ядро не дозволить overcommit понад простір swap плюс vm.overcommit_ratio від загального обсягу RAM vm.overcommit_memory=2 vm.overcommit_ratio=50% RAM=8GB SWAP=4GB
За наведеної конфігурації overcommit можливий у межах 4GB SWAP + 50% від 8GB RAM
sysctl -w vm.overcommit_memory=2
sysctl -w vm.overcommit_ratio=100
sysctl -w не зберігається після перезавантаження; додайте ті самі два рядки до /etc/sysctl.conf.
З FAQ EuroVPS.
Більше в категорії «Інструкції»Ваш наступний партнер з інфраструктури
Залишилося
запитання?
Розкажіть, що ви намагаєтеся зробити. Інженер прочитає і відповість.
+357 222 32280
Почнімо з вашої інфраструктури.
Трохи контексту допомагає нам почати правильну розмову.
