свободная память на сервере

Dec 08, 2014 21:50

А давайте я вам этот вопрос задам ( Read more... )

linux

Leave a comment

Comments 25

greycat_na_kor December 8 2014, 20:53:01 UTC
Точно - никак. Сама постановка задачи несколько странная.

Во-первых, OOM killer настраивается, и далеко не всегда его поведение имеет отношение к абстрактному "сколько памяти свободно". В некоторых режимах оверкоммита первостепенное значение начинает иметь аппроксимация первой или второй производной роста потребления у конкретного процесса и его могут прибить превентивно, иногда сильно далеко от конкретных лимитов потребления памяти.

Во-вторых, даже если таки как-то уговорить OOM killer погодить (в частном случае - отключив его или сильно закрутив лимиты) и выжрать памяти впритык - такая система внезапно становится сильно менее работоспособной, чем обычно, вплоть до "совсем неработоспособной". Особенно если в ней больше, чем один процесс.

Вопрос чисто теоретический или все-таки практический? На практике - подавляющее большинство живет примерной оценкой через чтение /proc/meminfo или /proc/vmstat и отнимания от них взятых с потолка 7-10-15%. Или все-таки это какая-то специфическая задача?

Reply

amarao_san December 8 2014, 23:19:03 UTC
Ок, ок, спасибо.

Итак, речь про обычный (дефолтный) режим №1. Меня интересует ситуация, когда free говорит, что памяти свободной много (допустим, free 300Mb, cached 3Gb, buffers 300Mb, в свопе +2Гб свободно), приложение пишет в 400Мб блок уже аллоцированной памяти, тут прилетает OOM и бьёт всех по рукам.

Экспериментально-эвристически было обнаружено, что дельта явно связана с объёмом записанного на tmpfs, но там ещё что-то есть.

.... А для мониторинга проблема, что "взятые с потолка 15%" ничего не гарантируют.

Reply

greycat_na_kor December 9 2014, 01:58:46 UTC
Ну, вообще почти везде дефолтный - как раз vm.overcommit_memory = 0, а не 1 - и там как раз эта эвристика, первая-вторая производная и все такое в полный рост ( ... )

Reply

amarao_san December 9 2014, 14:32:24 UTC
Я попутал. Чтобы числа не писать, давай говорить guess, never, always. Дефолтный режим guess, именно его я и отлаживаю. При режиме never оно не работоспособно - приложения слишком много virt берут.

NUMA исключаем, у нас interleave.

За shmem спасибо.

У меня задача не приложение отлаживать, а понять, когда на сервере OOM придёт, чтобы мониторинг настроить. Обычными методами он промахивается и срабатывает либо сильно заранее, либо не предупреждает о предстоящем OOM'е.

Reply


_winnie December 8 2014, 22:34:48 UTC
Я плохо знаю линукс, я просто выделяю лишнюю память и смотрю влияет ли это на работу тестового стенда под нагрузкой.
https://gist.github.com/dobrokot/3321085c1b1daa901894

Reply

amarao_san December 8 2014, 23:14:30 UTC
Эм, совсем не оно. Мне нужно понять, когда память на сервере заканчивается. Желательно с точностью хотя бы в +/- гигабайт (из 128-256 доступных).

Reply


qehgt December 8 2014, 22:40:20 UTC
Скорее так: Committed_AS меньше, чем CommitLimit. При этом vm.overcommit_memory должно быть равно 2, чтобы убрать эвристику. В этом случае OOM-killer не будет вызываться вообще, так как для памяти всегда будут назначены virtual pages.

Если же CommitLimit превышен, то OOM-killer может быть вызван даже если память уже не выделять - достаточно будет приложениям начать работать со всей памятью, которую они уже себе выделили.

Reply

amarao_san December 8 2014, 23:16:06 UTC
Эту часть я читал. Но CommitLimit обычно больше объёма оперативной памяти.

Проблема в том, что tmpfs'ные данные засчитываются в buffered (или cached?), но вытеснены не могут быть, из-за этого все эвристики думают, что памяти дофига, а происходит OOM из-за того, что COW'у во время PF не найти свободной страницы.

Reply

qehgt December 9 2014, 00:18:15 UTC
CommitLimit - это swap + какая-то часть RAM. Поэтому он может быть больше RAM, например, если swap большой.

tmpfs выделяет себе память когда ей они понадобились, не резервируя. Поэтому Committed_AS про эту память ничего не знает. Плюс ещё inodes надо хранить - они тоже динамически выделяются.

В твоём случае, получается, что "гарантированная свободная память" - это CommitLimit минус Committed_AS, и минус "сколько ещё может себе забрать tmpfs", и минус "сколько ещё может себе забрать другие части ядра".

Reply

amarao_san December 9 2014, 00:46:16 UTC
Пока что по моим наблюдениям про tmpfs как раз Committed_AS знает, а все остальные нет.

Это если локально.

А если глобально, я понял, что в линуксах никто не знает, сколько памяти свободной, кроме MemFree. Всё остальное спекуляции и гадание на ядерной гуще.

... Да и MemFree не знает. Сколько раз я уже наблюдал, как в экстремальных тестах при 8 свободных мегабайтах, программу, попросившую 4, сносили с треском.

Reply


nefigtut December 10 2014, 16:53:35 UTC
(лирическое отступление) я тут слышал от чувака, пишущего патчи в mm-подсистему ядра высказывание вида "memory mgmt in linux is a pile of crap mixed with legacy crap".

не применим ли в твоей ситуации workaround вида сказать oom-killer-у чтоб "вот этот процесс по oom не убивать ваще, даже если ядро придётся в своп вытеснить"?

Reply

amarao_san December 10 2014, 17:11:30 UTC
oom-adj уже давно во всю используется, но меня интересует состояние раньше.

Reply


si14 December 11 2014, 09:28:41 UTC
Напишешь пост по итогам расследования? Было бы интересно почитать, как правильно контролировать память на хосте.

Reply


Leave a comment

Up