Налаштування swap Linux: чому сервіс падає під час піку пам'яті
Аварійний перезапуск сервісу трапляється в розпал пікового навантаження на сервер, хоча моніторинг цієї ж миті показує вільну пам'ять.
Це не помилка графіків: нестача оперативної пам'яті проявляється не в загальному обсязі, а в доступності сторінок у потрібній зоні та в здатності ядра виділити безперервну ділянку. У логах Linux це виглядає так: oom killer завершив процес, а супервізор підняв його знову.
Жертву ядро обирає за oom_score з поправкою oom_score_adj, і найчастіше нею стає основний робочий процес, а не той, хто накопичив витік: у довгоживучого сервісу вище споживання — вищий і шанс потрапити під завершення.
Перезапуск повертає з'єднання, але втрачає недописані транзакції, а за кілька хвилин картина повторюється, якщо причину не усунули.
Налаштування swap Linux у цій схемі — не «додати повільної пам'яті», а видати ядру буфер часу: вивантажити холодні сторінки замість негайного завершення процесу на першому ж піку.
vm.swappiness визначає, наскільки охоче витісняються анонімні сторінки, а ліміти cgroup і режим vm.overcommit_memory — кому й скільки взагалі дозволено зайняти.
Розбираємо, як це закривається: за якими метриками наближення до відмови видно раніше за сам OOM, як рахуються ліміти за групами процесів і що робити, якщо робочий набір сервісу вже не вміщається в пам'ять.
Ефект керованої підкачки: відгук і стабільність
Ефект керованої підкачки видно не за графіком вільної пам'яті, а за кількістю інцидентів.
Після того як swap і політику реакції на нестачу пам'яті налаштовано під профіль навантаження, сервіс на піках переходить у передбачувану деградацію: частина операцій сповільнюється, але процеси не гинуть і не тягнуть за собою сусідні. Нижче — перевірки, за якими ми приймаємо роботу.
- Аварійні перезапуски. Кількість падінь процесів через нестачу пам'яті падає на порядок: замість десятків подій залишаються поодинокі, і кожна розбирається як аномалія, а не як фон.
- Передбачувана деградація. Під піком зростає час відповіді, але черги не рвуться: холодні сторінки йдуть у підкачку, гарячий робочий набір залишається в пам'яті, відмова сервісу не настає.
- Рівний відгук на сплесках. Поріг вільних сторінок і агресивність витіснення виставлені під навантаження, тому короткі bursts проходять без провалів — сервіс сповільнюється плавно, а не обривається.
- Ізоляція наслідків. Ліміти пам'яті для груп процесів і ранній вбивця за тиском на пам'ять розбираються лише з проблемним сервісом; сусіди на тій самій машині не втрачають доступність.
- Знятий клас інцидентів. Нічні підняття та сторінки чергового через падіння за пам'яттю зникають із потоку — залишаються завдання на планове розширення, а не на гасіння.
- Швидке повернення. Після піку сервіс входить у робочий режим за десятки секунд, без повторного прогріву кешу та ручного втручання.
Кожен пункт перевіряємо на стенді з відтворюваним профілем навантаження: знімаємо метрики до й після, порівнюємо частоту перезапусків і поведінку на межі. Так ефект підкачки стає вимірюваним, а не декларативним.
Способи організації підкачки: порівняння та обмеження
Вибір носія підкачки визначає не лише доступний обсяг, а й час відгуку в момент вичерпання пам'яті.
Ядро опитує активні області підкачки в порядку спадання пріоритету, тому swap-файл на швидкому локальному накопичувачі та місткий розділ на повільному масиві спокійно співіснують: гарячі сторінки йдуть на швидкий, холодні — на об'ємний. Помилка починається там, де під підкачку віддають носій, не розрахований на постійний запис.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Swap-файл на локальному накопичувачі | Швидко розгорнути, змінити розмір, додати другу область | Потребує вільного місця у файловій системі, під час зміни розміру фрагментується |
| Окремий розділ підкачки | Передбачувана затримка, сервери без гібернації, СУБД | Розмір фіксується під час розмітки, змінюється лише перерозбиттям |
| Стиснена підкачка в оперативній пам'яті | Малопам'ятні віртуальні машини, вузли без локального диска | Витрачає такти процесора, не рятує за справжнього дефіциту пам'яті, не переживає перезавантаження |
| Том на менеджері логічних томів | Потрібно змінювати розмір на ходу без зупинки служб | Додатковий шар абстракції, снапшоти непомітно з'їдають місце |
| Область на віддаленому блоковому пристрої | Кластери без локальних дисків, аварійний резерв | Мережева затримка робить її марною під навантаженням |
Пріоритет областей підкачки задається явно — у записі файлової системи або ключем під час підключення, — інакше порядок заповнення виявиться випадковим.
Підбір swappiness ведуть за профілем навантаження: для сервісів із великим файловим кешем значення знижують, для віртуальних машин і тонких клієнтів підвищують.
Рішення ухвалюють не за смаком, а за лічильниками промахів сторінкових відмов і даними про тиск на пам'ять — тоді підкачка закриває піки, а не маскує нестачу пам'яті.
Порядок робіт: від аудиту пам'яті до передачі регламентів
Починаємо не з правки конфігурації, а з фактів: без профілю споживання будь-яке налаштування параметрів пам'яті перетворюється на вгадування.
Такий порядок виключає типовий сценарій, коли підкачку вмикають «на всякий випадок» і отримують просідання відгуку або раптовий перезапуск сервісу в годину пік.
- Аудит споживання пам'яті. Знімаємо метрики за процесами та групами: пікове й середнє споживання, частка анонімних сторінок, поведінка в години навантаження. Окремо дивимося, хто утримує пам'ять після сплеску.
- Схема розміщення підкачки. Визначаємо, потрібен файл підкачки чи окремий розділ, на якому носії та якого розміру. Фіксуємо, які дані допустимо витісняти, а які мають залишатися в оперативній пам'яті.
- Налаштування порогів і аварійного завершення. Задаємо інтенсивність витіснення, ліміти для груп процесів і пріоритети, за якими ядро обирає жертву за нестачі пам'яті. Явні пріоритети надійніші за автоматичний вибір.
- Перевірка під навантаженням. Проганяємо сценарії зі штучним дефіцитом пам'яті й дивимося результат: чи зростає затримка відгуку, чи спрацьовує аварійне завершення і які процеси гинуть першими.
- Спостережуваність. Ставимо оповіщення на наближення до лімітів, на зростання витіснення та на факт аварійного завершення — інцидент стає видно до того, як упаде сервіс.
- Передача регламентів. Віддаємо схему розміщення підкачки, значення параметрів з обґрунтуванням, процедуру відкату та чек-лист дій за різкого зростання споживання.
Комплект документів і конфігурацій після впровадження
Після впровадження в команди залишаються не лише робочі налаштування, а й документи, за якими їх можна змінювати та передавати без нас. Нижче — перелік артефактів, які замовник отримує разом із результатом.
Кожен розрахований на чергового інженера, який відкриє його в момент інциденту, а не «колись прочитаємо».
- Конфігурація підкачки — файл або розділ із записом у fstab, значення vm.swappiness, overcommit і cache_pressure, поруч коментар: чому вибрано таку поведінку і що зміниться за повернення до значень за замовчуванням.
- Політики за сервісами — ліміти пам'яті в cgroup і пріоритети oom_score_adj: хто отримує шанс вижити під тиском, кого ядро звільняє першим.
- Схема розміщення — на якому вузлі та носії лежить область підкачки, як вона співвідноситься з томами даних і де вузькі місця за дисковими операціями.
- Регламент чергової зміни — покрокові дії за зростання споживання пам'яті та спрацювання OOM Killer: що дивитися, що перезапускати, коли викликати старшого інженера.
- Документація з пам'яті — профіль споживання за сервісами, межі норми, типові причини зростання та журнал змін налаштувань.
- Перевірки та план відкату — метрики, оповіщення й команди діагностики в готовому вигляді плюс порядок повернення попереднього профілю, якщо зміни погіршили поведінку сервісу.
Окремо фіксуємо власників: хто у вашій команді переглядає ліміти під час зростання навантаження і за якими ознаками запускається перегляд.
Кейс: усунення аварійних перезапусків під час піків
Сервіс під навантаженням поводився рівно, але в пікові години впирався в пам'ять. Ядро, не знайшовши вільних сторінок, аварійно завершувало найважчі процеси — разом із ними йшов увесь вузол.
Підсумок: сім інцидентів на місяць, кожен із ручним розбором; відновлення займало до 45 хвилин, і частина запитів у це вікно губилася.
Що змінили
Розділили два різних сценарії — короткий сплеск і стійку нестачу пам'яті. Під сплески відвели область підкачки на окремому томі: вона дає ядру запас, щоб дочекатися звільнення пам'яті, а не завершувати процеси.
Для контейнерів задали жорсткі ліміти та порядок завершення — першим іде фоновий обробник, фронтальний сервіс залишається в строю.
За споживанням стежили через Prometheus: алерт на стійке зростання налаштований так, щоб спрацьовувати раніше за аварійний механізм. Це дало розбір причини до збою, а не після.
Зміни закріплювали трьома місяцями спостережень. Зведення до й після:
| Показник | До | Після |
|---|---|---|
| Аварійні перезапуски сервісу | 7 на місяць | 1 за квартал |
| Час відновлення сервісу | до 45 хвилин вручну | до 3 хвилин автоматично |
| Піки, поглинуті підкачкою | не вимірювалися | 9 з 10 |
| Нічні виклики чергового | 4–6 на місяць | 0 |
Підкачка при цьому не маскує витік: якщо споживання зростає лінійно, приходить алерт, і причину розбирають до того, як закінчиться запас.
Чим swap-файл відрізняється від окремого розділу?
З погляду ядра різниці майже немає: і файл, і розділ після ініціалізації стають блоковим пристроєм, який підключається однією командою. Різниця проявляється в тому, як цей обсяг створюється, змінюється й переживає перерозбиття диска.
Виділений розділ — заздалегідь відрізаний шматок розмітки. Ядро звертається до нього напряму, без прошарку файлової системи, тому накладні витрати на введення-виведення нижчі, а поведінка під навантаженням передбачуваніша.
Плата за це — жорсткість: розмір фіксується в момент розмітки, і щоб його змінити, доводиться зачіпати таблицю розділів і часто перезавантажуватися.
Такий варіант беруть там, де підкачка пов'язана з гібернацією: ядру потрібна безперервна ділянка диска, описана в параметрах завантаження.
Файл підкачки живе у наявній файловій системі. Його створюють і підключають на ходу, розмір змінюють без зупинки сервісів, а кілька файлів із різними пріоритетами дозволяють розкласти навантаження за різними дисками.
Обмеження успадковуються від файлової системи: на частині мережевих і копіювальних сховищ такий файл не працює, а за гібернації потребує ручного розрахунку зміщення.
На розмітку це впливає напряму: розділ з'їдає місце заздалегідь і змушує планувати схему під час встановлення, файл залишає розмітку плоскою й дає підганяти обсяг підкачки під реальне навантаження.
Звідси й вибір: фізичні сервери з гібернацією — розділ; віртуальні машини, хости контейнерів і хмара — файл, бо змінювати розмітку там дорожче, ніж прибрати або додати файл.
Часті запитання щодо поведінки системи за нестачі пам'яті
Перед стартом робіт виникають ті самі сумніви: чи не почне сервіс падати частіше, чи не просяде відгук, що зміниться в контейнерах і чи можна обійтися без перезавантаження вузла.
Частину запитань знімають на діагностиці — за лічильниками вбивств процесів, статистикою vmstat і лімітами cgroup видно, що відбувається зараз і чим це загрожує під навантаженням.
Як зрозуміти, що сервіс упав саме через пам'ять?
Запис у журналі ядра називає процес-жертву та причину — вичерпання пам'яті вузла або ліміту групи. Якщо рядка про вбивство немає, а процес усе одно завершився, причину шукаємо в застосунку: витік, власний обмежувач, помилка в обробці піку. Різниця принципова: в одному випадку налаштовуємо ядро, в іншому правимо код.
Чи потрібна підкачка, якщо оперативної пам'яті достатньо?
Підкачка не прискорює роботу, але тримає запас на піку: рідко використовувані сторінки йдуть на диск замість запуску вбивства процесу. Вимикати її варто лише там, де важлива передбачувана затримка, — і тоді ліміти задаються жорсткіше, з явним резервом під пікове навантаження.
Чи не стане сервіс працювати повільніше?
Поки активні сторінки залишаються в пам'яті, відгук не змінюється. Просідання починається за активного витіснення: його видно за полями введення-виведення у vmstat і за зростанням часу відповіді. Тому значення swappiness підбирають під профіль навантаження, а не залишають успадкованим.
Як це працює в контейнерах і чи застосовується без перезавантаження?
Усередині контейнера діють ліміти групи, а не пам'ять вузла: жертву обирає ядро хоста, але за пріоритетами всередині групи, тому параметри узгоджують на двох рівнях.
Більшість значень змінюється на льоту, решта фіксується в конфігурації — перезавантажувати вузол не потрібно, достатньо перезапустити контейнер.
Обговоримо задачу та повернемося з планом впровадження
Старт завжди однаковий: спочатку розбір ситуації, потім оцінка та план впровадження, і лише потім зміни на живих серверах.
Ми не торкаємося параметрів пам'яті «за відчуттями» — спочатку потрібно побачити, як swap і механізм аварійного завершення процесів поводяться під вашим реальним навантаженням.
Для цього достатньо опису задачі та доступу до спостережень за системою, а не повного доступу до продакшену на першому кроці.
- Розбір ситуації. Фіксуємо, які сервіси живуть на хості, які в них піки споживання пам'яті та що вже відбувалося: чи були перезапуски, «завмирання» під навантаженням, раптові падіння процесів.
- Збір вихідних даних. Дивимося поточні параметри підкачки, ліміти пам'яті для контейнерів і служб, історію спрацювань аварійного завершення процесів. Це відповідає на питання, де саме втрачається пам'ять.
- Оцінка робіт. Визначаємо обсяг змін, порядок кроків, вікна для правок і точки відкату. Ви отримуєте оцінку та план до того, як щось зміниться на серверах.
- План впровадження. Узгоджуємо, які пороги та пріоритети виставляємо, які процеси захищаємо від завершення, як налаштовуємо аварійне звільнення пам'яті, щоб воно вдаряло по потрібній цілі.
- Впровадження та перевірка. Змінюємо конфігурацію, проганяємо навантажувальний профіль і переконуємося, що під піком система не йде в перезапуск. Результат — передбачувана поведінка замість раптових падінь.
- Передача. Віддаємо конфігурації, схему ухвалених рішень і метрики, за якими зміни видно на графіках.
Щоб почати, опишіть задачу: що за сервіси, які симптоми турбують і що вже пробували. Повернемося з оцінкою та планом впровадження — без зобов'язань запускати роботи одразу.







