Вимкнути вбивцю Linux OOM за замовчуванням?


37

Вбивця OOM в Linux так часто загрожує різними програмами, і, як видається, для розробки ядра насправді робиться не так багато. Чи не було б краще, як найкраща практика під час налаштування нового сервера , щоб змінити значення за замовчуванням на перезаключенні пам'яті, тобто вимкнути його ( vm.overcommit_memory=2), якщо ви не знаєте, що ви хочете, щоб він увімкнувся для вашого конкретного використання? І які б це випадки використання, коли ви знаєте, що хочете перевитрати комітету?

Як бонус, оскільки поведінка у випадку vm.overcommit_memory=2залежить від місця vm.overcommit_ratioта міняти місцями, що було б найкращим правилом щодо розміру двох останніх, щоб ціла установка працювала розумно?

Відповіді:


63

Цікава аналогія (від http://lwn.net/Articles/104179/ ):

Авіакомпанія виявила, що літати на її літаках дешевше палива на борту. Літаки були б легшими і витрачали менше палива, а гроші були заощаджені. Однак рідко кількість палива була недостатньою, і літак зазнав аварії. Цю проблему інженери компанії вирішили розробкою спеціального механізму OOF (без палива). У надзвичайних випадках пасажира вибирали та викидали з літака. (У разі необхідності процедуру повторювали.) Була розроблена велика частина теорії, і багато публікацій було присвячено проблемі правильного вибору жертви для викидання. Чи слід обрати жертву навмання? Або варто вибрати найважчу людину? Або найдавніший? Якщо пасажири платять, щоб не викинути, щоб жертва була найбіднішою на борту? І якщо, наприклад, обрали найважчу людину, чи повинен бути спеціальний виняток у випадку, коли це був пілот? Чи слід звільняти пасажирів першого класу? Тепер, коли існував механізм OOF, він буде активізуватися раз у раз та викидати пасажирів навіть тоді, коли б не бракувало пального. Інженери досі точно вивчають, як викликана ця несправність.


11
Мені це дуже сподобалося, дякую, що розкопали його.
Нік Болтон

32

Вбивця OOM спричиняє шкоду лише в тому випадку, якщо ви перевантажили систему. Дайте йому достатню кількість підказок і не запускайте програми, які раптом вирішать їсти величезну кількість оперативної пам’яті, і у вас не виникне проблем.

Щоб спеціально відповісти на ваші запитання:

  • Я не думаю, що це загальна ідея вимкнути надмірну комісію в загальному випадку; написано дуже мало додатків для належного вирішення проблеми brk(2) (та обгортки, які її використовують, наприклад malloc(3)), що повертають помилку. Коли я експериментував з цим на своїй попередній роботі, вважалося, що це більше клопоту, щоб отримати все, що здатне впоратися з помилками в пам'яті, ніж просто боротися з наслідками OOM (що, в нашому випадку, було набагато гірше, ніж перезапускати випадкові послуги, якщо трапляється OOM - нам довелося перезавантажувати цілий кластер, оскільки GFS - це парна фекалія).
  • Ви хочете перезавантажити будь-який процес, який переповнює пам'ять. Два найпоширеніших винуватців тут - Apache і JVM, але багато додатків роблять це в більшій чи меншій мірі. Вони думають, що їм може знадобитися багато пам’яті в якийсь момент майбутнього, тому вони схоплюють великий шматок відразу. У системі, що підтримує перезавантаження, ядро ​​надходить "я, що завгодно, пригнічіть мене, коли ви насправді хочете писати на ці сторінки", і нічого поганого не відбувається. У системі перезаключення ядро ​​говорить, що «ні, у вас не може бути стільки пам’яті, якщо вам трапиться написати це все в якийсь момент, в майбутньому я виснажений, тому для вас немає пам’яті!» і розподіл не вдається. Оскільки нічоготам йде "о, гаразд, чи можу я мати цей менший об'єм сегмента даних про процес?", тоді процес (а) закривається з помилкою в пам'яті, або (b) не перевіряє код повернення з malloc, вважає, що це нормально, і записує в недійсне місце пам'яті, викликаючи segfault. На щастя, JVM робить все це попередньою програмою при запуску (тож ваш JVM або починається, або вмирає негайно, що ви зазвичай помічаєте), але Apache робить це прикольні речі з кожною новою дитиною, що може мати захоплюючі ефекти у виробництві (невідтворювана "не обробка зв’язків "типи збудження).
  • Я не хотів би встановлювати моє надмірне співвідношення вище, ніж за замовчуванням 50%. Знову ж таки, з мого тестування, хоча встановлення його приблизно 80 чи 90 могло б здатися чудовою ідеєю, ядро ​​вимагає великих шматочків пам’яті в незручні часи, і повністю завантажена система з високим коефіцієнтом перевитрати, ймовірно, не матиме достатньої запасної пам’яті коли ядро ​​це потребує (призводить до страху, моровиці та оопсів). Таким чином, граючи з overcommit, вводить новий, ще веселіший режим відмов - замість того, щоб просто перезапустити будь-який процес, отриманий OOMed, коли у вас не вистачає пам’яті, тепер ваша машина виходить з ладу, що призводить до виходу з ладу всього пристрою. ДУЖЕ!
  • Простір обміну в системі без домішок залежить від обсягу запитуваної, але невикористаної пам'яті, необхідної вашим програмам, а також здорового запасу безпеки. Опрацювання того, що потрібно в конкретному випадку, залишається вправою для читача.

В основному, мій досвід полягає в тому, що відключення надмірної комісії - це приємний експеримент, який рідко спрацьовує так добре на практиці, як це звучить теоретично. Це чудово відповідає моєму досвіду роботи з іншими перетвореннями в ядрі - розробники ядра Linux майже завжди розумніші за вас, і типові налаштування працюють найкраще у переважній, переважній більшості випадків. Залиште їх у спокої, а замість цього перейдіть, знайдіть, який процес має витік, і виправте це.


2
Я не хочу, щоб мій процес резервного копіювання був убитий, оскільки хтось займається моїм веб-сервером. Винятки є нормальними, але за замовчуванням повинні бути безпека та послідовність. Оптимізації, такі як OOM, слід увімкнути IMHO вручну. Це як кодування, ви чітко кодуєте, а потім оптимізуєте. Перевиконання зобов’язань є приємною особливістю, але не повинно бути типовим.
Акі

1
Якщо ви не хочете, щоб ваш процес резервного копіювання загинув через те, що хтось здійснює ваш веб-сервер, не налаштовуйте веб-сервер таким чином, що DoS може спричинити перевантаження ресурсів у системі.
живіт

У мене є 8 Гб оперативної пам’яті, а лише запущений Firefox і віртуальна машина іноді призводять до того, що вбивця OOM вбиває VM. Компілюючи Unreal Engine 4, кожен виклик клаксону займає 1 ~ 1,5 Гб пам'яті, і знову-таки вбивця OOM раз у раз вбиває. Зараз я взагалі добре з цим, без вбивці OOM, вони, мабуть, все-таки будуть сегментуватися. Просто щоразу, коли вбивця OOM хоче вбити процес, моя система замерзає на 10 хвилин, перш ніж поганий процес насправді буде вбитий. Баг, можливо? Швидше за все. Я хочу цього? Точно ні. І це ваша причина, чому ви можете відключити вбивцю OOM.
Шахбаз

1
Якщо ви робите все це на коробці, вам потрібно більше оперативної пам’яті, а вимкнення перезарядки лише погіршить.
Бен Лутгенс

6

Гм, я не повністю переконаний в аргументах на користь переборщика та вбивці ОМВ ... Коли жінка пише,

"Убивця OOM спричиняє шкоду лише в тому випадку, якщо ви перевантажили свою систему. Дайте їй достатню кількість підкачок і не запускайте додатки, які раптом вирішать їсти велику кількість оперативної пам'яті, і у вас не виникне проблем".

Він розповідає про сценарій оточення, коли забороняється перевиконання та вбивця OOM не застосовуються, або не реально діють (якщо всі програми виділяли пам’ять за потребою, і було достатньо виділити віртуальну пам'ять, запис пам'яті пильно слідкує за розподілом пам'яті без помилок, тому ми не могли реально говорити про переналагоджену систему, навіть якщо була включена стратегія перевиконання). Йдеться про неявне визнання, що надмірний комітет і вбивця ООМ найкраще спрацьовує тоді, коли їхнє втручання не потрібне, на що якимось чином поділяється більшість прихильників цієї стратегії, наскільки я можу сказати (і, я визнаю, я не можу сказати багато чого ...). Morover, посилаючись на програми із специфічною поведінкою при попередньому розміщенні пам'яті, змушує мене думати, що конкретне керування може бути налаштоване на рівні розповсюдження, а не за замовчуванням,

Для того, що відносяться до JVM, ну, це віртуальна машина, в деякій мірі , необхідно виділити всі ресурси, необхідні при запуску, так що він може створити своє середовище «підроблені» для її застосування, і тримати його доступний ресурс відокремлена від хоста навколишнє середовище, наскільки це можливо. Таким чином, може бути кращим, щоб він не працював під час запуску, а не через деякий час, як наслідок «зовнішньої» умови OOM (спричиненої вбивцею OOM / OOM / будь-яким іншим), або в будь-якому випадку страждав від такого стану, що втручався в його власний внутрішні стратегії обробки OOM (загалом, VM повинен отримувати будь-які необхідні ресурси з самого початку, а хост-система повинна «ігнорувати» їх до кінця; так само, як і будь-яка кількість фізичного тарана, спільного з відеокартою, ніколи - і не може бути - торкнувся ОС).

Щодо Apache, я сумніваюся, що час від часу вбивати і перезавантажувати весь сервер краще, ніж дозволити одній дитині разом з одним з'єднанням провалитися з початку (= дитини / з'єднання) початку (як би це був цілий новий екземпляр JVM, створений після іншої інстанції, деякий час запускається) Я думаю, що найкраще «рішення» може залежати від конкретного контексту. Наприклад, розглядаючи послугу електронної комерції, може бути набагато кращим мати іноді декілька підключень до діаграми покупок, яка не виходить випадковим чином, а не втратити всю послугу, ризикуючи, наприклад, перервати поточне завершення замовлення, або (можливо гірше) процес оплати з усіма наслідками справи (може бути нешкідливим, але, можливо, корисним - і точно, коли виникли проблеми,

Таким же чином, на робочій станції процес, який витрачає найбільше ресурсів, і таким чином, щоб стати першим вибором для вбивці OOM, міг би бути інтенсивним в пам'яті додатком, таким як відеопередавач чи програмне забезпечення для візуалізації, ймовірно, єдиним додатком користувач хоче бути недоторканим. Ці міркування натякають на мене, що політика дефолту OOM вбивць занадто агресивна. Він використовує "найгірший підхід" підхід, який певним чином схожий з деякими файловими системами (OOMK намагається звільнити стільки пам'яті, скільки може, зменшуючи кількість вбитих підпроцесів, щоб запобігти подальшому втручанню за короткий час, як а також fs може виділити більше дискового простору, ніж фактично потрібно для певного файлу, щоб запобігти подальшому розподілу, якщо файл виріс і, таким чином, певною мірою запобігаючи фрагментації).

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

Більше того, це може бути неправдою, що вбивство меншої кількості можливих процесів - це завжди хороший вибір. Наприклад, у середовищі робочого столу (давайте придумаємо неттоп або нетбук з обмеженими ресурсами, для зразка) користувач може запустити браузер з декількома вкладками (таким чином, споживає пам'ять - припустимо, це перший вибір для OOMK) , плюс кілька інших додатків (текстовий процесор із не збереженими даними, поштовий клієнт, зчитувач PDF, медіаплеєр, ...), плюс кілька (системних) демон, а також кілька екземплярів файлового менеджера. Тепер трапляється помилка OOM, і OOMK вирішує знищити браузер, тоді як користувач робить щось, що вважається "важливим" через мережу ... користувач буде розчарований. З іншого боку, закриття кількох файлових менеджерів "

У всякому разі, я думаю, що користувачеві слід дати можливість самостійно приймати рішення про те, що робити. У настільній (= інтерактивній) системі це зробити досить просто, за умови, що достатньо ресурсів зарезервовано для того, щоб попросити користувача закрити будь-яку програму (але навіть закриття декількох вкладок може бути достатньо) та обробляти його вибір (варіант може складаються з створення додаткового файлу swap, якщо є достатньо місця). Для сервісів (і загалом) я також розглядаю два можливі вдосконалення: одне - це реєстрація вбивчих інтервенцій OOM, а також процеси, що починаються / виправляють збої таким чином, що помилка може бути легко налагоджена (наприклад, API може інформувати процес, що видає нове створення процесу або розгортання - таким чином, такий сервер, як Apache, з належним патчем, може забезпечити кращу реєстрацію певних помилок); це можна зробити незалежно від того, щоб надмірно / комітетом докладати зусиль; по-друге, але не важливо, міг би бути створений механізм для тонкої настройки алгоритму OOMK - я знаю, що можна певною мірою визначити конкретну політику на основі процесу, але я б націлив «централізований» механізм конфігурації, заснований на одному або кількох списках імен додатків (або ідентифікаторів) для виявлення відповідних процесів та надання їм певної міри важливості (відповідно до перелічених атрибутів); такий механізм повинен (або, принаймні, міг би) також бути шаруватим, щоб міг бути визначений користувачем список вищого рівня, список, визначений системою (розподілом), та визначений додатком (нижній рівень) записів (так наприклад, менеджер файлів DE може доручити OOMK безпечно вбити будь-який екземпляр,

Morover, API може бути наданий для того, щоб додатки могли підняти або знизити рівень їх важливості під час виконання (щодо цілей управління пам'яттю та незалежно від пріоритету виконання), так що, наприклад, Word-процесор міг би починати з низька «важливість», але підвищуйте її, оскільки деякі дані зберігаються перед передачею у файл або виконуються операції запису, і знову важливіше, як тільки така операція закінчується (аналогічно, менеджер файлів може змінити рівень, коли він перейшов з просто запалювання файлів для роботи з даними та viceversa, замість того, щоб використовувати окремі процеси, і Apache міг надавати різного рівня важливості різним дітям або змінити стан дитини відповідно до певної політики, яку вирішили систематики та викриті через Apache - або будь-який інший тип сервера - налаштування). Звичайно, такий API може і може бути зловживаний / неправомірно використаний, але я думаю, що це незначне занепокоєння в порівнянні з ядром, що самовільно вбиває процеси, щоб звільнити пам'ять без будь-якої відповідної інформації про те, що відбувається в системі (і споживання пам'яті / час створення або подібні арени 'не достатньо релевантного або' валідаційного 'для мене) - лише користувачі, адміністратори та автори програм можуть дійсно визначити, чи потрібен процес з якихось причин, в чому причина та / або чи програма перебуває у стані, що веде за собою до втрати даних або інших пошкоджень / неприємностей, якщо вони вбиті; однак, деякі припущення ще можуть бути зроблені, наприклад, пошук ресурсів певного виду (дескриптори файлів, мережеві розетки тощо), придбані процесом, і при виконанні операцій, що перебувають у стані очікування, могли б визначити, чи повинен процес бути у вищому «стані», ніж один набір,

Або просто уникайте перевиконання і нехай ядро ​​робить саме те, що має робити ядро, виділяючи ресурси (але не рятуючи їх довільно, як це робить вбивця OOM), планування процесів, запобігання голодуванню та тупикам (або рятування від них), забезпечення повного викупу та розділення простору пам'яті тощо.

Я також хотів би витратити ще кілька слів про підходи до перевиконання. З інших обговорень я висловив думку про те, що одна з головних проблем щодо надмірної передачі (як причина, щоб цього захотіти, так і як джерело можливих неприємностей) полягає у поводженні з виделками: чесно, я не знаю, як саме копіювати, реалізована стратегія "на запис", але я думаю, що будь-яка агресивна (або оптимістична) політика може бути пом’якшена стратегією локальної локації. Тобто замість того, щоб просто клонувати (і коригувати) роздвоєні кодові сторінки та структури планування, кілька інших сторінок даних можна було скопіювати перед фактичним записом, вибравши серед тих сторінок, до яких батьківський процес звертався до запису частіше (тобто використання лічильника для операцій запису).

Все, звичайно, ІМХО.


5
"Morover, API може бути наданий для того, щоб додатки могли підняти або знизити рівень" важливості "під час виконання" Важливість /proc/$PID/oom_adj.
Ві.

1
Що стосується JVM, то є механізм, який змушує вас захотіти перевиконання пам'яті в деяких випадках: якщо ви хочете створити інший JVM з оригінального JVM, він зателефонує fork (). Виклик вилки виділяє стільки пам'яті, скільки і початковий процес (перший), поки він дійсно не запустить процес. Тож скажіть, у вас є JVM об'ємом 4 ГБ і ви хочете створити з нього новий JVM 512 Кб, якщо тільки ви не перезавантажте, для цього вам знадобиться 8 Гб пам'яті ...
alci,

4
@Vi. Здається, зараз/proc/$PID/oom_score_adj
m3nda

1

Якщо ваша пам’ять вичерпно використовується процесами в тій мірі, яка, можливо, загрожує стабільності системи, тоді вбивця OOM вступає в картину. Завдання Вбивці OOM - це вбити процеси, поки не буде звільнено достатньо пам'яті для безперебійного функціонування решти процесу. Убивця OOM повинен вибрати "найкращий" процес для вбивства. Тут "найкраще" відноситься до того процесу, який звільнить максимум пам'яті після вбивства, а також є найменш важливим для системи. Основна мета - знищити найменшу кількість процесів, що мінімізує завданий збиток і одночасно максимізує кількість звільненої пам'яті. Щоб полегшити це, ядро ​​підтримує oom_score для кожного з процесів. Ви можете побачити oom_score кожного з процесів у файловій системі / proc в каталозі pid

# cat /proc/10292/oom_score

Чим вище значення oom_score будь-якого процесу, тим вище є його ймовірність загинути вбивцею OOM в ситуації поза пам'яттю.

Кредит: - Ядро Linux запускає вбивцю OOM

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