Linux ограничить использование оперативной памяти

Ограничение максимальной доступной памяти процессом

Девопсы настраивают OOM killer, чтобы процессы в контейнере не потребляли памяти больше заданного порога. Софт в контейнере — некоторая самопальная СУБД, которая все данные хранит в памяти. Если пользователь загружает данных в СУБД больше порога, OOM killer благополучно убивает процесс, и девопсы бегут к разработчикам разбираться, почему сервер в очередной раз упал 🙂

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

Понимаю, что можно заменить аллокатор в new/delete, и перед выделением данных в динамической памяти проверять этот порог, но может есть готовые решения? хотя бы для линукса, допустим в glibc может какая функция есть, которая в глобальную переменную в malloc порог запишет?

Или может быть в настройках процессов можно искусственно ограничить процесс, чтобы при привышении порога malloc возвращал nullptr?

Понимаю, что можно заменить аллокатор в new/delete

Я иногда заменяю malloc/free, ты не представляешь себе насколько нетривиальна эта задача… ну у тебя есть операционная система, попробуй покапать в сторону setrlimit

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

Понимаю, что можно заменить аллокатор в new/delete, и перед выделением данных в динамической памяти проверять этот порог, но может есть готовые решения? хотя бы для линукса, допустим в glibc может какая функция есть, которая в глобальную переменную в malloc порог запишет?

Или может быть в настройках процессов можно искусственно ограничить процесс, чтобы при привышении порога malloc возвращал nullptr?

Ничего из этого не будет работать лучше OOM killer. Вернуть nullptr может любой маллок, в том числе никак не связанный с пользователем, загрузившим много данных, а значит опять же упадёт весь сервер. Ну или процесс связанный совершенно другим пользователем. Только в отличие от OOM который прибивает всё и сразу, тут, в зависимости от того как написан сервер, и насколько корректно он обрабатывает nullptr из ВСЕХ маллоков, в т.ч. во внешних библиотеках, может случиться и что-то похуже падения, например зависание с жором ресурсов или повреждение данных.

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

В текущей проблеме все пользователи работают в одном процессе.

В контейнере кроме сервера нет других активных сущностей, только всякие системные проги из baseutils, а если появятся, то девопсы сами себе буратины.

Читайте также:  Установка пакета rpm linux mint

Если какой-то модуль обрабатывает nullptr некорректно, то тут только исправлять ошибки.

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

Это по-моему какое-то извращение, не?

Это по-моему какое-то извращение, не?

Можно вообще без malloc (new) писать, и в ряде случаев это и есть правильный подход.

В текущей проблеме все пользователи работают в одном процессе.

Ну значит в любом случае будет падать весь процесс как я и сказал.

Если какой-то модуль обрабатывает nullptr некорректно, то тут только исправлять ошибки.

Да, но исправления ошибок это одно, а сделать так чтобы программа могла продолжиться после нехватки памяти — совсем другое дело. В общем случае это невозможно, но даже в частном возвращением 0 из malloc по порогу не обойтись.

Например, вернёте вы 0 и код у вас правильный, он обработает 0 и начнёт возвращать ошибку пользователю, выделит для этого память, получит опять 0, а дальше или падение или бесконечная рекурсия или падение. Значит как минимум нужен статический буфер для этой ошибки, а его нужно синхронизировать, а это медленно, значит нужно по буферу на пользователя, а их нужно выделять, а при этом может не хватить памяти — понятна идея?

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

Это по-моему какое-то извращение, не?

Шутите? Это единственное решение вашей проблемы, вполне очевидное.

Источник

Как ограничить память и время процессов в Linux

Системным администраторам часто требуется ограничить память и время процессов в Linux, чтобы избежать ненужного потребления ресурсов. Вы можете легко сделать это с помощью скрипта timeout, который не требует установки и может быть запущен непосредственно из терминала. Он позволяет запускать программы с ограничениями по времени и памяти, а программы, нарушающие эти ограничения, автоматически завершаются. Кроме того, вы можете запустить скрипт таймаута таким образом, чтобы он прерывал только нарушающий процесс и отправлял вам заранее определенное уведомление.

linux

Как ограничить память и время процессов в Linux

Для этой цели мы будем использовать perl-скрипт под названием timeout. Он присутствует в виде репозитория на GitHub. Нет необходимости устанавливать его. Вы можете напрямую скачать и запустить его. Вам просто нужно иметь perl 5, установленный в вашей системе, чтобы иметь возможность ограничивать память и время процессов в Linux. Вы можете проверить версию perl с помощью следующей команды.

Читайте также:  Dhcp сервер linux ubuntu

Скрипт timeout присутствует в виде репозитория на GitHub. Вы можете напрямую клонировать репозиторий timeout, используя следующие команды.

cd ~/bin git clone https://github.com/pshved/timeout.git cd timeout

Базовое ограничение памяти

После загрузки скрипта и перехода в его каталог, вы можете использовать его для ограничения памяти, используя опцию -m и указывая память в килобайтах. Вот пример ограничения виртуальной памяти утилиты stress-ng до 100 Мб.

./timeout -m 100000 stress-ng -t 10m

