Главная
» Как сделать
»
Ограничение использования ЦП и памяти командой с помощью cgroups в Ubuntu.
Ограничение использования ЦП и памяти командой с помощью cgroups в Ubuntu.
Если какая-либо команда замедляет работу вашего рабочего стола Ubuntu или приводит к нехватке памяти на сервере, поместите эту команду и её дочерние процессы в управляемую systemd группу cgroup с квотой на ЦП и ограничением на использование памяти. В текущих версиях Ubuntu systemd-run --scopeэто самый короткий практический путь: команда запускается во временной области видимости, а systemd применяет ограничения через элементы управления cgroup.
В приведенном ниже примере рабочая нагрузка ограничена половиной мощности одного процессора и 1 ГБ памяти. Это ограничения для всей области видимости, включая дочерние процессы; они не гарантируют, что программа будет работать с определенной скоростью.
Почему процессу необходимо ограничение на количество процессов в группе (cgroup limit)?
Загруженный процесс может конкурировать с интерактивными приложениями, а процесс, интенсивно использующий память, может привести к освобождению памяти или нехватке памяти. Группа процессов (cgroup) объединяет процесс с его потомками, чтобы ядро могло учитывать и ограничивать эту группу. Система systemd в Ubuntu предоставляет удобный интерфейс для управления этими процессами.
Настройки ЦП и памяти ведут себя по-разному. CPUQuota=50%ограничивает время работы ЦП половиной мощности одного ЦП, усредненной за период планирования. Значение 200%представляет собой время работы до двух ЦП, если оно доступно. Это верхний предел, а не приоритет ЦП или резервирование. MemoryMax=1Gустанавливает жесткий потолок для памяти, выделяемой группе cgroup; если рабочая нагрузка не может оставаться ниже этого уровня, ядро может освободить память или вызвать завершение процесса в этой группе cgroup из-за нехватки памяти. Выберите ограничение с запасом для приложения и его дочерних процессов.
1. Убедитесь, что Ubuntu использует cgroup v2.
В системах Ubuntu, использующих systemd, обычно применяется унифицированная иерархия cgroup v2. Перед использованием указанных далее путей подтвердите активную конфигурацию:
stat -fc %T /sys/fs/cgroup
systemctl --version | head -n 1
Первая команда должна вывести сообщение об ошибке cgroup2fs. Если она выводит сообщение о другом типе файловой системы, пути к файлам cgroup v2, указанные в этой статье, не применяются в том виде, в котором они описаны. Свойства systemd могут по-прежнему поддерживаться при другой иерархии, но используйте соответствующую документацию дистрибутива, а не копируйте пути v2.
Также проверьте точную версию systemd, если какое-либо свойство отклонено. В документации Ubuntu Noble эти параметры описываются CPUQuota=как MemoryMax=настройки управления ресурсами; в более старых версиях Ubuntu могут использоваться другие версии systemd.
2. Начните выполнение работы в ограниченном объеме.
Запустите программу systemd-run, заменив её реальный исполняемый файл и аргументы. Для команды в текущем каталоге используйте ./и передайте все аргументы после --:
Запуск команды во временной области видимости systemd с учетом ограничений по процессору и памяти.
Для команды, принадлежащей пользователю, попробуйте сначала выполнить её без прав администратора sudo. Если systemd сообщает о недоступности запрошенного контроллера или свойства, возможно, у администратора пользователя нет разрешения на его делегирование; повторная попытка от имени root может быть уместна для общесистемной нагрузки, но это изменяет контекст безопасности команды. Не запускайте ненадежную программу от имени root бездумно. Если использование системного администратора от имени root необходимо, используйте эту команду sudo systemd-run --scope ...только после учета этого изменения.
Терминал остается подключенным к области видимости во время выполнения команды. Нажатие клавиши Ctrl+Cпрерывает работу в фоновом режиме. Область видимости является временной и обычно исчезает после завершения процессов. Это удобный способ запуска команды в рамках установленных ограничений, а не постоянная политика для будущих запусков.
3. Определите область применения и проверьте её границы.
systemd-runВыводит имя создаваемого юнита, обычно что-то вроде run-….scope. Пока команда выполняется, выводит список деревьев cgroup:
systemd-cgls
Найдите временную область видимости и убедитесь, что целевая программа и ее дочерние приложения находятся под ней. Это важно, потому что дочернее приложение, работающее вне этой области видимости, не будет охвачено тем же ограничением cgroup.
Используйте дерево cgroup, чтобы убедиться, что программа и ее рабочие процессы сгруппированы в рамках временной области видимости.
Используйте выведенное имя области видимости в следующей команде. Замените run-abc.scopeна фактическое имя:
systemctl show run-abc.scope \
-p ControlGroup -p CPUQuotaPerSecUSec -p MemoryMax
CPUQuotaPerSecUSec=50000Соответствует 50% квоте, когда период квоты systemd составляет 100 мс; MemoryMax=1073741824составляет 1 ГиБ в байтах. Актуальные значения более полезны, чем предположение, что каждый хост примет каждый запрос без изменений, поскольку родительские cgroups и доступные контроллеры могут ограничивать эффективный результат.
Проверьте указанную в осциллографе группу управления, а также настроенные ограничения по загрузке ЦП и памяти.
4. Проверьте файлы cgroup ядра и внесите необходимые корректировки.
Это ControlGroupсвойство задаёт путь к cgroup относительно /sys/fs/cgroup. Сохраните его в переменной оболочки, чтобы команды следовали пути, фактически назначенному на вашем компьютере:
В cgroup v2 cpu.maxсодержится квота и период в микросекундах. Например, 50000 100000означает 50 мс процессорного времени в каждом 100-миллисекундном периоде. memory.maxпоказывает потолок памяти в байтах. Если файлы отсутствуют, убедитесь, что область действия все еще активна и что ядро использует cgroup v2.
Прочитайте файлы cgroup v2 ядра, чтобы проверить настроенные квоту и потолок памяти.
Если вы запустили именованный долго работающий модуль и вам необходимо настроить его ограничения, systemd поддерживает изменение свойств ресурсов активного модуля, например sudo systemctl set-property --runtime my-worker.service CPUQuota=50% MemoryMax=1G. Это относится к cgroup этой службы и требует соответствующих привилегий. Он не подключает произвольный уже запущенный процесс только потому, что известен его PID; для одноразового процесса его следует корректно остановить и перезапустить через ограниченную область видимости. Для постоянной службы настройте свойства в модуле службы или в модуле systemd и перезапустите его во время соответствующего окна обслуживания.
Проверьте результат
Поддерживайте рабочую нагрузку активной во время ее проверки. Убедитесь, что systemd-cglsпроцесс и его дочерние процессы находятся в пределах заданной области видимости, что systemctl showсообщается о запрошенных свойствах и что соответствующие cpu.maxфайлы memory.maxсуществуют с конечными значениями. После завершения процесса временная область видимости удаляется, поэтому его файлы cgroup могут исчезнуть.
Квота ограничивает время работы процессора, но не гарантирует фиксированный процент в мониторе рабочего стола, а жесткое ограничение памяти может привести к сбоям, если приложению требуется больше памяти, чем предусмотрено ограничением. Если рабочая нагрузка становится нестабильной, остановите ее и повысьте лимит до измеренного безопасного значения или используйте более мягкий MemoryHigh=порог нагрузки наряду с более высоким значением MemoryMax=. Для получения точной информации о поведении обратитесь к документации установленной системы systemd и ядра; авторитетными источниками являются руководство по systemd-run в Ubuntu , руководство по управлению ресурсами systemd в Ubuntu и документация ядра Linux cgroup v2 .