Почему IOPS на VDS — это не просто «чем больше, тем лучше»
Когда выбирают VDS под базу данных или брокер сообщений, часто сравнивают тарифы по одной цифре «IOPS». Проблема в том, что IOPS — метрика контекстная: она зависит от размера блока (4K, 16K, 128K), типа операций (random/sequential, read/write, sync/async), глубины очереди и целевой задержки. Поэтому два диска с одинаковыми IOPS «по паспорту» могут дать совершенно разный результат в реальном database workload.
Правильный вопрос для админа звучит так: «Какие у меня I/O patterns и какая latency приемлема, чтобы сервис держал SLA?» Если разобрать это до цифр, выбор тарифа становится предсказуемым.
IOPS, latency и throughput: как связаны три главные метрики
IOPS — количество операций чтения/записи в секунду. Latency — задержка одной операции. Throughput — объём данных в секунду (MB/s или GB/s). Важно: при фиксированной глубине очереди рост latency неизбежно «съедает» IOPS.
В эксплуатации удобно держать в голове приближение из закона Литтла:
IOPS ≈ QueueDepth / LatencySeconds
Пример: при QueueDepth=4 и средней задержке 2 мс (0.002s) теоретический потолок около:
IOPS ≈ 4 / 0.002 = 2000
Если latency выросла до 10 мс, то при той же очереди получится около 400 IOPS. Это не «внезапное падение диска», а нормальная физика очередей.
Throughput напрямую зависит от IOPS и размера блока:
Throughput ≈ IOPS × BlockSize
Отсюда практический вывод: сравнивать IOPS без размера блока почти бессмысленно. «10000 IOPS» на 4K — это порядка 40 MB/s, а на 128K — уже около 1.25 GB/s.
Почему NVMe меняет правила игры (но не отменяет планирование)
NVMe ценен в первую очередь низкой latency и эффективной работой с очередями по сравнению с SATA/SAS, особенно на random I/O. Но на VDS вы почти всегда упираетесь не только в «железо», а в комбинацию факторов: виртуализация, лимиты хранилища, соседние нагрузки, настройки ОС и файловой системы, а также поведение конкретного приложения.
Практический ориентир: для БД и очередей чаще важнее не «максимальные IOPS», а стабильная latency под смешанной записью. NVMe обычно выигрывает именно стабильностью на малых блоках и при конкурентной нагрузке.
Если вы планируете переносить тяжёлую БД/очереди на новый сервер, сначала определите, какую задержку записи вы считаете «нормальной» на 95p/99p — и уже под это выбирайте конфигурацию диска и лимиты.

