cgroup2: io controller throttled — Троттлинг дискового ввода-вывода в Linux
Архитектура ошибки и симптомы сбоя
Предупреждение «cgroup2: io controller throttled: rbps/wbps limit reached» генерируется подсистемой контроля блочного ввода-вывода cgroups v2 (I/O Controller / BlkIO). Событие означает, что процессы внутри определенной контрольной группы (Docker-контейнер, systemd service, Kubernetes Pod) исчерпали выделенную полосу дискового чтения (rbps), записи (wbps) или лимиты по числу операций в секунду (riops / wiops), заданные в файле io.max. В результате ядро принудительно задерживает I/O запросы в очереди, вызывая резкий рост iowait и падение отзывчивости приложения.
Диагностическая таблица параметров сбоя
| Параметр | Значение | Инженерный смысл сбоя |
|---|---|---|
| io.max | $MAJ:$MIN rbps=.. wbps=.. | Жесткие абсолютные лимиты пропускной способности (байт/сек) и IOPS. |
| io.pressure (PSI) | I/O Stall Percentage | Метрика времени, проведенного потоками в ожидании дискового троттлинга. |
| io.stat | rbytes, wbytes, dbytes | Фактическая статистика переданных байтов и сбросов (throttled count). |
Пошаговое дерево решений и сценарии траблшутинга
Сценарий 1: Анализ троттлинга и потерь времени на I/O в cgroup
# Определение Major:Minor номера сбойного накопителя (например, 8:0 для sda):
ls -l /dev/sda
# Просмотр статистики троттлинга конкретного сервиса:
cat /sys/fs/cgroup/system.slice/service_name.service/io.stat
# Проверка метрик давления на диск (I/O PSI):
cat /sys/fs/cgroup/system.slice/service_name.service/io.pressureСценарий 2: Увеличение лимитов скорости и IOPS в Systemd
Отрегулируйте дисковые квоты для сервиса:
# Редактирование юнита systemd:
sudo systemctl edit service_name.service
# Добавьте в открывшуюся конфигурацию расширенные лимиты:
[Service]
# Увеличение чтения и записи до 250 MB/s на диске 8:0:
IOReadBandwidthMax=/dev/sda 250M
IOWriteBandwidthMax=/dev/sda 250M
# Увеличение лимита IOPS до 15 000:
IOReadIOPSMax=/dev/sda 15000
IOWriteIOPSMax=/dev/sda 15000
# Примените изменения:
sudo systemctl daemon-reloadСценарий 3: Снятие ограничений io.max в Docker / cgroups v2 напрямую
# Полное удаление лимитов для cgroup (установка max):
echo "8:0 rbps=max wbps=max riops=max wiops=max" | sudo tee /sys/fs/cgroup/my_container_cgroup/io.max
# Для Docker контейнера при запуске:
docker run -d --device-write-bps /dev/sda:500mb --device-write-iops /dev/sda:20000 my_imageСценарий 4: Переключение I/O планировщика на BFQ или MQ-Deadline
# Для NVMe накопителей используйте none или mq-deadline:
echo mq-deadline | sudo tee /sys/block/sda/queue/schedulerITSTM настроит справедливое весовое распределение дисковых ресурсов (io.weight / BFQ), тюнинг page cache и обеспечит гарантированный SLA ввода-вывода.
Частые вопросы (FAQ)
Чем подход io.weight отличается от io.max в cgroups v2?
io.max задает жесткий фиксированный потолок (Hard Limit), выше которого процесс не прыгнет даже на абсолютно пустом диске. io.weight задает пропорциональный вес (1–10000): процесс получает всю скорость диска, пока нет конкурентов, и плавно ограничивается только в моменты одновременной нагрузки.
Включает ли io controller сброс грязных страниц (buffered write)?
В cgroups v2 (в отличие от v1) контроллер памяти и контроллер I/O полностью объединены. Сброс асинхронной буферизованной записи (Writeback) корректно атрибутируется к той cgroup, которая сгенерировала dirty pages.
Как Major и Minor номера дисков связаны с io.max?
Контроллер cgroups адресует физические накопители строго по их системным номерам устройств. Узнать номера можно командой ls -l /dev/sd* или lsblk (столбец MAJ:MIN).
Что показывает строка 'some' в файле io.pressure?
Она показывает процент времени, в течение которого хотя бы один процесс в cgroup ожидал завершения дисковых операций ввода-вывода из-за троттлинга или физической перегрузки накопителя.