Лимиты дисковых операций для виртуалок: настройка и смысл
Одна виртуалка запустила бэкап или тяжёлый batch-процесс — и у соседних VM на том же хранилище внезапно "залипает" диск: базы данных подвисают на записи, сайты отвечают медленнее, мониторинг сыплет алертами о высоких задержках. Если вы не задавали явных лимитов дисковой пропускной способности для каждой VM, рано или поздно это случится именно так. Решение не в том, чтобы гадать и выкручивать общие настройки хранилища, а в том, чтобы явно ограничить каждую виртуалку на уровне её собственного диска — и делать это осознанно, на основе замеров, а не наугад.
Содержание
- Что происходит без лимитов: один шумный сосед душит всех
- Два инструмента ограничения: bps и iops — это разные вещи
- Как задать лимиты в Proxmox: конкретные параметры диска VM
- Как измерить реальную пропускную способность хранилища перед тем как раздавать лимиты
- Как посчитать лимит для конкретной виртуалки: доля от измеренного максимума, а не произвольное число
- Предсказуемость планирования: зачем считать худший сценарий заранее
Что происходит без лимитов: один шумный сосед душит всех
Физическое хранилище под гипервизором — будь то локальный NVMe-массив, RAID из SSD или сетевой Ceph/NFS — обслуживает одну общую очередь запросов от всех виртуалок сразу. У диска (или у сетевого хранилища) есть конечная пропускная способность в мегабайтах в секунду и конечное число операций в секунду, которое он способен обработать с приемлемой задержкой. Когда все VM ведут себя скромно, очередь не копится, и никто не замечает, что ресурс общий.
Проблема начинается, когда одна VM внезапно генерирует резкий всплеск ввода-вывода: ночной бэкап с полным сканированием диска, пересборка индексов в базе, разворачивание образа, антивирусная проверка, интенсивный rsync или архивация логов. Без ограничений эта VM может занять всю доступную пропускную способность общего хранилища на минуты или десятки минут. Остальные виртуалки в это время не "падают" явно — они просто ждут своей очереди дольше обычного. На практике это выглядит как рост await и svctm в iostat на соседних VM, таймауты у клиентов приложений, медленные коммиты в базах, а иногда и алерты мониторинга уровня "диск не отвечает". Разобраться, что именно тормозит диск на конкретной VM, помогает статья про диагностику медленного диска на VPS — но лучше не доводить до диагностики постфактум, а не допустить самой возможности монополизации.
Явный лимит bps/iops на уровне конфигурации диска VM решает эту проблему на корню: гипервизор просто не даст виртуалке превысить установленный порог, сколько бы она ни просила. Остальные VM физически не могут пострадать от чужого всплеска, потому что "нарушитель" упирается в собственный потолок, а не в общий предел хранилища.
Два инструмента ограничения: bps и iops — это разные вещи
Часто их путают, а разница принципиальна:
bps(bytes per second, в Proxmox обычно задаётся в MB/s черезmbps_rd/mbps_wr) — лимит на объём переданных данных в секунду. Он важен для последовательных операций с большими блоками: копирование файлов, потоковая запись видео, разворачивание образов, бэкапы больших директорий.iops(iops_rd/iops_wr) — лимит на количество операций ввода-вывода в секунду, независимо от размера каждой операции. Он критичен для нагрузок с большим числом мелких случайных запросов: базы данных, почтовые серверы, файловые системы с множеством мелких файлов. Именно IOPS обычно упирается в потолок раньше, чем MB/s — подробнее о том, почему цифра IOPS в характеристиках диска редко достижима на практике, разобрано в статье "Что такое IOPS на самом деле и почему цифра недостижима".
Оба параметра в Proxmox задаются раздельно для чтения (_rd) и записи (_wr), что позволяет тонко настраивать асимметричные сценарии. Например, VM с бэкап-агентом читает много (сканирует файловую систему), но почти ничего не пишет на локальный диск — там имеет смысл жёстко ограничить чтение и оставить запись свободной. А VM с базой данных обычно наоборот чувствительна к задержкам записи (fsync на каждый коммит), поэтому лимит на запись нужно ставить с запасом, а не впритык.
Кроме базовых (mbps_rd, mbps_wr, iops_rd, iops_wr) в Proxmox есть параметры burst-лимитов — mbps_rd_max, mbps_wr_max, iops_rd_max, iops_wr_max — они задают более высокий кратковременный потолок, до которого VM может подниматься на короткое время (пока не исчерпан "бакет" накопленных токенов), после чего скорость возвращается к базовому значению. Это удобно для нагрузок, у которых редкие пики не страшны, а вот постоянная высокая нагрузка — да: VM получает разгон при разовом всплеске, но не может держать этот уровень часами.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверКак задать лимиты в Proxmox: конкретные параметры диска VM
Лимиты настраиваются на уровне конкретного виртуального диска конкретной VM — не глобально на всё хранилище и не на весь узел. Это можно сделать двумя способами.
Через веб-интерфейс: Datacenter → узел → VM → Hardware → выбрать диск → Edit → Advanced — там есть отдельные поля Limit read (MB/s), Limit write (MB/s), Limit read (ops/s), Limit write (ops/s).
Через qm set из консоли — быстрее для скриптов и повторяемых конфигураций:
qm set 101 --scsi0 local-lvm:vm-101-disk-0,mbps_rd=150,mbps_wr=100,iops_rd=4000,iops_wr=2500
Или, если диск уже подключён и нужно только поменять лимиты, не трогая остальные параметры:
qm set 101 --scsi0 local-lvm:vm-101-disk-0,mbps_rd_max=250,mbps_wr_max=180
Посмотреть текущую конфигурацию диска VM, чтобы не потерять уже заданные параметры при правке:
qm config 101 | grep scsi0
Важный нюанс: лимиты применяются на лету без перезагрузки VM в большинстве случаев (через qm set изменения подхватываются гипервизором сразу), но стоит проверить фактическое применение — например, повторным qm config и тестовым запуском fio внутри VM после изменения.
Если у VM несколько дисков (например, системный на быстром NVMe и архивный на медленном HDD-пуле), лимиты задаются отдельно на каждый диск — это нормально и часто нужно: системный диск с базой получает более щедрый лимит IOPS, а диск с логами или архивами — жёсткий лимит по MB/s, чтобы архивация не мешала остальным.
Как измерить реальную пропускную способность хранилища перед тем как раздавать лимиты
Ставить лимиты "на глазок" — плохая идея: слишком низкий лимит душит легитимную нагрузку, слишком высокий не защищает от шумного соседа. Прежде чем расписывать цифры по VM, нужно знать реальный потолок конкретного хранилища на конкретном железе — паспортные цифры производителя SSD или маркетинговые "до N IOPS" почти никогда не совпадают с тем, что вы получите в реальном RAID/ZFS/Ceph-массиве под смешанной нагрузкой.
Практичный способ — прогнать fio на самом хранилище (на пустом тестовом разделе или временной тестовой VM, ещё до раздачи продакшн-нагрузки):
# случайное чтение блоками 4K — типичная нагрузка баз данных
fio --name=randread --filename=testfile --size=4G --rw=randread \
--bs=4k --iodepth=32 --numjobs=4 --runtime=60 --time_based --group_reporting
# случайная запись 4K — самый чувствительный сценарий для БД и очередей
fio --name=randwrite --filename=testfile --size=4G --rw=randwrite \
--bs=4k --iodepth=32 --numjobs=4 --runtime=60 --time_based --group_reporting
# последовательная запись большими блоками — для бэкапов и потоковой записи
fio --name=seqwrite --filename=testfile --size=4G --rw=write \
--bs=1M --iodepth=8 --numjobs=2 --runtime=60 --time_based --group_reporting
В выводе смотрите на iops и bw (bandwidth) в секции read/write, а также на clat (completion latency) — если задержка резко растёт при увеличении iodepth, вы уже нашли реальный потолок хранилища, а не теоретический. Держите в уме: у сетевого хранилища (Ceph, NFS, iSCSI) на результат сильно влияет ещё и сеть между узлами — какие типы хранилищ обычно используются в Proxmox и когда какой уместен, разобрано в статье "Хранилища в Proxmox: что и когда". Тестировать нужно именно ту связку "хранилище + сеть", которая будет обслуживать боевые VM, а не абстрактный локальный SSD на столе.
Конкретные цифры, которые вы получите, будут вашими собственными — на разном железе, RAID-контроллерах и типах SSD (SATA/NVMe, с PLP или без) результат отличается в разы. Не переносите чужие ориентиры из статей или форумов на своё железо — это ровно та ситуация, когда нужно измерить самому.
Как посчитать лимит для конкретной виртуалки: доля от измеренного максимума, а не произвольное число
Когда есть реальные цифры хранилища (условно — в вашем случае получилось, скажем, 60 000 IOPS на случайную запись 4K и 900 MB/s на последовательную запись), дальше это надо честно поделить между VM, а не просто скопировать в конфиг каждой виртуалки.
Логика расчёта:
- Оставьте запас, не разгоняйте лимиты впритык к измеренному максимуму. Сам гипервизор, фоновые задачи Proxmox (snapshot-очистка, репликация,
pvestatd), а также деградация SSD при заполнении диска съедают часть реальной производительности. Разумно закладывать сумму лимитов всех VM на уровне 60-75% от измеренного максимума хранилища, а не 100%. - Распределяйте пропорционально приоритету, а не поровну. Продакшн-база данных с чувствительными коммитами получает больший запас IOPS, чем фоновая VM с архивом логов или тестовым стендом.
- Считайте IOPS и MB/s отдельно — они не взаимозаменяемы, VM может упереться в один лимит и не задеть другой.
Пример распределения для узла, где измеренный потолок хранилища — условно 60 000 IOPS (запись) и 900 MB/s, на нём 6 VM:
| VM | Роль | Доля от пула | iops_wr | mbps_wr |
|---|---|---|---|---|
| vm-db-prod | Продакшн-БД | 35% | 15000 | 200 |
| vm-web-1, vm-web-2 | Веб-фронты (по 15%) | 30% | 12000 (по 6000) | 160 (по 80) |
| vm-backup | Бэкап-агент | 10% | 4000 | 60 |
| vm-test | Тестовый стенд | 5% | 2000 | 30 |
| Резерв (новые VM, пики) | — | 20% | 12000 | 190 |
Сумма распределённых лимитов — около 80% от измеренного потолка, оставшиеся 20% — сознательный резерв на новые VM и на погрешность самого измерения. Это ориентировочная схема, а не готовый рецепт: реальные пропорции зависят от того, сколько у вас VM, какие из них критичны, и насколько сильно нагрузки пересекаются по времени.
Предсказуемость планирования: зачем считать худший сценарий заранее
Вторая причина ставить явные лимиты — не защита, а планирование. Без лимитов администратор не может ответить на простой вопрос: "что будет, если все VM одновременно упрутся в диск на полную мощность?" Это неизвестность, которая рано или поздно материализуется — например, в момент, когда несколько VM случайно синхронизировали бэкапы на одно и то же ночное окно.
Когда у каждой VM явно прописан лимит bps/iops, сумма этих лимитов — это и есть посчитанный "потолок худшего случая": максимальная суммарная нагрузка, которую хранилище увидит, даже если все виртуалки одновременно решат использовать диск на полную. Сравнивая эту сумму с измеренной реальной пропускной способностью хранилища (см. предыдущий раздел про fio), вы заранее знаете, справится ли железо, — вместо того чтобы узнавать это постфактум по алертам и жалобам пользователей.
Это же значительно упрощает добавление новых VM на узел: вместо интуитивной оценки "вроде должно поместиться" вы смотрите остаток резерва (в примере выше — 20% пула) и понимаете, сколько ещё виртуалок с каким профилем нагрузки можно безопасно добавить, не трогая существующие лимиты. Планирование ёмкости превращается из гадания в арифметику. Похожая логика "один шумный сосед против предсказуемости для всех" применима и к процессору — там роль играет steal time, о котором подробно написано в статье "Steal time: как понять, что сосед ест ваш CPU"; диск и CPU в этом смысле — зеркальные задачи одного и того же вопроса про общий ресурс.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Что делать, если лимит оказался слишком низким и мешает нормальной работе VM?
Смотрите на график использования IOPS/MB/s этой VM в мониторинге за пару недель. Если она регулярно упирается в потолок при обычной (не аварийной) нагрузке — лимит занижен, поднимайте его постепенно, а не сразу вдвое. Burst-параметры (mbps_wr_max, iops_rd_max) часто решают проблему мягче, чем прямое повышение базового лимита: VM получает запас на пики, но не может держать высокую нагрузку постоянно.
Можно ограничить только запись, оставив чтение без лимита?
Да, _rd и _wr задаются независимо. Это осмысленно, например, для VM с бэкап-агентом: она много читает (сканирует файловую систему источника), но почти не пишет на локальный диск, — лимитировать имеет смысл именно чтение, если оно мешает соседям.
А если хранилище сетевое — Ceph, NFS, iSCSI, а не локальный диск?
Логика та же самая, но замер нужно делать именно от VM до реального хранилища через ту же сеть, что будет использоваться в проде, — узкое место может оказаться не в самом хранилище, а в сетевом канале или в задержке протокола. Лимиты bps/iops на уровне диска VM работают одинаково независимо от типа бэкенда хранилища.
Нужны ли лимиты, если на сервере всего 1-2 виртуалки?
Критичность ниже, но польза остаётся: лимит защищает сам хост Proxmox (его системные процессы и логи) от случайного зависания из-за диска, а также заранее готовит конфигурацию к моменту, когда на узел добавится третья VM — не придётся вспоминать про лимиты в спешке.
Мешают ли лимиты бэкапам через vzdump?
Штатный бэкап Proxmox идёт как обычная нагрузка от той же VM (или от самого хоста при snapshot-режиме) и тоже упирается в заданные лимиты диска. Если ночные бэкапы стабильно не укладываются в окно из-за лимита — либо повышайте лимит именно на время бэкапа отдельной командой qm set, либо переносите бэкап-трафик на выделенный лимит с более высоким порогом чтения.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →