Нейросеть рисует и пишет
20 постов
20 постов
16 постов
111 постов
40 постов
192 поста
114 постов
21 пост
В силу ограниченности платформы Пикабу - статья сокращена. Полностью - на основном канале Дзен.
PG_EXPECTO — это не просто инструмент, а целостный комплекс, построенный на двух новых принципах.
1. Комплексный статистический анализ (CSSA)
Система больше не разделяет метрики СУБД и инфраструктуры. Она создаёт единый корреляционный снимок всей системы:
Вертикальная корреляция: Вместо отдельных событий система видит цепочки: например, как медленный запрос вызывает рост очереди дисковых операций (iowait).
Проактивность: Комплекс отслеживает не сбои, а тренды. Он может предупредить: «Обнаружена устойчивая тенденция к деградации из-за X», позволяя устранить проблему до того, как она затронет пользователей.
2. Семантический анализ и нейросеть-ассистент
Это и есть та самая «турбина». Вместо сырых графиков PG_EXPECTO использует нейросеть, которая интерпретирует данные в контексте.
1. Производительность и ожидания СУБД
2. Метрика vmstat
3.Метрика iostat для дискового устройства, файловой системы /data
3.Метрика iostat для дискового устройства, файловой системы /wal
Проведи анализ производительности и ожиданий СУБД PostgreSQL за заданный период
На основе предоставленных данных можно провести следующий анализ производительности и ожиданий СУБД PostgreSQL за период с 08:40 до 09:40:
· Операционная скорость (SPEED):
o Коэффициент детерминации R2=0.88R2=0.88 → модель хорошо описывает данные.
o Угол наклона = -43.1 → скорость со временем снижается.
· Ожидания СУБД (WAITINGS):
o R2=0.75R2=0.75 → модель умеренно точна.
o Угол наклона = +40.87 → количество ожиданий растёт.
· SPEED vs WAITINGS: −0.763→ сильная отрицательная корреляция. Чем больше ожиданий, тем ниже скорость.
· WAITINGS vs IPC: 0.9039 → очень сильная положительная корреляция. Рост межпроцессного взаимодействия связан с ростом ожиданий.
· WAITINGS vs LWLOCK: 0.9587 → почти прямая зависимость. Ожидания сильно связаны с лёгкими блокировками (lightweight locks).
· SPEED:
o Начало: ~130 572
o Конец: ~90 948
o Снижение на ~30% за час.
· WAITINGS:
o Начало: 345
o Конец: 435
o Рост на ~26%.
· IPC и LWLOCK также растут, особенно заметно после 09:30.
1. Рост LWLOCK → возможна конкуренция за лёгкие блокировки (например, в памяти).
2. Рост IPC → увеличивается нагрузка на межпроцессное взаимодействие, возможно из-за параллельных запросов.
3. Падение SPEED при росте WAITINGS → система тратит больше времени на ожидания (возможно, из-за блокировок или нехватки ресурсов).
Проведи анализ метрик vmstat за заданный период
На основе данных vmstat за период с 08:40 до 09:40 проведён анализ производительности системы, на которой работает PostgreSQL. Вот ключевые выводы:
· Время простоя CPU (idle) снизилось с 90% до 85%.
· Пользовательская нагрузка CPU (us) выросла с 9% до 13%.
· Системная нагрузка CPU (sy) стабильна (2%).
· Ожиданий ввода-вывода (wa) не наблюдается (0%).
Показатель Начало Конец Изменение Комментарий
swpd 710МБ 749МБ +39 МБ Незначительный рост свопа, система не испытывает нехватки RAM.
free 7185МБ 3221МБ -3964 МБ Сильное снижение свободной памяти, что говорит о её активном использовании.
cache 53521МБ 55937МБ +2416МБ Кэш памяти увеличивается, что нормально при активной работе с диском.
Вывод: Память активно используется, но свопинг минимален — система работает в рамках доступной памяти.
Показатель Начало Конец Пиковое значение Тренд
bi (блоков ввода/с) 572 2409 2409 Резкий рост после 09:25.
bo (блоков вывода/с) 850 511 850 Снижение, затем стабилизация.
Вывод:
· После 09:25 резко выросла активность чтения с диска (bi).
· Это совпадает с падением SPEED в данных PostgreSQL.
· Возможно, это связано с увеличением количества запросов к данным, не помещающихся в кэш.
Показатель Начало Конец Изменение
in (прерываний/с) 12833 14503 +13%
cs (переключений контекста/с) 6835 7033 +3%
Вывод: Умеренный рост прерываний и переключений контекста, что соответствует увеличению нагрузки.
Сравнивая с предыдущим анализом cluster.txt, наблюдаем:
1. Рост ожиданий (WAITINGS) в PostgreSQL коррелирует с:
o Ростом bi (чтение с диска).
o Увеличением us (пользовательская нагрузка CPU).
2. Падение SPEED совпадает с:
o Увеличением bi (дисковые операции).
o Снижением idle CPU.
1. Дисковый ввод-вывод: резкий рост bi после 09:25 может быть причиной замедления.
2. Использование памяти: свободная память уменьшается, но свопинг незначителен — пока критично.
3. Нагрузка на CPU: idle снижается, но не до критических значений.
1. Оптимизация запросов:
o Увеличить shared_buffers, чтобы больше данных кэшировалось в памяти.
o Проверить наличие медленных запросов, выполняющих полное сканирование таблиц.
2. Мониторинг диска:
o Проверить скорость дисковых операций (например, с помощью iostat).
o Рассмотреть использование SSD или увеличение скорости дискового массива.
3. Настройка PostgreSQL:
o Увеличить effective_cache_size.
o Настроить work_mem для уменьшения операций на диске.
4. Системные настройки:
o Убедиться, что достаточно оперативной памяти для кэширования.
o Рассмотреть увеличение количества CPU, если нагрузка продолжит расти.
· График SPEED и bi на одной оси времени → проверить корреляцию.
· График WAITINGS и us (пользовательская нагрузка CPU).
· График free memory и cache → отследить использование памяти.
Отрицательная корреляция: Рост значений bi сопровождается снижением операционной скорости.
Положительная корреляция: Рост значений us сопровождается увеличением количества ожиданий.
Отрицательная корреляция: Рост значений free сопровождается снижением значений cache.
free -3964 МБ: Сильное снижение свободной памяти, что говорит о её активном использовании.
cache +2416 МБ: Кэш памяти увеличивается, что нормально при активной работе с диском.
На основе данных iostat для устройства vdb за период с 08:40 до 09:40 проведён анализ дисковых операций. Вот ключевые выводы:
· Устройство vdb используется для операций чтения и записи.
· %util (загрузка диска) выросла с 5.59% до 6.7% — загрузка низкая.
· aqu_sz (средняя длина очереди) незначительно снизилась с 0.26 до 0.20 — очереди практически нет.
Показатель Начало Конец Изменение Комментарий
r/s (чтений/с) 40.00 27.92 -30% Снижение количества операций чтения.
rMB/s (МБ/с) 0.84 2.82 +235% Резкий рост объёма читаемых данных.
rareq_sz (средний размер запроса) 19.35 КБ 67.09 КБ +247% Запросы стали крупнее.
r_await (среднее время чтения, мс) 2.07 3.73 +80% Увеличение времени отклика на чтение.
Вывод:
После 09:20 резко вырос объём читаемых данных (rMB/s) и средний размер запроса (rareq_sz). Это говорит о переходе на более крупные блоки данных, возможно из-за изменения типа запросов (например, сканирование больших таблиц).
Показатель Начало Конец Изменение
w/s (записей/с) 16.83 15.20 -10%
wMB/s (МБ/с) 0.62 0.26 -58%
wareq_sz (средний размер записи) 31.74КБ 4.22КБ -87%
w_await (среднее время записи, мс) 5.57 3.59 -36%
Вывод:
Нагрузка на запись снижается, операции становятся мельче и быстрее.
· После 09:20 наблюдается рост r_await (время чтения) и WAITINGS (ожидания в СУБД).
· Рост rMB/s совпадает с ростом WAITINGS и падением SPEED.
· Это подтверждает гипотезу о том, что увеличение времени доступа к диску влияет на производительность БД.
1. Увеличение времени чтения (r_await): с 2 мс до 3.7 мс — рост на 80%.
2. Увеличение размера запросов (rareq_sz): с 19 КБ до 67 КБ — возможно, из-за отсутствия индексов или полного сканирования таблиц.
3. Рост объёма читаемых данных (rMB/s): в 3 раза — нагрузка на диск возросла.
1. Оптимизация запросов PostgreSQL:
o Проверить выполнение планов запросов (EXPLAIN ANALYZE).
o Добавить индексы для часто сканируемых таблиц.
o Увеличить shared_buffers, чтобы больше данных кэшировалось в памяти.
2. Мониторинг диска:
o Проверить скорость диска (например, с помощью hdparm или fio).
o Убедиться, что диск не фрагментирован.
3. Настройка PostgreSQL:
o Увеличить effective_cache_size.
o Настроить random_page_cost и seq_page_cost в соответствии с типом диска.
4. Аппаратные улучшения:
o Рассмотреть переход на SSD, если используется HDD.
o Увеличить скорость дисковой подсистемы (RAID, кэширование).
· График rMB/s и WAITINGS на одной оси времени.
· График r_await и rareq_sz.
· График %util и aqu_sz для оценки загрузки диска.
Увеличение rMB/s сопровождается ростом количества ожиданий.
Основная причина деградации производительности — рост размера и времени выполнения дисковых операций чтения, что приводит к увеличению лёгких блокировок (LWLOCK) и ожиданий (WAITINGS) в СУБД.
1. Оптимизация запросов и индексов
2. Настройка параметров PostgreSQL (память, I/O)
3. Аппаратное улучшение дисковых подсистем
4. Мониторинг и алертинг ключевых метрик
Система не испытывает критической нехватки CPU или памяти, но дисковый ввод-вывод стал узким местом из-за изменившегося характера нагрузки (крупные запросы на чтение).
Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).
Часто при замедлении работы базы данных первым решением кажется увеличение вычислительных ресурсов: больше ядер, памяти, быстрые диски. Однако существует и другой, более экономичный путь — заглянуть глубже, на уровень операционной системы, управляющей этими ресурсами.
Данная статья — это практический разбор реального кейса, где скрупулёзная настройка параметров подсистемы ввода-вывода, кэширования и планировщика задач Linux позволила поднять производительность PostgreSQL на впечатляющие 65%. Без замены железа, без увеличения лицензий, только за счёт грамотной оптимизации «фундамента», на котором работает СУБД. Мы пройдём по всем ключевым экспериментам, от базовых значений до финального результата, и покажем, какие именно настройки стали решающими в этой «бесплатной» победе над latency.
СУБД: PostgreSQL 17
Инструмент нагрузочного тестирования: pg_expecto
Тестовая база данных: pgbench (10GB, простая структура)
Условия тестирования: параллельная нагрузка от 5 до 22 сессий по каждому тестовому сценарию.
Общие параметры производительности:
vm.dirty_ratio = 30
vm.dirty_background_ratio = 10
Параметры IO-планировщика:
[none] mq-deadline kyber bfq
Настройки кэширования и буферизации:
vm.vfs_cache_pressure = 100
Параметры файловой системы:
/dev/mapper/vg_data-LG_data on /data type ext4 (rw,relatime)
Размер буферов для операций с блочными устройствами
read_ahead_kb=4096
vm.dirty_ratio=10
vm.dirty_background_ratio=5
[mq-deadline] kyber bfq none
vm.vfs_cache_pressure=50
/dev/mapper/vg_data-LG_data on /data type ext4 (rw,noatime,nodiratime)
echo 256 > /sys/block/vdd/queue/read_ahead_kb
Сравнительный график изменения операционной скорости в ходе нагрузочного тестирования для Эксперимента-8(SPEED-8) и базовыми значениями параметров IO для Эксперимента-1(SPEED-1)
Среднее увеличение операционной скорости в результате применения изменений подсистемы IO по сравнению с базовыми значениями составило 65.09%.
Систематическая оптимизация параметров подсистемы IO — таких как настройки кэширования, планировщика операций ввода-вывода и параметров файловой системы — позволила достичь значительного повышения производительности PostgreSQL.
Суммарный эффект от внесённых изменений выразился в среднем увеличении операционной скорости на 65,09% по сравнению с базовой конфигурацией. Наиболее существенный вклад внесли корректировки размера буферов предварительного чтения (read_ahead_kb) и отключение избыточного обновления временных меток файлов (noatime, nodiratime).
Результаты подтверждают - целенаправленная настройка окружения ОС является критически важным этапом развёртывания высоконагруженных СУБД.
Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).
В мире оптимизации СУБД иногда меньше означает больше. Вопреки стандартным рекомендациям об увеличении буферов, эксперимент показал, что осознанное уменьшение размера read_ahead_kb с 4 МБ до 256 КБ привело к росту общей производительности PostgreSQL на 7%. Это напоминание о том, что каждая система уникальна, а оптимизация требует тонкой настройки под реальную нагрузку.
Read_ahead_kb — параметр, который определяет максимальное количество килобайт, которые операционная система может прочитать заранее во время последовательной операции чтения.
В результате вероятно необходимая информация уже присутствует в кэше страниц ядра для следующего последовательного чтения, что улучшает производительность ввода-вывода.
По умолчанию значение параметра — 128 КБ для каждого сопоставляемого устройства. Однако увеличение значения read_ahead_kb до 4–8 МБ может улучшить производительность в средах приложений, где происходит последовательное чтение больших файлов
cat /sys/block/vdd/queue/read_ahead_kb
# cat /sys/block/vdd/queue/read_ahead_kb
4096
echo 256 > /sys/block/vdd/queue/read_ahead_kb
Увеличение предварительного чтения может улучшить производительность последовательных операций чтения.
Улучшение rMB/s для последовательных рабочих нагрузок.
Период анализа: 2026-01-07 10:50 - 2026-01-07 12:39 (109 минут)
Основные устройства хранения:
vdd (vg_data-LG_data): 100ГБ, смонтирован в /data - основной диск данных
vdc (vg_wal-LG_wal): 50ГБ, смонтирован в /wal - диск для WAL
vdb (vg_log-LG_log): 30ГБ, смонтирован в /log
vda: системный диск с разделами ОС
Тип нагрузки: Смешанная нагрузка с признаками как OLTP, так и OLAP
Для vdd: OLAP-сценарий (соотношение чтение/запись = 3.33:1)
Для vdc: OLTP-паттерн (высокая корреляция speed-IOPS)
ALARM: Загрузка устройства 100% во всех 110 наблюдениях
ALARM: Высокое время отклика на запись - 94.55% наблюдений превышают 5мс
ALARM: Постоянно высокая длина очереди - 100% наблюдений с aqu_sz > 1 (до 35)
ALARM: Высокий процент ожидания CPU IO (wa) - 100% наблюдений с wa > 10%
ALARM: Процессы в uninterruptible sleep возрастают при высоком wa
ALARM: Загрузка устройства >50% - 100% наблюдений (50-66%)
WARNING: Высокая корреляция wa-util (0.5115) - процессы ждут диск
ALARM: Очень высокая корреляция cache-w/s (0.7635) - неэффективное использование памяти
Отрицательная корреляция memory cache - r/s (-0.8040) и cache - rMB/s (-0.8465)
Память неэффективно используется для снижения нагрузки на диск
Отрицательная корреляция speed-IOPS (-0.2205) и speed-MB/s (-0.8862)
Производительность не ограничена IOPS или пропускной способностью
Узкое место в CPU, блокировках или параметрах параллелизма
Высокая положительная корреляция speed-IOPS (0.7764)
Классический OLTP-паттерн, производительность зависит от способности диска обрабатывать мелкие операции
Отрицательная корреляция speed-MB/s (-0.6110)
Проблема не в пропускной способности диска
r_await(ms): 2-5 мс (в пределах нормы)
w_await(ms): 4-16 мс (критически высоко, 94.55% > 5мс)
aqu_sz: 10-35 (критически высоко, всегда > 1)
proc_b: 5-13 процессов в uninterruptible sleep
cpu_wa(%): 39-45% (критически высоко)
Корреляция speed-IOPS: -0.2205 (отрицательная)
Корреляция speed-MB/s: -0.8862 (сильно отрицательная)
r_await(ms): 0 мс (нет операций чтения)
w_await(ms): 0.56-0.62 мс (в норме)
aqu_sz: 0.6-0.71 (в норме)
proc_b: 5-13 процессов в uninterruptible sleep
cpu_wa(%): 39-45% (критически высоко)
Корреляция speed-IOPS: 0.7764 (сильно положительная)
Корреляция speed-MB/s: -0.6110 (отрицательная)
vdd является основным узким местом - 100% загрузка, длинные очереди, высокое время отклика записи
Высокий cpu_wa на обоих устройствах указывает на системную проблему с IO
Разные паттерны нагрузки на vdd (OLAP) и vdc (OLTP) требуют разных подходов к оптимизации
Память используется неэффективно для кэширования, особенно на vdd
Текущее состояние: Критическое. Система испытывает серьезные проблемы с производительностью IO, особенно на основном диске данных (vdd).
Основные проблемы:
Диск vdd постоянно загружен на 100% с длинными очередями запросов
Высокое время отклика на операции записи (до 16мс)
Неэффективное использование оперативной памяти для кэширования
Значительные простои CPU из-за ожидания IO (wa 39-45%)
Прогноз: Без вмешательства производительность будет деградировать при росте нагрузки, возможны отказы служб из-за таймаутов IO.
Приоритет действий: Высокий. Рекомендуется начать с немедленных оптимизаций настроек СУБД и мониторинга, затем перейти к апгрейду инфраструктуры.
Сравнительный график изменения операционной скорости в ходе нагрузочного тестирования для Эксперимента-7(SPEED-7) и Эксперимента-8(SPEED-8)
Среднее увеличение операционной скорости в ходе Эсперимента-8 по сравнению с Экпериментом-7 составило 7.79%.⬆️
Сравнительный график изменения ожидания СУБД в ходе нагрузочного тестирования для Эксперимента-7(WAITINGS-7) и Эксперимента-8(WAITINGS-8)
Сравнительный график изменения количества IOPS в ходе нагрузочного тестирования для Эксперимента-7(IOPS-7) и Эксперимента-8(IOPS-8)
Сравнительный график изменения MB/s в ходе нагрузочного тестирования для Эксперимента-7(MB/s-7) и Эксперимента-8(MB/s-8)
Сравнительный график изменения длины очереди в ходе нагрузочного тестирования для Эксперимента-7(aqu_sz-7) и Эксперимента-8(aqu_sz-8)
Сравнительный график изменения r_await(ms) в ходе нагрузочного тестирования для Эксперимента-7(r_await(ms)-7) и Эксперимента-8(r_await(ms)-8)
Сравнительный график изменения w_await(ms) в ходе нагрузочного тестирования для Эксперимента-7(w_await(ms)-7) и Эксперимента-8(w_await(ms)-8)
Вывод: Оба эксперимента показывают, что узкое место не в подсистеме IO, а в других компонентах системы (CPU, блокировки, СУБД).
Эксп. 7: 2–5 мс, стабильно низкий.
Эксп. 8: 2–5 мс, стабильно низкий.
Вывод: Задержки чтения в норме, проблем нет.
Эксп. 7: 4–16 мс, есть рост в конце.
Эксп. 8: 4–16 мс, стабилен.
Вывод: Задержки записи также в допустимых пределах.
Эксп. 7: 10–31, растёт к концу.
Эксп. 8: 10–35, также рост к концу.
Вывод: Очереди увеличиваются, что может указывать на рост нагрузки или блокировок.
Эксп. 7: 4–13, умеренный рост.
Эксп. 8: 5–13, стабильно.
Вывод: Количество процессов в ожидании IO не критично.
Эксп. 7: 39–47%, высокий уровень.
Эксп. 8: 39–45%, также высокий.
Вывод: Высокий cpu_wa указывает на то, что CPU часто простаивает в ожидании IO или других ресурсов.
Отрицательная в обоих случаях, но в эксп. 7 — сильнее.
Это подтверждает, что производительность не зависит от IOPS.
Отрицательная, особенно сильная в эксп. 8.
Пропускная способность диска не является ограничением.
Utilization: 100% в обоих экспериментах, но это не означает перегрузку IO, так как задержки низкие.
Shared блоки: активный рост в обоих случаях, что характерно для OLTP-нагрузки.
Время чтения/записи shared блоков: растёт, особенно в эксп. 8.
IO не является узким местом ни в одном из экспериментов.
Проблемы связаны с CPU, блокировками, ожиданиями СУБД.
Рост очередей (aqu_sz) и времени ожидания CPU указывают на проблемы с параллелизмом или блокировками в СУБД.
Оба эксперимента подтверждают отсутствие IO-ограничений.
Задержки чтения/записи низкие, пропускная способность не влияет на производительность.
Эксперимент 8 показывает лучшую оптимизацию параметров IO, что выражается в более стабильных метриках r_await и w_await, а также в снижении влияния IOPS на скорость.
Основные проблемы остаются неизменными:
Высокий cpu_wa указывает на неэффективное использование CPU.
Рост aqu_sz и proc_b говорит о возможных блокировках или недостатке параллелизма.
Рекомендуется фокус на оптимизацию СУБД, настройку параллелизма и устранение блокировок.
Рекомендации:
Провести анализ ожиданий в СУБД (locks, latches, waits).
Настроить параметры параллелизма (если используется PostgreSQL — max_connections, work_mem, shared_buffers и т.д.).
Рассмотреть возможность увеличения CPU или оптимизации запросов.
Заключение: Эксперимент 8 демонстрирует улучшение в части управления IO, но системные проблемы (CPU, блокировки) остаются. Для дальнейшего повышения производительности необходимо сосредоточиться на оптимизации работы СУБД и устранении узких мест, не связанных с IO.
Взято с основного технического канала 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 можно сделать следующие выводы и рекомендации:
Утилизация диска (%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 МБ).
Средний размер запроса на чтение всего ~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 (возможны правки в исходной статье).
Производительность PostgreSQL в высокой степени зависит от корректной работы с памятью. Ядро Linux, управляя дисковым кэшем и буферами, может как значительно ускорить работу СУБД, так и стать причиной серьёзных проблем — от излишнего свопинга до деградации производительности из-за двойного кэширования. В статье предоставлены практические инструкции по настройке ключевых параметров ядра (vm.swappiness, vm.dirty_*, vm.vfs_cache_pressure) для оптимальной работы PostgreSQL.
Характер нагрузки на СУБД: преобладание чтения над записью
RAM = 8GB
shared_buffers = 2GB
# Основные параметры dirty-страниц и буферизации
echo "=== Текущие настройки кэширования ОС ==="
sudo sysctl -a | grep -E "(dirty|swappiness|vfs_cache_pressure)" | grep -v net.ipv4
# Альтернативно - чтение напрямую из /proc/sys/vm
cat /proc/sys/vm/swappiness
cat /proc/sys/vm/dirty_background_ratio
cat /proc/sys/vm/dirty_ratio
cat /proc/sys/vm/dirty_expire_centisecs
cat /proc/sys/vm/dirty_writeback_centisecs
cat /proc/sys/vm/vfs_cache_pressure
cat /sys/kernel/mm/transparent_hugepage/enabled
# Результат: [never] значит отключено, [always] - включено
# Общая статистика памяти
free -h
# Подробная информация о dirty-страницах
grep -E "(Dirty|Writeback|NFS_Unstable)" /proc/meminfo
# Динамический мониторинг (обновление каждые 2 секунды)
watch -n 2 'grep -E "(Dirty|Writeback)" /proc/meminfo && echo "---" && free -h | grep -v total'
# Установите sysstat если нет: sudo yum install sysstat / sudo apt-get install sysstat
iostat -x 2 5
# Обратите внимание на:
# - %util (загрузка диска)
# - await (среднее время ожидания)
# - avgqu-sz (средняя длина очереди)
psql -U postgres -d БД
-- Общий hit ratio для всех таблиц
SELECT
sum(heap_blks_read) as heap_read,
sum(heap_blks_hit) as heap_hit,
CASE
WHEN sum(heap_blks_hit) > 0 THEN
ROUND((sum(heap_blks_hit)::numeric / (sum(heap_blks_hit) + sum(heap_blks_read))) * 100, 2)
ELSE 0
END as heap_hit_ratio,
sum(idx_blks_read) as idx_read,
sum(idx_blks_hit) as idx_hit,
CASE
WHEN sum(idx_blks_hit) > 0 THEN
ROUND((sum(idx_blks_hit)::numeric / (sum(idx_blks_hit) + sum(idx_blks_read))) * 100, 2)
ELSE 0
END as idx_hit_ratio
FROM pg_statio_user_tables;
-- Hit ratio по базам
SELECT
datname,
blks_read,
blks_hit,
ROUND((blks_hit::numeric / (blks_hit + blks_read)) * 100, 2) as hit_ratio
FROM pg_stat_database
WHERE datname NOT LIKE 'template%';
-- Установиnm расширение если еще не установлено
CREATE EXTENSION IF NOT EXISTS pg_buffercache;
-- Топ-10 таблиц в кэше
SELECT
c.relname as table_name,
COUNT(*) * 8 / 1024 as cached_mb,
pg_size_pretty(pg_relation_size(c.oid)) as table_size,
ROUND(COUNT(*) * 100.0 / (SELECT setting::numeric FROM pg_settings WHERE name='shared_buffers'), 2) as percent_of_cache
FROM pg_buffercache b
JOIN pg_class c ON b.relfilenode = pg_relation_filenode(c.oid)
WHERE c.relkind = 'r' -- только обычные таблицы
GROUP BY c.relname, c.oid
ORDER BY cached_mb DESC
LIMIT 10;
-- Распределение shared_buffers по типам данных
SELECT
CASE
WHEN usagecount IS NULL THEN 'Free'
ELSE usagecount::text
END as usage_count,
COUNT(*) * 8 / 1024 as mb,
ROUND(COUNT(*) * 100.0 / (SELECT setting::numeric FROM pg_settings WHERE name='shared_buffers'), 2) as percent
FROM pg_buffercache
GROUP BY usagecount
ORDER BY usagecount DESC NULLS FIRST;
SELECT
datname,
temp_files,
pg_size_pretty(temp_bytes) as temp_size,
ROUND(temp_bytes / 1024.0 / 1024.0 / NULLIF(temp_files, 0), 2) as avg_file_size_mb
FROM pg_stat_database
WHERE temp_files > 0;
-- Активные запросы, использующие временные файлы
SELECT
pid,
query,
temp_files,
temp_bytes
FROM pg_stat_activity
WHERE temp_files > 0 AND state = 'active';
-- Критические настройки памяти
SELECT
name,
setting,
unit,
context
FROM pg_settings
WHERE name IN (
'shared_buffers',
'work_mem',
'maintenance_work_mem',
'effective_cache_size',
'wal_buffers',
'random_page_cost',
'effective_io_concurrency'
)
ORDER BY name;
# Создание директории для профиля
sudo mkdir -p /etc/tuned/postgresql-optimized
# Создание конфигурационного файла
sudo cat > /etc/tuned/postgresql-optimized/tuned.conf << 'EOF'
[main]
summary=Optimized for PostgreSQL with 8GB RAM, read-heavy workload
include=throughput-performance
[sysctl]
# Минимизация записи на диск (оптимизация для чтения)
vm.dirty_background_ratio = 2
vm.dirty_ratio = 5
vm.dirty_expire_centisecs = 6000
vm.dirty_writeback_centisecs = 1000
# Минимизация свопинга
vm.swappiness = 5
# Сохранение кэша dentry и inode (улучшение для частого чтения файлов)
vm.vfs_cache_pressure = 50
# Увеличение лимитов для большего количества соединений
fs.file-max = 2097152
EOF
# Активация профиля
sudo tuned-adm profile postgresql-optimized
sudo tuned-adm active # Проверка активации
# Немедленное отключение
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag
# Постоянное отключение (для систем с systemd)
sudo cat > /etc/systemd/system/disable-thp.service << 'EOF'
[Unit]
Description=Disable Transparent Huge Pages
[Service]
Type=oneshot
ExecStart=/bin/sh -c "echo never > /sys/kernel/mm/transparent_hugepage/enabled && echo never > /sys/kernel/mm/transparent_hugepage/defrag"
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable disable-thp.service
sudo systemctl start disable-thp.service
# Добавьте в /etc/security/limits.conf или создайте файл в /etc/security/limits.d/
sudo cat >> /etc/security/limits.conf << 'EOF'
postgres soft memlock 8388608 # 8GB в kB
postgres hard memlock 8388608
postgres soft nofile 65536
postgres hard nofile 65536
EOF
# Для применения в текущей сессии
sudo prlimit --pid $(pgrep -u postgres) --memlock=8388608:8388608
Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).
Noatime и nodiratime — параметры монтирования файловых систем в Linux, которые позволяют отключить обновление информации о времени доступа к файлам и каталогам.
Noatime полностью отключает запись времени доступа к файлу. Эта опция подходит, если приложения не зависят от atime. Noatime может быть полезен в разделах с интенсивным чтением, где не важна совместимость с ПО, полагающимся на atime. Например, в каталогах статического контента, кэшах, медиабиблиотеках, снапшотах сборок.
Nodiratime отключает обновление времени доступа только для каталогов. Для остальных файлов время atime будет обновляться всегда. Отдельный nodiratime актуален только при желании тонко выключить обновление atime для каталогов, оставив его для файлов (редкий случай).
# Текущее состояние
mount | grep/data
# Получить UUID устройства
blkid /dev/mapper/vg_data-LG_data
cp /etc/fstab /etc/fstab.backup_$(date +%Y%m%d)
vi /etc/fstab
добавить
# /data
/dev/mapper/vg_data-LG_data /data ext4 defaults,noatime,nodiratime 0 0
mount -o remount /data
# Проверить текущие опции монтирования
mount | grep/data
1. noatime vs relatime:
o noatime — полностью отключает обновление atime
o relatime (по умолчанию) — обновляет atime, только если mtime/ctime новее
o nodiratime — отключает atime только для директорий
2. Эффект от изменений:
o Уменьшение нагрузки на диск (меньше операций записи)
o Повышение производительности для workloads с частым чтением
o Некоторые приложения (например, backup-утилиты, использующие atime) могут работать некорректно
Период анализа: 06.01.2026 14:42 – 16:31 (около 2 часов)
Основные устройства хранения:
vdd (100 ГБ, монтирован в /data):
Используется под нагрузку чтения и записи
Наблюдается 100% утилизация (%util = 100)
Высокие показатели w_await (до 13 мс)
vdc (50 ГБ, монтирован в /wal):
Преимущественно запись
Утилизация 53–63%
Низкое время отклика на запись (~1 мс)
Другие диски: vda (система), vdb (лог)
Тип нагрузки: OLAP-сценарий с преобладанием операций чтения над записью (соотношение ~3.36:1). Нагрузка не ограничена пропускной способностью дисков.
100% утилизация диска vdd в течение всего периода наблюдения.
Высокое время отклика на запись (w_await) на vdd:
94.55% наблюдений превышают 5 мс
Максимум до 13 мс
Большая длина очереди (aqu_sz) на vdd:
Всегда > 1, достигает 31
Указывает на перегруженность диска
Высокий cpu_wa (I/O wait):
100% наблюдений > 10%
Процессы в состоянии uninterruptible sleep превышают количество ядер CPU в 25–50% случаев
Неэффективное использование кэша:
Высокая корреляция между cache и w/s на vdc (0.587)
Слабая корреляция буферной памяти с операциями чтения/записи
Отрицательная корреляция wa и util на vdd (-0.3019) — свидетельствует о том, что высокий wa не всегда связан с загрузкой диска.
Высокая корреляция операционной скорости с чтением блоков (0.7134) — производительность напрямую зависит от операций чтения с диска.
Низкая/отрицательная корреляция скорости с IOPS и пропускной способностью — указывает, что узкое место не в подсистеме IO.
Преобладание операций чтения (соотношение read/write = 3.36) — характерно для аналитических нагрузок.
Вывод по диагностике:
Основная проблема — высокое время отклика на запись на диске vdd и перегруженность очереди запросов. При этом общая производительность системы не ограничена пропускной способностью или IOPS, что указывает на иные узкие места: вероятно, недостаток RAM, неэффективные запросы или блокировки на уровне СУБД.
Оптимизация диска vdd:
Рассмотреть переход на более быстрые диски (SSD/NVMe)
Разделить нагрузку: выделить отдельный диск для журналов транзакций
Оптимизация памяти:
Увеличить размер буферного кэша СУБД
Настроить shared_buffers и effective_cache_size в PostgreSQL
Оптимизация запросов:
Провести анализ медленных запросов
Добавить/оптимизировать индексы для уменьшения seq scan
Использовать partitioning для больших таблиц
Настройка мониторинга:
Включить детальный мониторинг процессов в состоянии D (uninterruptible sleep)
Настроить оповещения при %util > 90% и w_await > 5 мс
Балансировка нагрузки:
Рассмотреть использование реплик для чтения
Возможно, увеличить количество ядер CPU для параллельной обработки запросов
Подсистема IO находится в критическом состоянии по следующим причинам:
Диск vdd постоянно перегружен (100% утилизация)
Высокое время отклика на запись (до 13 мс)
Длинная очередь запросов (до 31)
Высокий I/O wait процессора (до 47%)
Однако основное узкое место — не в пропускной способности дисков, а в:
Неэффективном использовании памяти (слабая кэшируемость данных)
Большом количестве операций чтения с диска из-за неоптимальных запросов
Высокой загрузке CPU в состоянии ожидания IO
Рекомендуется:
Сначала провести оптимизацию на уровне СУБД и приложения (индексы, запросы, кэширование), а затем рассмотреть апгрейд дисковой подсистемы для диска vdd.
Сравнительный график изменения операционной скорости в ходе нагрузочного тестирования для Эксперимента-5(SPEED-5) и Эксперимента-7(SPEED-7)
Среднее увеличение операционной скорости в ходе Эсперимента-7 по сравнению с Экпериментом-5 составило 7.47%.
Сравнительный график изменения ожидания СУБД в ходе нагрузочного тестирования для Эксперимента-5(WAITINGS-5) и Эксперимента-7(WAITINGS-7)
Сравнительный график изменения количества IOPS в ходе нагрузочного тестирования для Эксперимента-5(IOPS-5) и Эксперимента-7(IOPS-7)
Сравнительный график изменения MB/s в ходе нагрузочного тестирования для Эксперимента-5(MB/s-5) и Эксперимента-7(MB/s-7)
Сравнительный график изменения длины очереди в ходе нагрузочного тестирования для Эксперимента-5(aqu_sz-5) и Эксперимента-7(aqu_sz-7)
Сравнительный график изменения r_await(ms) в ходе нагрузочного тестирования для Эксперимента-5(r_await(ms)-5) и Эксперимента-7(r_await(ms)-7)
Сравнительный график изменения w_await(ms) в ходе нагрузочного тестирования для Эксперимента-5(w_await(ms)-5) и Эксперимента-7(w_await(ms)-7)
Общая проблема в обоих экспериментах: Производительность не ограничена подсистемой IO.
Основные узкие места: CPU, блокировки, параметры параллелизма, ожидания СУБД.
Статус аварийного оповещения: В обоих случаях зафиксирована отрицательная корреляция между операционной скоростью и IOPS/MB/s, что указывает на влияние не-IO факторов на производительность.
Вывод:
Оба эксперимента демонстрируют сходный паттерн нагрузки — низкая корреляция с метриками IO, что подтверждает, что производительность определяется не дисковыми операциями, а другими компонентами системы (CPU, блокировки, память).
Эксперимент-5: стабильно ~2–4 мс.
Эксперимент-7: стабильно ~2–5 мс.
Изменение: Незначительный рост в эксперименте-7, но в пределах нормы.
Эксперимент-5: 3–12 мс, плавный рост.
Эксперимент-7: 5–13 мс, более выраженный рост к концу теста.
Изменение: Увеличение задержек записи в эксперименте-7, что может указывать на влияние оптимизаций ФС на операции записи.
Эксперимент-5: 8–29.
Эксперимент-7: 13–31.
Изменение: Увеличение длины очереди в эксперименте-7, что согласуется с ростом w_await.
Эксперимент-5: 5–13.
Эксперимент-7: 4–13.
Изменение: Незначительные колебания, без явной тенденции.
Эксперимент-5: 42–47%.
Эксперимент-7: 39–47%.
Изменение: Снижение cpu_wa в эксперименте-7, что может указывать на улучшение использования CPU после оптимизации ФС.
Отрицательная в обоих случаях, сильнее в эксперименте-7. Это подтверждает, что рост IOPS не ведёт к росту производительности, проблема в других подсистемах.
Отрицательная, слабее, чем с IOPS. Пропускная способность диска не является ограничивающим фактором.
IOPS: в эксперименте-7 немного выше (до 4346 vs 4293 в эксперименте-5).
MB/s: стабильно ~39–43 MB/s в обоих экспериментах.
Utilization: 100% в обоих случаях, что говорит о полной загрузке устройства.
Эксперимент-5: Стабильные показатели IO, узкое место — CPU/блокировки.
Эксперимент-7: Ухудшение w_await и aqu_sz, но улучшение cpu_wa. Оптимизация ФС привела к увеличению задержек записи, но снизила нагрузку на CPU.
Оба эксперимента подтверждают, что узкое место — не в подсистеме IO, а в CPU, блокировках или настройках СУБД.
Эксперимент-7 (оптимизация ФС) показал:
Увеличение задержек записи (w_await) и длины очереди (aqu_sz).
Снижение времени ожидания CPU (cpu_wa).
Более сильную отрицательную корреляцию speed-IOPS, что указывает на ещё меньшую зависимость производительности от IO.
Эксперимент-5 (настройки кэширования) демонстрирует более стабильные задержки IO, но более высокую нагрузку на CPU.
Рекомендация:
Продолжить оптимизацию CPU, параллелизма и настройки СУБД.
Для экспериментов с ФС рекомендуется дополнительная настройка параметров записи для снижения w_await.
Мониторинг блокировок и contention в СУБД.
Оба эксперимента успешно идентифицировали, что производительность упирается не в IO, а в другие компоненты системы. Оптимизация файловой системы (Эксперимент-7) частично улучшила использование CPU, но ухудшила задержки записи. Это указывает на необходимость комплексной настройки системы, учитывающей как параметры ФС, так и настройки СУБД и CPU.
Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).
В рамках проекта PG_EXPECTO по всесторонней оптимизации СУБД PostgreSQL был проведён цикл экспериментов по настройке подсистемы ввода-вывода. В ходе «Эксперимента-5» фокус сместился на тонкую настройку механизмов кэширования и буферизации операционной системы. Целью было оценить, как управление памятью для метаданных файловой системы может повлиять на общую производительность дисковой подсистемы в условиях аналитической (OLAP) нагрузки, где чтение данных преобладает над записью. Результаты оказались показательными: даже одна корректировка параметра vm.vfs_cache_pressure принесла ощутимое улучшение.
Параметр в Linux, который контролирует склонность ядра к освобождению памяти, используемой для кэширования объектов VFS (Virtual File System). Влияет на баланс между кэшем страниц и кэшем метаданных файловой системы.
sysctl vm.vfs_cache_pressure
# sysctl vm.vfs_cache_pressure
vm.vfs_cache_pressure = 100
sysctl -w vm.vfs_cache_pressure=50
# sysctl -w vm.vfs_cache_pressure=50
vm.vfs_cache_pressure = 50
# sysctl vm.vfs_cache_pressure
vm.vfs_cache_pressure = 50
Уменьшает давление на кэш dentry и inode, что может улучшить кэширование файловых операций.
Улучшение эффективности кэша, снижение нагрузки на дисковые операции чтения.
Период анализа: 2026-01-06 11:36 – 2026-01-06 13:25 (около 1 часа 50 минут)
Основные устройства хранения:
vdd (100 ГБ, LVM /data) – основное устройство данных
vdc (50 ГБ, LVM /wal) – устройство для журналов
vdb (30 ГБ, LVM /log) – логи
vda (70 ГБ) – системный диск
Тип нагрузки: OLAP-сценарий с преобладанием операций чтения над записью (соотношение ~3.24:1). Нагрузка на оба диска (vdd и vdc) высокая, с признаками очередей и ожиданий.
Диск vdd перегружен:
%util = 100% на протяжении всего периода
w_await > 5 мс в 90.9% наблюдений
aqu_sz (средняя длина очереди) > 1 в 100% наблюдений
cpu_wa > 10% в 100% наблюдений
Диск vdc также показывает высокую загрузку:
%util = 51–62% (всё время выше 50%)
Запись стабильна, но загрузка высокая
Высокое соотношение чтения к записи (3.24:1) указывает на аналитическую нагрузку, требующую оптимизации кэширования и стратегий чтения.
Для vdd:
Высокая положительная корреляция buff – r/s (0.899) и buff – wMB/s (0.806) – память неэффективно снижает нагрузку на диск.
Отрицательная корреляция speed – IOPS (-0.593) – проблема не в IOPS, а в других подсистемах (CPU, блокировки).
Для vdc:
Слабая корреляция speed – IOPS (0.252) – IOPS не является узким местом.
Отрицательная корреляция speed – MB/s (-0.115) – пропускная способность не ограничивает.
Вывод: Проблема производительности связана не с пропускной способностью или IOPS, а с задержками, очередями и, возможно, с настройками СУБД или CPU.
Вывод по диагностике узких мест IO:
Основное узкое место – высокие задержки записи и большая очередь на диске vdd, что приводит к ожиданию со стороны CPU (wa высокий). Проблема усугубляется неэффективным использованием памяти для буферизации.
Оптимизация диска vdd:
Рассмотреть переход на более быстрые диски (SSD/NVMe).
Настроить параметры IO-планировщика (например, deadline или noop для SSD).
Увеличить размер очереди (nr_requests).
Оптимизация памяти и кэширования:
Увеличить shared_buffers (если это СУБД, например PostgreSQL).
Настроить vm.dirty_ratio и vm.dirty_background_ratio для более эффективной записи.
Оптимизация запросов и схемы данных:
Использовать индексы, секционирование, материализованные представления.
Пересмотреть запросы с большим количеством чтений.
Мониторинг и дальнейший анализ:
Следить за iowait, await, aqu_sz в реальном времени.
Анализировать логи СУБД на предмет медленных запросов.
Для vdc:
Мониторить утилизацию, при росте нагрузки – рассмотреть выделение более производительного диска.
Текущее состояние: Критическое.
Диск vdd является основным узким местом – постоянная 100% загрузка, высокие задержки записи, большая очередь запросов. Это приводит к простою CPU в ожидании IO и снижению общей производительности системы.
Перспективы:
При оптимизации диска vdd, настроек памяти и запросов можно ожидать значительного улучшения производительности. Диск vdc работает в допустимом режиме, но требует наблюдения.
Рекомендуемые первоочередные действия:
Апгрейд vdd на SSD.
Настройка параметров кэширования и записи в ОС и СУБД.
Анализ и оптимизация наиболее ресурсоемких запросов.
*Отчет подготовлен на основе автоматизированного анализа метрик iostat/vmstat за период 06.01.2026 11:36–13:25.*
Сравнительный график изменения операционной скорости в ходе нагрузочного тестирования для Эксперимента-3(SPEED-3) и Эксперимента-5(SPEED-5)
Среднее увеличение операционной скорости в ходе Эсперимента-5 по сравнению с Экпериментом-3 составило 30.82%.
Сравнительный график изменения ожидания СУБД в ходе нагрузочного тестирования для Эксперимента-3(WAITINGS-3) и Эксперимента-5(WAITINGS-5)
Сравнительный график изменения количества IOPS в ходе нагрузочного тестирования для Эксперимента-3(IOPS-3) и Эксперимента-5(IOPS-5
Сравнительный график изменения MB/s в ходе нагрузочного тестирования для Эксперимента-3(MB/s-3) и Эксперимента-5(MB/s-5)
Сравнительный график изменения длины очереди в ходе нагрузочного тестирования для Эксперимента-3(aqu_sz-3) и Эксперимента-5(aqu_sz-5)
Сравнительный график изменения r_await(ms) в ходе нагрузочного тестирования для Эксперимента-3(r_await(ms)-3) и Эксперимента-5(r_await(ms)-5)
Сравнительный график изменения w_await(ms) в ходе нагрузочного тестирования для Эксперимента-3(w_await(ms)-3) и Эксперимента-5(w_await(ms)-5)
Вывод: В обоих экспериментах IO-подсистема не является узким местом. Проблема производительности связана с другими компонентами системы (CPU, блокировки, память).
Вывод: Оба эксперимента демонстрируют схожий паттерн — отсутствие значимой корреляции между производительностью и метриками IO, что подтверждает гипотезу о том, что ограничение находится вне IO-подсистемы.
Наблюдение: Латентности операций чтения и записи находятся в приемлемых пределах в обоих экспериментах.
Наблюдение: Наблюдается рост длины очереди и количества заблокированных процессов, но значения не критичны.
Наблюдение: Высокий процент времени ожидания IO процессором в обоих экспериментах, что может указывать на неоптимальное взаимодействие CPU и IO.
Наблюдение: Показатели IOPS и пропускной способности сопоставимы в обоих экспериментах. Время операций с блоками демонстрирует схожую динамику роста.
IO-подсистема не является ограничивающим фактором в обоих экспериментах по следующим причинам:
Низкие латентности операций чтения/записи
Отсутствие значимых корреляций между производительностью и метриками IO
Умеренные значения длины очереди и заблокированных процессов
Схожие показатели IOPS и пропускной способности в обоих экспериментах
Консистентность результатов: Оба эксперимента демонстрируют одинаковый основной вывод — IO-подсистема не является узким местом в системе.
Эффективность оптимизаций: Эксперимент 5 (с настройками кэширования и буферизации) показал:
Незначительное улучшение latencies (особенно r_await)
Слегка сниженные значения cpu_wa
Сопоставимые основные показатели IOPS и пропускной способности
Рекомендации:
Сфокусироваться на оптимизации CPU, устранении блокировок и настройке параллелизма
Рассмотреть оптимизацию работы с памятью
Провести детальный анализ времени выполнения запросов СУБД
Настройки кэширования из эксперимента 5 можно считать успешными, но недостаточными для решения основной проблемы производительности
Общий вывод: Проблема производительности в обоих случаях связана с факторами вне IO-подсистемы. Оптимизации кэширования (эксперимент 5) дали незначительные улучшения, но не решили основную проблему, что подтверждает необходимость дальнейшего исследования CPU, блокировок и параметров параллелизма.
Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).
В мире высоконагруженных баз данных каждая миллисекунда ожидания ввода-вывода может стать узким местом всей системы. В поисках решения администраторы часто обращаются к настройке глубины очереди запросов к диску (nr_requests), надеясь одним параметром решить проблему высокой утилизации хранилища. Данный разбор на реальных метриках показывает, что вслепую увеличивать очередь не только бесполезно, но иногда и вредно. Когда диск постоянно работает на 100%, ключ к оптимизации лежит не в очереди, а в грамотном перераспределении нагрузки, стратегическом кэшировании и настройке планировщика операций ввода-вывода.
Проанализируй показатели производительности IO и текущие значения для параметра nr_requests :"# cat /sys/block/vdd/queue/nr_requests
256". Подготовь рекомендации о целесообразности изменения параметра nr_requests для оптимизации подсистемы IO.
Высокая загрузка диска:
%util = 100% постоянно
Средняя длина очереди (aqu_sz) от 11 до 29
Большое количество процессов в состоянии uninterruptible sleep (6-14 при 8 CPU)
Характер нагрузки:
Преобладание операций чтения над записью (соотношение ~3:1)
OLAP-подобный сценарий с интенсивным чтением
Высокая корреляция между объемом кэша и объемом чтения с диска
Проблемы:
Чрезмерное ожидание IO процессором (wa = 45-51%)
Глубина очереди постоянно > 1 (100% наблюдений)
Признаки недостаточной эффективности кэширования
Достаточно высокое для большинства рабочих нагрузок
НЕ является основным ограничивающим фактором при текущей нагрузке
Увеличение не решит проблему 100% утилизации
НЕ увеличивать nr_requests (256 → более высокие значения):
Текущая очередь и так переполнена (aqu_sz до 29)
Увеличение nr_requests не снизит %util = 100%
Может привести к:
Увеличению латентности отдельных запросов
Росту потребления памяти ядром
Эффекту "застревания" старых запросов
Оптимизировать параметры планировщика (scheduler):
# Для OLAP-нагрузки с преобладанием чтения
echo deadline > /sys/block/vdd/queue/scheduler
# Настройки для deadline (опционально)
echo 256 > /sys/block/vdd/queue/iosched/read_expire
echo 5000 > /sys/block/vdd/queue/iosched/write_expire
echo 8 > /sys/block/vdd/queue/iosched/fifo_batch
Увеличить readahead для последовательных чтений:
# Текущее значение обычно 128 или 256
cat /sys/block/vdd/queue/read_ahead_kb
# Увеличить для OLAP
echo 4096 > /sys/block/vdd/queue/read_ahead_kb
Приоритетные оптимизации:
Увеличить кэширование (если возможно добавить RAM)
Оптимизировать запросы БД (индексы, уменьшение seq scan)
Рассмотреть разделение нагрузки на несколько дисков
Проверить настройки ФС (noatime, nodiratime)
Экспериментальная проверка (если решили изменить nr_requests):
#Временно уменьшить для теста
echo 128 > /sys/block/vdd/queue/nr_requests
# Мониторинг эффекта
iostat -x 1
cat /proc/interrupts | grep vdd
Параметр nr_requests = 256 не является узким местом.
Проблема :
Слишком высокой нагрузке на диск (OLAP + вероятно недостаток кэша)
Возможно, недостаточной производительности самого диска для текущей нагрузки
Рекомендация:
Сфокусироваться на:
Увеличении оперативной памяти для кэширования
Оптимизации запросов к базе данных
Рассмотрении более производительного хранилища (SSD/NVMe вместо HDD)
Настройке параметров планировщика и readahead
Изменение nr_requests даст минимальный эффект и может ухудшить ситуацию при текущей 100% утилизации диска.
Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).
В мире высоконагруженных СУБД каждый компонент системы требует пристального внимания. Подсистема ввода-вывода (IO) часто становится узким местом, напрямую влияющим на отзывчивость и стабильность работы базы данных. Данный анализ фокусируется на сердце этой подсистемы — планировщике операций ввода-вывода. Мы не просто сравниваем доступные алгоритмы (mq-deadline, kyber, bfq, none), но и проводим детальную оценку их применимости в конкретных условиях: для основного хранилища данных (vdd) и диска журнала транзакций (vdc). Цель — не слепая погоня за новыми технологиями, а взвешенное, обоснованное решение, основанное на анализе нагрузки, характеристик накопителей и архитектурных особенностей PostgreSQL.
vdd (данные): [mq-deadline] kyber bfq none
vdc (журнал): [mq-deadline] kyber bfq none
Текущий выбор: mq-deadline на обоих устройствах.
Принцип работы: Гарантирует максимальное время обслуживания запросов
Приоритеты: Чтение над записью (особенно важно для СУБД)
Особенности: Использует "deadline" механизм для предотвращения голодания операций
Лучше всего для: Смешанных нагрузок, особенно с преобладанием чтения
Принцип работы: Адаптивный планировщик, оптимизированный для SSD/NVMe
Особенности: Автоматически настраивает глубину очереди на основе целевых задержек
Лучше всего для: Быстрых накопителей (SSD/NVMe) в виртуализированных средах
Принцип работы: Справедливое распределение пропускной способности между процессами
Особенности: Гарантирует пропускную способность для каждого процесса
Лучше всего для: Интерактивных и десктопных систем, многопользовательских сред
Принцип работы: Без планировщика, запросы передаются напрямую
Особенности: Минимальные накладные расходы
Лучше всего для: Быстрых устройств с собственными алгоритмами оптимизации
Проблемы: 100% утилизация, высокие задержки записи, OLAP-нагрузка с преобладанием чтения
Оценка альтернатив:
Оставить mq-deadline:
✅ Приоритет чтения важен для OLAP
✅ Deadline механизм предотвращает голодание
❌ Не решает проблему 100% утилизации
Перейти на kyber:
✅ Адаптивное управление очередями
✅ Хорошо для виртуализированных сред
❌ Разработан для быстрых SSD/NVMe (неизвестен тип накопителя)
❌ Меньший приоритет чтения перед записью
Перейти на bfq:
❌ Большие накладные расходы
❌ Не оптимален для серверных нагрузок
❌ Может ухудшить производительность при 100% утилизации
Перейти на none:
❌ Опасен при высоких очередях
❌ Может привести к полному захвату устройства одним процессом
❌ Требует тщательного мониторинга
Рекомендация для vdd: Оставить mq-deadline, но рассмотреть тонкую настройку параметров
Текущее состояние: Умеренная нагрузка, только запись, хорошая производительность
Оценка альтернатив:
Оставить mq-deadline:
✅ Стабильная работа подтверждена данными
✅ Хорошо справляется с последовательной записью
✅ Deadline механизм важен для журналов
Перейти на kyber:
✅ Возможна оптимизация задержек
❌ Незначительный потенциальный выигрыш
Рекомендация для vdc: Оставить mq-deadline
Если устройство vdd — это HDD (вероятно, учитывая высокие задержки):
# Увеличение времени дедлайна для записи (по умолчанию 5 секунд)
echo 10000 > /sys/block/vdd/queue/iosched/write_expire
# Уменьшение времени дедлайна для чтения (по умолчанию 500 мс)
echo 250 > /sys/block/vdd/queue/iosched/read_expire
# Увеличение размера пакета (может улучшить пропускную способность)
echo 16 > /sys/block/vdd/queue/iosched/fifo_batch
# Увеличение количества запросов в очереди (осторожно!)
echo 256 > /sys/block/vdd/queue/nr_requests
Если устройство vdd — это SSD:
# Уменьшение времени дедлайна для записи
echo 5000 > /sys/block/vdd/queue/iosched/write_expire
# Уменьшение времени дедлайна для чтения
echo 100 > /sys/block/vdd/queue/iosched/read_expire
# Увеличение размера пакета для SSD
echo 32 > /sys/block/vdd/queue/iosched/fifo_batch
# Рассмотреть переход на kyber
echo kyber > /sys/block/vdd/queue/scheduler
Прежде чем вносить изменения:
# Сохранить текущие настройки
cat /sys/block/vdd/queue/iosched/* > ~/mq-deadline-backup.txt
После изменений мониторить:
# Глубина очереди
cat /sys/block/vdd/queue/nr_requests
# Статистика планировщика
cat /sys/block/vdd/queue/iosched/*
# Производительность в реальном времени
iostat -x 1
Текущий выбор планировщика (mq-deadline) является оптимальным для текущей нагрузки, учитывая:
Преобладание операций чтения на vdd
Последовательную запись на vdc
Высокую утилизацию устройств
Определить тип накопителя vdd:
cat /sys/block/vdd/queue/rotational
Если 1 — HDD, оставлять mq-deadline с тонкой настройкой
Если 0 — SSD, можно протестировать kyber
Настройка параметров mq-deadline для vdd:
# Для HDD
echo 10000 > /sys/block/vdd/queue/iosched/write_expire
echo 250 > /sys/block/vdd/queue/iosched/read_expire
# Проверить результат
iostat -x 1 | grep vdd
A/B тестирование (только в периоды низкой нагрузки):
# Тест kyber
echo kyber > /sys/block/vdd/queue/scheduler
# Мониторить 15-30 минут
# Вернуть обратно при ухудшении
echo mq-deadline > /sys/block/vdd/queue/scheduler
Документирование изменений:
Зафиксировать исходные параметры
Записать все изменения
Сравнить метрики "до" и "после"
Основная проблема vdd — 100% утилизация и высокие задержки. Изменение планировщика не решит эту проблему кардинально.
Необходимо:
Увеличить ресурсы (RAM, быстрые диски)
Оптимизировать запросы СУБД
Рассмотреть балансировку нагрузки между несколькими дисками
Планировщик — это инструмент управления очередями, а не увеличения пропускной способности устройства.
Анализ основан на данных мониторинга от 05.01.2026 и текущей конфигурации планировщиков.