Если процесс stress-ng займет больше памяти, то он будет автоматически завершен.

Базовое ограничение времени

Вы также можете использовать скрипт timeout для ограничения времени процесса, используя опцию -t, за которой следует число секунд. Вот пример ограничения времени процесса stress-ng до 4 секунд.

./timeout -t 4 stress-ng -t 10m

В приведенном выше примере мы запускаем команду stress-ng в течение 10 секунд, но накладываем на нее временное ограничение в 4 секунды. Поэтому она завершится через 4 секунды.

Ограничение времени и памяти процесса

Вы можете использовать скрипт timeout для ограничения времени и памяти процесса в одной команде. Вот одна команда для указания ограничений на время и память для одного процесса.

./timeout -t 4 -m 100000 stress-ng -t 10m

Вы также можете настроить сценарий таймаута на автоматическое обнаружение зависаний с помощью опции -detect-hangups.

./timeout --detect-hangups -m 100000 stress-ng -t 10m

Вы также можете контролировать размер резидентного набора с помощью переключателя -memlimit-rss или -s.

./timeout -m 100000 -s stress-ng -t 10m

Также, если вы хотите, чтобы команда timeout возвращала код завершения вашего процесса или команды, используйте опцию -c.

./timeout -m 100000 -c stress-ng -t 10m

Заключение

В этой статье мы узнали, как ограничить память и время процессов в Linux. Вы можете запускать эти команды через терминал или запускать их из скрипта. Важно следить за памятью и временем, потребляемым различными процессами в вашей системе, чтобы убедиться, что все работает гладко и не перегружает ваши ресурсы. Timeout — это очень полезный инструмент для системных администраторов и разработчиков, которые хотят контролировать потребление ресурсов процессами, запущенными в системе.

Похожие записи:

Источник

limits.conf и лимиты потребления

limits.conf — файл в Linux системах в котором можно задавать ограничения для системных пользователей, чаще всего на практике оказывается полезным ограничивать количество выделенных ресурсов центрального процессора или оперативной памяти. Файл находится на Debian подобных системах по пути /etc/security/limits.conf

limits.conf и лимиты потребления ресурсов для пользователей в Linux

Прежде всего, как выяснить процессы каких пользователей потребляют больше всего ресурсов CPU оперативной памяти.

Для текущего момента посмотреть процессы можно при помощи утилиты ps

ps aux —sort=%cpu | grep -v ‘root’ | head -n 35

ps aux —sort=%mem | grep -v ‘root’ | head -n 35

Команды выведут сортированные списки процессов в одной из колонок каждого списка будет указано имя пользователя. Процессы, запущенные от имени root показываться не будут и выведутся только 35 самых активных процессов.

Читайте также:  Переключение между языками линукс минт

Пример вывода для cpu:

limits.conf

Пример вывода для mem:

лимиты потребления mem для системных пользователей

Подобным образом достоверные данные получить не удастся, например, для веб-сервера с mod_php, процессы всех пользователей при такой конфигурации будут запускаться от имени пользователя с правами которого работает веб-сервер.

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

Ограничения нужны на нагруженных серверах, они существуют, например, у каждого хостинг провайдера.

Лимитировать количество процессов можно используя механизм ядра cgroups — на практике проще всего установить ограничения отредактировав файл /etc/security/limits.conf и перезагрузив сервер.

Изменять /etc/security/limits.conf может только пользователь root или другой пользователь работающий из под sudo

Файл хорошо задокументирован, вся необходимая информация находится в нем в комментариях, правила меняются с помощью любого текстового редактора

В общем виде любое правило выглядит так:

domain — это пользователь или группа, для которых лимитируем ресурсы

type — тип ограничения: soft или hard, ограничение soft может быть переопределено пользователем.

item — ресурс, который ограничиваем — обычно это cpu (в минутах) или as — максимальное количество оперативной памяти (в Кб); также можно задать nice level, который не сможет быть превышен процессами пользователя/группы (минимум 20, максимум -19); здесь же можно задать chroot (только для debian)

item — само численное значение

Для того чтобы изменения вступили в силу нужна перезагрузка.

ulimit в Linux и ограничение ресурсов для пользователя

Soft лимиты пользователь может переопределить используя ulimit

Выполнение команды с аргументом -a выведет актуальные ограничения

ulimit -as 1500000
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 14685
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 14685
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

Ключи из вывода можно брать и использовать в командах, которые будут задавать ограничения для текущей терминальной сессии.

Дополнительно следует указывать тип ограничения:

Если не указывать ничего лимиты будут заданы жестко. hard здесь можно задать для текущего пользователя даже без прав root, но изменения не сохранятся после перезагрузки и чтобы ограничения были установлены постоянно нужно редактировать файл, который был рассмотрен ранее.

Создадим ограничение по оперативной памяти в 1500 Мб для пользователя

ulimit set soft limit

Выполнив ulimit -Sm или ulimit -a сейчас можно увидеть, что ограничение установлено.

Получить ту же информацию можно просмотрев лимиты для процесса

Можно указывать идентификатор любого процесса, запущенного от имени пользователя, для которого задали ограничение по памяти

Источник

Оцените статью
Adblock
detector