Что такое очередь запросов диска и почему она важна
Очередь запросов (I/O queue depth) — это количество операций чтения и записи, которые диск обрабатывает одновременно. У жёсткого диска физическая очередь ограничена скоростью механики, у SATA SSD — протоколом AHCI (глубина очереди до 32), у NVMe — самим протоколом NVMe, который поддерживает до 65535 очередей по 65536 команд в каждой. Именно поэтому NVMe-диски держат высокую нагрузку заметно стабильнее SATA при одинаковом числе IOPS.
Когда очередь на диске растёт быстрее, чем он успевает её обрабатывать, время ответа на каждый следующий запрос увеличивается — это и есть рост латентности под нагрузкой, а не снижение "скорости" в привычном смысле.
IOPS и латентность: в чём разница и как их считать
IOPS (input/output operations per second) — это количество операций в секунду. Латентность — время выполнения одной операции, в миллисекундах или микросекундах. Эти две метрики связаны через очередь: приблизительно IOPS = глубина очереди / средняя латентность одной операции.
Для HDD типичная латентность случайного чтения — 5-10 мс, для SATA SSD — 0,1-0,2 мс, для NVMe — 0,02-0,05 мс. Разница в 100-200 раз между HDD и NVMe значит, что при одинаковой глубине очереди NVMe даёт в сотни раз больше IOPS на случайных операциях, хотя на последовательном чтении крупными блоками разница уже не так велика.
Как измерить очередь и задержку в реальном времени
Базовый инструмент — iostat из пакета sysstat:
iostat -x 1 5
В выводе важны три колонки: avgqu-sz (или aqu-sz в новых версиях) — средняя глубина очереди, await — среднее время ожидания запроса в миллисекундах, %util — доля времени, когда диск был занят обработкой запросов. Если %util держится у 100%, а await растёт — диск стал узким местом системы, и дальше нужно смотреть, что именно его нагружает.
Процесс, который создаёт наибольшую нагрузку на диск, находят через:
iotop -o
fio: синтетический тест под профиль реальной нагрузки
Чтобы проверить диск не абстрактно, а под конкретный сценарий, используют fio с параметрами, близкими к реальной нагрузке. Для базы данных с большим числом мелких случайных операций:
fio --name=randread --filename=/dev/nvme0n1 --rw=randread \
--bs=4k --iodepth=32 --numjobs=4 --runtime=60 --time_based \
--group_reporting
Для последовательной записи большими блоками, как при бэкапе или логировании:
fio --name=seqwrite --filename=/data/testfile --rw=write \
--bs=1M --size=10G --iodepth=8 --runtime=60 --time_based
В отчёте fio смотрят на clat (completion latency) в процентилях — среднее значение маскирует редкие, но болезненные задержки на 99-м перцентиле, которые как раз и ощущают пользователи как подвисания.
NVMe против SATA: разница в глубине очереди на практике
| Параметр | SATA SSD (AHCI) | NVMe |
|---|---|---|
| Макс. глубина очереди | 32 | 65536 на очередь |
| Число очередей | 1 | до 65535 |
| Латентность случайного чтения | 0,1-0,2 мс | 0,02-0,05 мс |
На практике разница ощущается сильнее всего в многопоточных нагрузках — базы данных, виртуализация с десятками ВМ на одном хосте, очереди сообщений. Для одиночного диска под сервер базы данных NVMe почти всегда предпочтительнее SATA SSD именно из-за глубины очереди, а не только из-за более высокой линейной скорости.
Чек-лист диагностики проблем с диском
%utilв iostat стабильно около 100% — диск действительно упёрся в предел, а не есть проблема в другом месте.awaitрастёт быстрее, чем растёт нагрузка — очередь не успевает разгружаться, стоит проверить RAID-контроллер и режим кеширования.- Тест fio проведён с параметрами, близкими к реальному профилю (размер блока, iodepth, доля чтения/записи), а не с настройками по умолчанию.
- Сравнение с паспортными IOPS диска показывает разрыв больше, чем 20-30% — стоит проверить выравнивание разделов и режим TRIM.
- Для критичных БД и высоконагруженных сервисов очередь и латентность проверены на профиле уровня RAID (RAID 10 из нескольких дисков), а не на одиночном накопителе.
Замер очереди и латентности до запуска сервиса в продакшн экономит часы разбора инцидентов позже: большинство жалоб на "тормозящий сервер" на деле сводится к диску, который упёрся в предел своей очереди.