- Який найшвидший спосіб відновити контроль над системою Linux, яка стала невідповідною або надзвичайно млявою через надмірну заміну?
Вже відповів вище за допомогою Alt-SysRq-F
- Чи існує ефективний спосіб запобігти виникненню таких замінів, наприклад, обмеженням обсягу пам'яті, який дозволено спробувати виділити?
Я відповідаю на цю 2-ю частину. Так, ulimit
все ще працює досить добре, щоб обмежити один процес. Ти можеш:
- встановіть м'який ліміт для процесу, який ви знаєте, ймовірно, вийде з-під контролю
- встановіть жорсткий ліміт для всіх процесів, якщо ви хочете отримати додаткову страховку
Також, як коротко згадувалося:
Ви можете використовувати CGroups для обмеження використання ресурсів та запобігання таких проблем
Дійсно, групи пропонують більш досконалий контроль, але наразі на мою думку складніше налаштувати.
Стара школа ulimit
Одного разу вимкнений
Ось простий приклад:
$ bash
$ ulimit -S -v $((1*2**20))
$ r2(){r2 $@$@;};r2 r2
bash: xmalloc: .././subst.c:3550: cannot allocate 134217729 bytes (946343936 bytes allocated)
Це:
- Встановлює м'який ліміт загального обсягу використання пам’яті 1 Гб (зменшення припускає ліміт у кБ)
- Виконує рекурсивний виклик функції bash,
r2(){ r2 $@$@;};r2 r2
який буде експоненціально розжувати процесор і оперативну пам'ять, нескінченно подвоюючи себе, вимагаючи стека пам'яті.
Як бачите, його зупинили при спробі запитувати більше 1 Гб.
Зауважте, -v
діє на розподіл віртуальної пам'яті (загальний, тобто фізичний + своп).
Постійний захист
Щоб обмежити розподіл віртуальної пам'яті, as
це еквівалент -v
для limits.conf
.
Я роблю такі дії, щоб захистити від будь-якого одного недобросовісного процесу:
- Встановіть обмежений простір адресного простору для всіх процесів.
address space limit = <physical memory> - 256MB
.
- Тому жоден процес із жадібним використанням пам'яті або активним циклом та витоком пам’яті не може споживати ВСЮ фізичну пам'ять.
- Розміщення на 256 МБ є необхідним для оброблення файлом ssh або консоллю.
Один вкладиш:
$ sudo bash -c "echo -e \"*\thard\tas\t$(($(grep -E 'MemTotal' /proc/meminfo | grep -oP '(?<=\s)\d+(?=\skB$)') - 256*2**10))\" > /etc/security/limits.d/mem.conf"
Для перевірки це призводить до наступного (наприклад, у системі 16 ГБ):
$ cat /etc/security/limits.d/mem.conf
* hard as 16135196
$ ulimit -H -v
161351960
Примітки:
- Лише пом'якшує процес, який перебуває за бортом із використанням пам'яті.
- Не завадить багатопроцесовий навантаження з великим тиском пам’яті, що спричиняє молотіння (тоді група відповіді).
- Не використовуйте
rss
параметр у limit.conf. Нові ядра не поважаються.
- Це консервативно.
- Теоретично процес може спекулятивно вимагати великої кількості пам'яті, але лише активно використовувати підмножину (менший робочий набір / використання резидентної пам'яті).
- Вищеописаний жорсткий ліміт призведе до переривання таких процесів (навіть якщо вони могли б інакше спрацювати, якщо Linux дозволяє надмірно передавати адресний простір віртуальної пам'яті).
Новіші групи CG
Забезпечує більше контролю, але в даний час більш складний у використанні:
- Поліпшується безперервна пропозиція.
memory.max_usage_in_bytes
може обліковувати та обмежувати фізичну пам'ять окремо.
- Тоді як
ulimit -m
і / або rss
в limits.conf
малося на увазі пропонувати подібну функціональність, але це не працює з ядра Linux 2.4.30!
- Потрібно включити деякі ядра контрольної групи прапорів в засобі завантаження:
cgroup_enable=memory swapaccount=1
.
- Це не сталося за замовчуванням з Ubuntu 16.04.
- Можливо, через деякі наслідки для ефективності додаткових накладних витрат.
- Програми cgroup / systemd є відносно новими і досить мінливими, тому потік вище за течією передбачає, що постачальники дистрибутивів Linux ще не зробили його легким у використанні. Між 14.04LTS та 16.04LTS, інструмент користувальницького простору змінився для використання груп.
cgm
тепер, здається, є офіційно підтримуваним інструментом простору користувачів.
- Файли системних одиниць ще не мають жодних заздалегідь визначених параметрів "постачальник / дистрибутив", які надають пріоритет таким важливим службам, як ssh.
Наприклад, щоб перевірити поточні налаштування:
$ echo $(($(cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes) / 2**20)) MB
11389 MB
$ cat /sys/fs/cgroup/memory/memory.stat
...
Наприклад, щоб обмежити пам'ять одного процесу:
$ cgm create memory mem_1G
$ cgm setvalue memory mem_1G memory.limit_in_bytes $((1*2**30))
$ cgm setvalue memory mem_1G memory.memsw.limit_in_bytes $((1*2**30))
$ bash
$ cgm movepid memory mem_1G $$
$ r2(){ r2 $@$@;};r2 r2
Killed
Щоб побачити це в дії, що розжовує оперативну пам'ять як фоновий процес, а потім вбиває:
$ bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2' & while [ -e /proc/$! ]; do ps -p $! -o pcpu,pmem,rss h; sleep 1; done
[1] 3201
0.0 0.0 2876
102 0.2 44056
103 0.5 85024
103 1.0 166944
...
98.9 5.6 920552
99.1 4.3 718196
[1]+ Killed bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2'
Зверніть увагу на експоненціальне (потужність 2) зростання запитів на пам'ять.
Надалі сподіваємось побачити "distro / vendors" попередньо налаштувати пріоритети та обмеження для групи (через системні блоки) для таких важливих речей, як SSH та графічний стек, щоб вони ніколи не голодували пам'яті.