Служба работает медленно: упор в CPUQuota
Если служба работает заметно медленнее, чем позволяет машина, стоит проверить квоту процессора. При упоре в неё ядро придерживает процессы, и внешне это выглядит как загадочная медлительность без нагрузки на систему.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Квота задана меньше реальной потребности
Значение вроде 50% выглядит безобидно, но означает половину одного ядра — на многоядерной машине это мало для нагруженной службы.
-
Квота задана у среза
Ограничение среза делится между всеми его службами. Поднятие квоты у одной службы ничего не даст.
-
Дело не в квоте, а в приоритете ввода-вывода
Если служба ждёт диск, процессор не при чём. Признак — процессы в состоянии ожидания и низкая загрузка процессора.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Фактическое потребление процессора по группам.
systemd-cgtop -1 --order=cpu | head -12Все ограничения, влияющие на скорость работы.
systemctl show myapp.service | grep -E "CPUQuota|CPUWeight|IOWeight|Slice"Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Значение вроде 50% выглядит безобидно, но означает половину одного ядра — на многоядерной машине это мало для нагруженной службы.
- Как проверить
-
Посмотрите квоту и фактическое потребление.
systemctl show myapp.service -p CPUQuotaPerSecUSec -p CPUUsageNSec systemd-cgtop -1 --order=cpu | head
- Как исправить
-
Поднимите квоту с учётом числа ядер:
CPUQuota=200%означает два ядра. Либо уберите её и ограничивайте приоритетом черезCPUWeight=.
- Почему происходит
- Ограничение среза делится между всеми его службами. Поднятие квоты у одной службы ничего не даст.
- Как проверить
-
Посмотрите квоту среза.
systemctl show myapp.service -p Slice systemctl show system.slice -p CPUQuotaPerSecUSec
- Как исправить
- Правьте квоту среза или вынесите службу в собственный срез.
- Почему происходит
- Если служба ждёт диск, процессор не при чём. Признак — процессы в состоянии ожидания и низкая загрузка процессора.
- Как проверить
-
Посмотрите состояния процессов и нагрузку на диск.
ps -eo pid,stat,pcpu,cmd | grep myapp | head iostat -x 2 2 2>/dev/null | tail -10
- Как исправить
-
Проверьте
IOWeight=иIOSchedulingClass=: возможно, служба намеренно уступает диск.
Пример вывода
Служба ограничена половиной ядра. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
$ systemctl show myapp.service -p CPUQuotaPerSecUSec
CPUQuotaPerSecUSec=500ms
$ systemd-cgtop -1 --order=cpu | head -3
Control Group Tasks %CPU Memory
/system.slice/myapp.service 12 49.8 512.0M
Связанные ошибки
- signal=XCPU и signal=XFSZ в systemd Процесс службы убит из-за превышения предела процессорного времени (XCPU) или размера файла (XFSZ) из LimitCPU и LimitFSIZE.
- Failed with result 'resources' Состояние resources: systemd не смог выделить ресурсы для запуска службы. Чем отличается от кодов 200-й группы и что проверять.
- status=214/SETSCHEDULER в systemd Код 214/SETSCHEDULER: не удалось применить политику планирования процессора из CPUSchedulingPolicy=. Обычно из-за прав или диапазона приоритета.
- Cannot allocate memory в журнале службы Не удалось выделить память: предел службы, память машины, настройка overcommit, исчерпанные области отображения.
- Disk quota exceeded для службы Место на разделе есть, а запись отклоняется: исчерпана дисковая квота пользователя или группы.
- Elasticsearch: max virtual memory areas vm.max_map_count is too low Elasticsearch отказывается стартовать из-за заниженного vm.max_map_count. Как поднять значение и закрепить его.
- No buffer space available в журнале службы Ошибка 105: нет места в буферах ядра. Разбор для сети и таблиц соседей.
- No space left on device в журнале службы Нет места на устройстве: разбор по свободным блокам, по inode, по журналу systemd и по удалённым, но открытым файлам.
Источники
-
systemd.resource-control(5)
CPUQuota=, CPUWeight= и их влияние. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Проверено на службе с CPUQuota=50%: потребление не превышает половины ядра.