Какие I/O patterns встречаются чаще всего
Чтобы прикинуть sizing, полезно классифицировать нагрузку по нескольким осям:
- Random vs Sequential: базы и очереди чаще random, бэкапы и стриминг — sequential.
- Read vs Write: кэши и большие буфер-пулы разгружают reads; логи и очереди часто write-heavy.
- Sync vs Async:
fsyncв БД делает запись «дороже» по latency, но надёжнее. - Block size: для «паспортных» тестов любят 4K; в реальном приложении часто встречаются 8K/16K/32K и выше.
- Concurrency: один поток покажет «космическую» latency и «смешные» IOPS; рост параллельности увеличит IOPS, но обычно ухудшит хвосты.
Если вы не знаете свой паттерн, начните с измерений на текущем сервере: доля reads/writes, очереди и распределение задержек. Для практики по инструментам и интерпретации метрик полезно иметь под рукой заметку про iostat, iotop, fio и I/O scheduler.
Что означает «IOPS для базы данных» на практике
Запросы вроде «postgresql iops» и «mysql iops» обычно означают одно: выдержит ли диск пиковую запись и случайные чтения так, чтобы не росли задержки запросов и не начинались лавинообразные таймауты из-за накопления очереди.
PostgreSQL: где IOPS и latency реально важны
Для PostgreSQL «опасные» места по диску:
- WAL: интенсивная последовательная запись +
fsync. Если WAL тормозит, растут задержки коммитов. - Checkpoints: периодические всплески записи грязных страниц из shared buffers.
- Autovacuum: много мелких чтений/записей, особенно при блоате и большом количестве таблиц/индексов.
- Сортировки/хэши на диск: при нехватке памяти (
work_mem) растут временные файлы и random I/O.
По паттернам это часто «смешанная» нагрузка: random reads по данным/индексам, bursts записи при checkpoint и стабильная запись WAL. Поэтому диск «для Postgres» — это тот, который держит предсказуемую latency на записи даже при одновременных random reads.
MySQL/InnoDB: типичная картина по диску
В MySQL (InnoDB) важны:
- Redo log и политика flush: влияет на частоту синхронных операций.
- Dirty pages flush: фоновые записи, конкурирующие с чтением.
- Doublewrite (в зависимости от версии/настроек): добавляет I/O к записи страниц.
- Случайные чтения индексов при недостаточном буфер-пуле.
Если упрощать: MySQL чаще «упирается» в диск в write-heavy сценариях и при маленьком innodb_buffer_pool_size, когда приходится постоянно ходить на диск за страницами.
RabbitMQ: почему «rabbitmq disk» может внезапно стать узким местом
RabbitMQ многим кажется «про сеть и CPU», но диск критичен как минимум в трёх ситуациях:
- Persisted messages: подтверждённая (durable) публикация требует записи на диск.
- Очереди, которые копят бэклог: растёт объём данных на диске и число операций записи/чтения.
- Quorum queues: требуют более строгой устойчивости, что обычно повышает требования к latency диска.
Ключевое: для RabbitMQ опасна не столько «низкая пропускная способность», сколько рост задержек записи, из-за которого включается flow control и падает throughput всей системы.
Как прикинуть sizing по IOPS без гадания
Точный sizing всегда упирается в измерения, но рабочая схема такая:
- Определите критичный путь: коммиты в БД, запись WAL/redo, durable publish в очереди.
- Снимите базовую телеметрию: средняя/95p/99p latency диска, текущие IOPS и объём (MB/s).
- Зафиксируйте целевую latency: например, 1–3 мс для «быстро», 5–10 мс для «терпимо» (но зависит от приложения и SLA).
- Оцените конкуренцию: сколько параллельных воркеров/соединений реально бьют в диск (и какие фоновые процессы добавляют нагрузку).
- Заложите запас: базы и очереди плохо переживают работу «впритык», потому что пики превращаются в очереди и лавинообразный рост latency.
Если вы выбираете диск «только по IOPS», вы почти всегда недооцениваете хвосты latency. Для пользовательского опыта важнее 95p/99p, чем среднее.
Как правильно тестировать IOPS на VDS: fio с профилями под реальность
Типичная ошибка — прогнать fio на 4K random read с большой очередью, получить красивые цифры и сделать выводы. Но для database workload важны смешанные паттерны и синхронность (или близкая к ней модель).
Ниже несколько профилей, которые ближе к реальности. Запускайте их на отдельном тестовом файле, в период минимальной нагрузки. Учтите: тесты могут серьёзно грузить диск.
1) Random read 4K (проверка «потолка» по чтению)
fio --name=randread4k --filename=/var/tmp/fio.test --size=4G --rw=randread --bs=4k --iodepth=32 --numjobs=4 --direct=1 --time_based=1 --runtime=60 --group_reporting
2) Random write 4K с sync-подобным поведением (условно «дорогая запись»)
fio --name=randwrite4k_sync --filename=/var/tmp/fio.test --size=4G --rw=randwrite --bs=4k --iodepth=1 --numjobs=4 --direct=1 --fdatasync=1 --time_based=1 --runtime=60 --group_reporting
Почему iodepth=1: синхронные коммиты часто упираются в latency каждой операции, а не в «ширину трубы».
3) Mixed 70/30 (read/write) 16K — приближение к «смешанному» приложению
fio --name=randrw16k_70r30w --filename=/var/tmp/fio.test --size=8G --rw=randrw --rwmixread=70 --bs=16k --iodepth=16 --numjobs=4 --direct=1 --time_based=1 --runtime=120 --group_reporting
Что смотреть в выводе fio
- clat (completion latency) и особенно 95p/99p: хвосты почти всегда важнее среднего.
- IOPS отдельно для read и write: смешанные профили могут маскировать перекос.
- bw: чтобы понимать, не упёрлись ли вы в throughput вместо IOPS (или наоборот).

Симптомы «упора в IOPS/latency» в проде
Даже без синтетики узкое место по диску обычно проявляется типично:
- растёт время ответа БД, но CPU не загружен;
- в
iostatрастутawaitи загрузка устройства, увеличивается очередь; - в приложении появляются волны таймаутов (не ровная деградация, а «качели»);
- RabbitMQ включает flow control и падает скорость публикации/потребления;
- в PostgreSQL заметны пики на checkpoint/autovacuum, в MySQL — на flush/redo.
Практические советы: как снизить требования к диску без потери надёжности
Не всегда нужно «покупать больше IOPS». Часто выигрыш даёт архитектура и настройки:
- Держите горячие данные в памяти: корректные размеры буферов БД и кэшей уменьшают random reads.
- Разделяйте роли диска: лог/очередь/данные на разные тома (если доступно) уменьшают конкуренцию паттернов.
- Следите за блоатом и вакуумом: «лишние» страницы — это прямые лишние IOPS.
- Не допускайте свопинга: память, вытесненная на диск, превращает любую систему в I/O-ад.
- Проверяйте политику fsync: отключать надёжность ради цифр в тесте — плохая сделка; лучше подобрать диск и параметры под SLA.
Короткий чек-лист при выборе VDS под I/O
- Понимайте свой workload: read/write, random/sequential, sync/async.
- Сравнивайте не только IOPS, но и latency на 95p/99p под смешанной нагрузкой.
- Учитывайте размер блока: 4K для «мелких операций», 16K/32K для типичных страниц/батчей.
- Для БД и очередей чаще выигрывает NVMe из-за низкой и стабильной latency.
- Закладывайте запас по диску: пики и фоновые задачи (checkpoint, vacuum, flush) неизбежны.
Итоги
IOPS — полезная метрика, но только вместе с размером блока, глубиной очереди и задержками. Для VDS ключевой критерий storage performance в реальной жизни — стабильная latency на записи и предсказуемое поведение под смешанными I/O patterns. Если вы выбираете сервер под PostgreSQL, MySQL или RabbitMQ, ориентируйтесь на профили нагрузки и тестируйте так, как работает ваш сервис — тогда sizing будет обоснованным, а не «по рекламной цифре».


