Анализ возможности изменения размера буферов для операций с блочными устройствами
Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).
В современных вычислительных системах операции ввода-вывода (I/O) часто становятся узким местом, ограничивающим общую производительность. Одним из ключевых параметров, влияющих на эффективность работы с дисковыми накопителями, является размер буфера предварительного чтения (read-ahead). Этот параметр определяет, сколько данных система заранее считывает с диска в память в ожидании последующих запросов. Хотя увеличение этого буфера может ускорить последовательные операции чтения, его неоптимальное значение способно привести к обратному эффекту — избыточной нагрузке на подсистему хранения, бесполезному расходованию пропускной способности и кэш-памяти.
В данной статье на реальном примере разбирается кейс анализа производительности блочного устройства vdd в Linux-системе, где наблюдалась 100% утилизация диска и высокие задержки. Мы детально исследуем метрики ввода-вывода, корреляции между ними и оценим целесообразность изменения параметра read_ahead_kb с текущего значения 4096 КБ. Материал будет полезен системным администраторам, DevOps-инженерам и всем, кто стремится глубже понять тонкости настройки ОС для максимизации отдачи от дисковой подсистемы.
Текущее значение
# cat /sys/block/vdd/queue/read_ahead_kb
4096
На основе анализа производительности IO для устройства vdd можно сделать следующие выводы и рекомендации:
Текущая ситуация с устройством vdd:
Утилизация диска (%util): постоянно 100% в течение всего периода наблюдения.
Задержки записи (w_await): в 94,55% наблюдений превышают 5 мс (ALARM).
Глубина очереди (aqu_sz): постоянно >1 (ALARM).
Соотношение чтения/записи: 3,36:1 (OLAP-сценарий, много операций чтения).
Средний размер запроса:
Чтение (rareq_sz): ~9–10 КБ
Запись (wareq_sz): ~10–11 КБКорреляция speed – IOPS: отрицательная (–0,7013), что указывает на не-IO-ограниченную систему (проблемы могут быть в CPU, блокировках, памяти).
Корреляция cache – r/s: отрицательная (–0,6421), что говорит об эффективности кэширования.
Параметр read_ahead_kb: текущее значение = 4096 (4 МБ).
Анализ целесообразности изменения read_ahead_kb:
✅ Аргументы за уменьшение значения:
Средний размер запроса на чтение всего ~10 КБ, а предзагрузка установлена на 4 МБ — это избыточно и может приводить к:
Чтению лишних данных, которые не используются.
Нагрузке на IO-подсистему без реальной пользы.
Заполнению кэша ненужными данными, вытесняя полезные.Высокая утилизация диска (100%) и большая глубина очереди указывают на то, что диск перегружен. Уменьшение read_ahead_kb может снизить избыточную нагрузку.
OLAP-сценарий (много чтения) — в таких случаях слишком большой read-ahead может мешать, если запросы случайные или не последовательные.
⚠️ Аргументы против уменьшения:
Если нагрузка в основном последовательное чтение больших файлов (например, обработка логов, дампов), то большой read-ahead может быть полезен.
Резкое уменьшение может увеличить количество IOPS, что при уже высокой утилизации может ухудшить ситуацию.
Рекомендация:
Изменить read_ahead_kb с 4096 на 128–256 КБ (например, 256 КБ), так как:
Средний размер запроса ~10 КБ.
Это уменьшит избыточное чтение, но сохранит преимущества предзагрузки для последовательных операций.
Наблюдать за изменениями в r/s, r_await, %util, aqu_sz.
Команда для изменения:
echo 256 > /sys/block/vdd/queue/read_ahead_kb
Мониторинг после изменения:
Сравнить r/s, rMB/s, r_await, %util до и после.
Проверить, не увеличилась ли глубина очереди (aqu_sz).
Оценить влияние на общую производительность (например, через vmstat, iostat).
Дополнительные рекомендации:
Исследовать другие узкие места: так как система не ограничена IO, стоит проверить:
CPU (wa > 10% — ALARM).
Память (использование кэша и буферов).
Процессы в D состоянии (ожидание IO).Оптимизировать запросы к СУБД:
Увеличить shared_buffers (если PostgreSQL).
Проверить наличие полных сканирований больших таблиц.Рассмотреть возможность увеличения IOPS/пропускной способности диска (если это облачный диск — изменить тип на более производительный).
Заключение:
Изменение read_ahead_kb с 4096 на 256 КБ целесообразно, но должно проводиться осторожно, с мониторингом. Это может снизить избыточную нагрузку на диск, но не решит основную проблему — 100% утилизацию диска, которая требует более комплексного подхода (апгрейд диска, оптимизация запросов, увеличение кэша).

Postgres DBA
284 поста64 подписчика
Правила сообщества
Пока действуют стандартные правила Пикабу.