Нейросеть рисует и пишет
20 постов
20 постов
16 постов
112 постов
40 постов
211 постов
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 (возможны правки в исходной статье).
Традиционный подход к диагностике производительности PostgreSQL зачастую опирается на эвристики, «типовые чек‑листы» и интуицию администратора. Администратор видит всплеск ожиданий, находит самый массовый тип события и принимает решение: «увеличить shared_buffers» или «выключить параллельные запросы». Такой метод работает в очевидных случаях, но оказывается бессилен, когда система находится в состоянии сложного баланса между разными механизмами, а первопричина торможения скрыта за вторичными эффектами.
Статистический подход, реализованный в методике pg_expecto, принципиально меняет логику расследования. Вместо субъективного выбора «самого громкого» типа ожиданий во главу угла ставятся количественные критерии, основанные на реальном поведении системы во времени.
Применение корреляционного и регрессионного анализа позволяет решить три критически важные задачи:
Отсечь иллюзорные связи. Тип ожидания может быть многочисленным, но при этом не оказывать системного влияния на рост общей задержки. Статистическая значимость (p‑value) и низкая взвешенная корреляция (ВКО)отфильтровывают такие события, экономя часы бесполезных настроек.
Выявить скрытые доминанты. Нередко тип ожидания, занимающий лишь 10–15% в структуре событий, на поверку оказывается «бутылочным горлышком», с которым жёстко связан общий рост ожиданий. Именно его корректировка даёт максимальный прирост производительности. ВКО как интегральная метрика ранжирует проблемы именно по степени их фактического влияния на нагрузку, а не по частоте появления в логах.
Оценить предсказуемость и устойчивость. Высокий коэффициент детерминации (R²) регрессионной модели говорит о том, что связь между типом ожидания и общей задержкой стабильна и воспроизводима. Это не разовый выброс, а системный паттерн. Низкий R², напротив, предупреждает: даже значимый по корреляции тип ожидания ведёт себя хаотично, и его оптимизация может дать непредсказуемый результат.
В практическом примере, представленном в статье , именно статистический анализ позволил объективно выделить IPC как доминирующий фактор (ВКО = 0,74) и обосновать первоочередность его настройки, несмотря на то что в «сырых» счётчиках событий он мог не бросаться в глаза. Одновременно были отсеяны типы, которые при поверхностном взгляде часто вызывают неоправданное беспокойство (например, Lock или BufferPin).
Таким образом, внедрение статистических методов превращает анализ производительности из искусства субъективных догадок в инженерную дисциплину, опирающуюся на объективные метрики и воспроизводимые выводы. Представленный отчёт — наглядная демонстрация того, как точные расчёты помогают принимать решения об оптимизации с предсказуемым положительным эффектом.
Методика предназначена для количественной оценки производительности PostgreSQL, выявления узких мест и факторов, вызывающих задержки, на основе статистического анализа временных рядов событий ожидания(wait_event_type). Применяется при нагрузочном тестировании, мониторинге продуктивных систем или постмортем‑анализе инцидентов.
Данная методика позволяет системно подойти к выявлению причин замедления PostgreSQL, опираясь исключительно на статистические свойства собранных метрик, и даёт чёткие критерии для принятия решений об оптимизации.
Для анализа необходимы:
временные ряды операционной скорости ;
временные ряды суммарного количества ожиданий СУБД ;
временные ряды событий ожидания по типам (wait_event_type): BufferPin, Extension, IO, IPC, Lock, LWLock, Timeout .
Шаг 1. Оценка корреляции с суммарными ожиданиями
Вычисляется коэффициент корреляции Пирсона между суммарными количествами ожиданий СУБД и событиями ожидания конкретного типа .
Проверка значимости:
Если p‑value ≥ 0,05 – тип исключается из дальнейшего анализа (связь нестабильна).
Если значимо – переходим к шагу 2.
Шаг 2. Расчёт взвешенной корреляции ожиданий (ВКО)
ВКО – интегральная метрика, ранжирующая типы ожиданий по степени их влияния на нагрузку. Значение ВКО лежит в пределах [0,1].
Порог отбрасывания: ВКО < 0,01 – влияние пренебрежимо мало, тип игнорируется.
Чем выше ВКО, тем критичнее проблема. Значения, близкие к 1, требуют немедленного анализа.
Шаг 3. Построение регрессионной модели
Для типов ожиданий, прошедших шаги 1 и 2, строится линейная регрессия вида:
Y = a + b·X,
где Y – суммарные ожидания, X – ожидания данного типа.
Оценивается R² модели .
R² ≥ 0,8 — исключительно сильная модель, прогноз надёжен.
0,6 ≤ R² < 0,8 — качественная модель.
0,4 ≤ R² < 0,6 — приемлемая модель.
0,2 ≤ R² < 0,4 — слабая модель.
R² < 0,2 — модель непригодна для прогнозирования.
Дата тестирования: 2026-02-12 (14:11 – 16:00)
Объект: PostgreSQL (нагрузочное тестирование)
Операционная скорость: демонстрирует умеренный рост (угол наклона +38,6).
Качество модели: хорошее (R² = 0,64). Достоверный, практически полезный тренд.
Общие ожидания СУБД: растут опережающими темпами (угол наклона +43,3).
Качество модели: очень высокое (R² = 0,89). Прогнозная способность высокая, связь сильная.
Взаимосвязь скорости и ожиданий:
Коэффициент детерминации R² = 0,69 — качественная модель.
Рост ожиданий сопровождается ростом операционной скорости (положительная корреляция).
Вывод: увеличение нагрузки приводит к соразмерному росту как производительности, так и времени ожидания. Система работает на пределе эффективности, требуется анализ узких мест.
Критерии отбора:
Статистическая значимость корреляции (p < 0,05).
Взвешенная корреляция ожиданий (ВКО) ≥ 0,01.
Коэффициент детерминации R² ≥ 0,2.
Отсеяны (не влияют или некоррелируют):
BufferPin, Extension, Lock — отрицательная/отсутствующая корреляция, дальнейший анализ не требуется.
Тип ожидания: IPC (межпроцессное взаимодействие)
ВКО = 0,74 — критическое значение. Основной фокус расследования.
Корреляция с общими ожиданиями: очень сильная (R = 0,981, R² = 0,96).
Модель регрессии: R² = 0,96 — исключительно сильная, прогноз исключительно точный.
Рекомендации:
Настройка параллельных запросов (max_parallel_workers_per_gather, max_parallel_workers).
Оптимизация фоновых процессов (autovacuum, background writer, checkpointer).
Увеличение shared_buffers для снижения конкуренции.
Возможно выделение отдельного инстанса под тяжёлые аналитические запросы.
Тип ожидания: IO (ввод-вывод)
ВКО = 0,18 — высокое значение.
Корреляция: сильная (R = 0,867, R² = 0,75). Модель качественная.
Рекомендации:
Агрессивная настройка autovacuum для горячих таблиц (снижение порогов, частая очистка).
Разделение таблиц и индексов по разным табличным пространствам на отдельных дисках.
Миграция наиболее интенсивно используемых данных на быстрые накопители (NVMe/SSD).
Тип ожидания: LWLock
ВКО = 0,01 — низкое, статистически значимая корреляция (R = 0,902, R² = 0,81).
Влияние на общую нагрузку минимально, но модель очень сильная.
Рекомендации (при ухудшении):
Обновление PostgreSQL до версий с улучшенными алгоритмами LWLock.
Выделение специализированных инстансов для разных типов нагрузки.
Консультация с экспертами по тонкой настройке.
Тип ожидания: Timeout
ВКО = 0,01 — низкое, корреляция очень сильная (R = 0,979, R² = 0,96).
Текущее влияние незначительно, но высокая предсказуемость.
Рекомендации (при ухудшении):
Реорганизация длинных транзакций, уменьшение их количества.
Внедрение механизмов повторных попыток с экспоненциальной задержкой на стороне приложения.
Обучение разработчиков работе с асинхронными вызовами.
Система работает под высокой нагрузкой, что подтверждается устойчивым ростом как производительности, так и времени ожидания. Тренд ожиданий усиливается быстрее — потенциальный риск деградации при дальнейшем росте нагрузки.
Основной источник проблем — IPC (74% взвешенного влияния). Необходима срочная диагностика и оптимизация механизмов параллелизма и фоновых процессов.
Второй значимый фактор — подсистема ввода-вывода (18% влияния). Требует плановой оптимизации с акцентом на физическое размещение данных и настройку autovacuum.
Остальные типы ожиданий (LWLock, Timeout) в настоящее время не создают критических задержек, но их высокие корреляции сигнализируют о наличии потенциально опасных паттернов. Рекомендуется мониторинг и превентивные архитектурные улучшения.
Типы BufferPin, Extension, Lock не оказывают значимого влияния — фокусироваться на них нецелесообразно.
IPC
Проверить текущие значения max_parallel_workers_per_gather, max_parallel_workers, max_worker_processes.
Оценить загрузку autovacuum и background writer, настроить их интенсивность.
Рассмотреть увеличение shared_buffers (при достаточном ОЗУ).
IO
Выявить наиболее «горячие» таблицы и индексы.
Настроить пороги autovacuum (autovacuum_vacuum_scale_factor, autovacuum_vacuum_threshold).
При наличии нескольких физических дисков — распределить табличные пространства.
Мониторинг
Установить длительный сбор статистики по ожиданиям IPC и IO.
Отслеживать динамику ВКО по LWLock и Timeout.
Отчет составлен на основе статистического анализа с применением взвешенной корреляции ожиданий (ВКО), регрессионного анализа и проверки значимости связей.
Представленная методика комплексного статистического анализа ожиданий PostgreSQL (реализованная в комплексе pg_expecto) знаменует принципиальный сдвиг в подходе к диагностике производительности СУБД.
Новизна исследования заключается не в самом факте сбора событий ожидания — это давно доступно, — а в переходе от плоскостного ранжирования по частоте к многомерной статистической оценке.
Влияние типа ожидания оценивается не изолированно, а в системной связке с общей динамикой задержек;
Введена интегральная метрика ВКО (взвешенная корреляция ожиданий), позволяющая объективно ранжировать проблемы по степени их фактического воздействия на нагрузку;
Применён жёсткий статистический фильтр, отсекающий случайные и нестабильные корреляции;
Качество каждой выявленной связи верифицируется через коэффициент детерминации (R²), что даёт уверенность в воспроизводимости результата.
Практическая ценность методики уже подтверждена в ходе нагрузочного тестирования:
Второстепенные и шумовые типы ожиданий (BufferPin, Extension, Lock) отброшены автоматически — без затрат времени на их анализ;
Скрытый доминант — IPC — выявлен и обоснован как первоочередная цель оптимизации (ВКО = 0,74), хотя в структуре событий он мог не быть самым массовым;
По каждому значимому типу сформулированы конкретные, применимые немедленно рекомендации и контрольный чек-лист.
Таким образом, pg_expecto превращает трудно формализуемое искусство «тонкой настройки PostgreSQL» в воспроизводимый инженерный процесс, где каждое решение опирается на математически обоснованные критерии, а эффект оптимизации становится предсказуемым.
Предложенный подход не заменяет экспертизу администратора, но вооружает её точными инструментами измерения, позволяя фокусировать усилия именно там, где они принесут максимальный результат. Это первый шаг к созданию полноценной предиктивной аналитики производительности PostgreSQL, и уже сегодня он готов к промышленному применению.
Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).
В мире администрирования PostgreSQL данные об ожиданиях (wait events) являются ключевым источником диагностики производительности. Однако отдельные метрики без аналитической обработки создают лишь информационный шум, не отвечая на главный вопрос: какой тип ожиданий действительно определяет общую нагрузку на систему?
Метод «Взвешенной корреляции ожиданий (ВКО)», реализованный в комплексе PG_EXPECTO, основан на серьёзной теоретической базе. Он сочетает корреляционный анализ для оценки силы связи между типом ожиданий и общей нагрузкой с взвешиванием по значимости, учитывающим долю каждого типа. Без этого фундамента метрика оставалась бы просто числом, а не стратегическим инструментом приоритизации.
Именно теория превращает ВКО в точный компас, который позволяет отделить системные узкие места от фонового шума и сфокусироваться на главной причине проблем — будь то ожидания IO, IPC или блокировок.
В статье рассматривается , как теоретические принципы статистики воплощаются в практический инструмент для анализа производительности PostgreSQL, способный превращать данные в чёткий план действий.
Корреля́ция (от лат. correlatio «соотношение»), или корреляцио́нная зави́симость — статистическая взаимосвязь двух или более случайных величин (либо величин, которые можно с некоторой допустимой степенью точности считать таковыми), при этом изменения значений одной или нескольких из этих величин сопутствуют систематическому изменению значений другой или других величин.
Положительная корреляция в таких условиях — это такая связь, при которой увеличение одной переменной связано с увеличением другой переменной.
Score = Corr(WaitType, Total) * P(WaitType)
Corr ∈ [0, 1]: коэффициент корреляции между ожиданиями данного типа wait_event_type ∈ [BufferPin, Extension, IO, IPC, Lock, LWLock, Timeout] и всеми ожиданиями СУБД за выбранный период .
P ∈ [0, 1]: доля в процентах(деленная на 100) количества ожиданий данного типа wait_event_type ∈ [BufferPin, Extension, IO, IPC, Lock, LWLock, Timeout] ко всем ожиданиями СУБД за выбранный период .
"Взвешенная корреляция ожиданий (ВКО)" отвечает на вопрос: "Насколько данный тип ожиданий является доминирующим и стабильным фактором, определяющим общую нагрузку ожиданиями в системе?"
Проще говоря, она помогает ранжировать проблемы и отделить системные, хронические узкие места от всплесков или шума.
Ранг 5 (Критический) — Score ≥ 0.20
Что это значит: Явное, системное узкое место. Данный тип ожиданий является основным драйвером проблем производительности в системе. Высокая доля и сильная связь с общей нагрузкой.
Характер проблемы: Емкостное (ресурсное) ограничение или масштабная логическая проблема, затрагивающая всю СУБД.
Типовые мероприятия:
Немедленный детальный анализ этого конкретного типа ожиданий
Оценка загрузки соответствующего ресурса ОС (если это IO — дисковые утилизации и задержки; IPC/LWLock — загрузка CPU, межпроцессное взаимодействие).
Анализ топ-запросов по общему времени и времени ожиданий данного типа.
Приоритетная настройка/оптимизация: Для IO — настройка work_mem, effective_io_concurrency, проверка индексов; для Lock — анализ долгих транзакций, оптимизация логики приложения.
Рассмотрение вопросов масштабирования/апгрейда (более быстрые диски, увеличение RAM, добавление CPU ядер).
Ранг 4 (Высокий) — 0.10 ≤ Score < 0.20
Что это значит: Существенный фактор, влияющий на производительность. Проблема является заметной и устойчивой, но может быть не единственной.
Характер проблемы: Локальное емкостное ограничение или широко распространенная логическая проблема.
Типовые мероприятия:
Целевой анализ запросов, создающих данный тип ожиданий.
Проверка конфигурации СУБД, связанной с этой областью (shared_buffers, max_connections, настройки блокировок и т.д.).
Глубокий мониторинг этого типа ожиданий во времени для выявления пиков и их триггеров.
Планирование оптимизационных работ (перестройка индексов, рефакторинг проблемных участков кода приложения, настройка пулеров соединений).
Рассмотрение точечных улучшений инфраструктуры.
Ранг 3 (Средний) — 0.04 ≤ Score < 0.10
Что это значит: Заметная проблема второго плана. Может быть либо важной, но редко проявляющейся, либо частой, но не являющейся основным ограничителем.
Характер проблемы: Периодические всплески или симптом более глубокой проблемы.
Типовые мероприятия:
Анализ в связке с другими метриками: Необходимо смотреть, не маскирует ли эта проблема другую (например, высокие LWLock могут быть следствием плохого плана запроса).
Сбор дополнительного контекста: В какое время суток проявляется? С какими конкретными операциями (SELECT, UPDATE, VACUUM) связан?
Оптимизация "низко висящих фруктов": Проверка очевидных вещей — достаточно ли maintenance_work_mem для AUTOVACUUM, нет ли явных дедлоков.
Включение в список для регулярного аудита, но без срочных действий.
Ранг 2 (Низкий) — 0.01 ≤ Score < 0.04
Что это значит: Фоновый шум или нишевая проблема. Не оказывает значительного влияния на общую производительность системы в текущий момент.
Характер проблемы: Узкая проблема, затрагивающая специфичные операции, или стабильный фоновый шум.
Типовые мероприятия:
Документирование и наблюдение. Зафиксировать факт наличия ожиданий данного типа.
Установка базового уровня (baseline). Это норма для данной системы?
Проверить, не является ли это симптомом неправильной настройки мониторинга или сбора статистики.
Действия требуются только в случае роста Score или появления связанных с этим алертов (например, таймауты приложений).
Ранг 1 (Минимальный) — 0 < Score < 0.01
Что это значит: Статистический шум. Вклад в общие проблемы производительности пренебрежимо мал.
Характер проблемы: Практически отсутствует.
Типовые мероприятия:
Игнорировать в рамках анализа производительности. Не тратить время на расследование.
Возможно, стоит проверить корректность вычисления метрик (достаточен ли объем выборки, нет ли ошибок в запросе).
Учесть как часть общей картины для полноты отчета, но без выделения отдельного внимания.
Ранжирование следует использовать как фильтр для приоритизации. Даже при среднем ранге (3) проблема может быть критичной для конкретной бизнес-операции.
Метрика «Взвешенная корреляция ожиданий (ВКО)», реализованная в комплексе PG_EXPECTO, представляет собой мощный инструмент для системного и объективного анализа производительности PostgreSQL. Её основная ценность заключается не просто в диагностике наличия ожиданий, а в расстановке приоритетов при устранении узких мест.
На практике администратор или разработчик часто сталкивается с десятками различных метрик и типов ожиданий, что может привести к «аналитическому параличу» — попыткам оптимизировать всё сразу без чёткого понимания, что влияет на систему больше всего. ВКО решает эту проблему, отвечая на ключевой вопрос: какой тип ожиданий является основным, стабильным драйвером проблем в данный период времени?
Использование системы рангов (от критического 5 до минимального 1) позволяет:
Мгновенно сфокусироваться на главном источнике проблем (Score ≥ 0.20), игнорируя статистический шум.
Планировать работы на основе данных: высокий и средний ранги указывают на целевые области для глубокого анализа конфигурации СУБД, оптимизации запросов или инфраструктуры.
Разделять системные, хронические проблемы от ситуационных всплесков, что критически важно для планирования долгосрочных улучшений и точечных «тушению пожаров».
Создавать объективную основу для отчётности, переходя от субъективных ощущений «система тормозит» к конкретным утверждениям: «доминирующим фактором нагрузки являются ожидания типа IO с весом 0.25».
Как показано в примере с имитацией OLAP-нагрузки, метрика наглядно выделяет доминирующие типы ожиданий (например, IO и IPC), предоставляя отправную точку для углублённого анализа: изучения топ-запросов, проверки дисковых подсистем или настройки параметров параллелизма.
Таким образом, ВКО — это не просто ещё один показатель, а стратегический фильтр и компас для специалистов по производительности. Она позволяет превратить разрозненные данные о событиях ожидания в чёткий план действий, экономя время и ресурсы и направляя усилия туда, где они дадут максимальный эффект для устойчивой и предсказуемой работы СУБД PostgreSQL.
Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).
Тестирование производительности PostgreSQL часто упирается в вопрос: как система поведёт себя под реальной, смешанной нагрузкой? Методы «на глазок» и разрозненные метрики не дают полной картины. PG_EXPECTO v.6 — инструмент, который целенаправленно создаёт реалистичную имитацию OLTP и OLAP-нагрузки, дополняя её структурированными чек-листами по вводу-выводу и памяти, а также ключевой статистикой по vm_dirty и shared_buffers для глубокой диагностики.
# НАСТРОЙКИ НАГРУЗОЧНОГО ТЕСТИРОВАНИЯ
# 6.0
# Максимальная нагрузка
finish_load = 20
# Тестовая БД
testdb = default
# testdb = demo
# Тип синтетической нагрузки
load_mode = oltp
#load_mode = olap
# Веса сценариев по умолчанию
scenario1 = 0.7
scenario2 = 0.2
scenario3 = 0.1
# Инициализировать тестовую БД
init_test_db = on
#init_test_db = off
# Размер тестовой БД
# ~200MB
#scale = 20
#~10GB
scale = 685
Тип имитируемой нагрузки определяется значением параметра "load_mode":
oltp : Нагрузочное тестирование под синтетической нагрузкой, имитирующей OLTP.
olap : Нагрузочное тестирование под синтетической нагрузкой, имитирующей OLAP.
Исходный файл: postgres.1.1.shared_buffers.report.txt
Исходный файл: linux.5.1.vm_dirty.txt
Имитация нагрузки — это лишь первый шаг. Истинная ценность подхода, реализованного в PG_EXPECTO v.6, — в целостной интерпретации результатов. Когда данные с «датчиков» vm_dirty и shared_buffers рассматриваются через призму чек-листов по IO и RAM, вы перестаётся быть пассивным наблюдателем за сбоями. Вы становитесь инженером, который понимает язык своей системы и может проактивно устранять риски, обеспечивая её устойчивость и скорость. Добро пожаловать в эпоху осознанной производительности.
Эффективность параметров настройки CPU для PostgreSQL сильно зависит от типа нагрузки: OLTP требует минимальной задержки и эффективной обработки множества коротких операций, а OLAP — максимальной пропускной способности для сложных вычислений.
Основываясь на анализе практических тестов и рекомендаций, вот ключевые параметры, сгруппированные по категориям.
Управляющий драйвер (governor)
Для OLTP: performance. Фиксация на максимальной частоте снижает задержку каждой транзакции.
Для OLAP: performance или schedutil. Стабильно высокая частота или интеллектуальное управление от планировщика ядра ускоряют обработку объемных данных.
Состояния простоя (C-states)
Для OLTP: Ограничение глубоких состояний (например, processor.max_cstate=1). Снижает латентность при частых переходах от простоя к активности, что критично для отклика транзакций.
Для OLAP: Менее критично. Можно разрешить более глубокие состояния для энергосбережения, так как запросы длительные и массовые.
Планировщик задач ядра Linux
Для OLTP: Отключение sched_autogroup_enabled. Предотвращает несправедливое распределение CPU между фоновыми процессами СУБД (например, autovacuum) и обработкой запросов.
Общая рекомендация: Настройка sched_min_granularity_ns. Увеличение значения может снизить накладные расходы на переключение контекста при высокой конкуренции за CPU.
Параметры параллелизма PostgreSQL
Для OLAP: Крайне важны. Увеличение max_parallel_workers_per_gather, max_worker_processes. Позволяют одним аналитическим запросом задействовать несколько ядер, значительно ускоряя выполнение.
Для OLTP: Обычно не требуют изменений. Короткие транзакции редко используют параллельное выполнение.
Изоляция CPU (cgroups, systemd, isolcpus)
Для смешанных нагрузок (OLTP+OLAP): Выделение отдельных ядер для фоновых процессов PostgreSQL (autovacuum, WAL writer) или для выполнения аналитических запросов. Это предотвращает их вмешательство в обработку критичных транзакций.
Для чистого OLTP/OLAP: Менее актуально, но может использоваться для тонкой настройки под конкретную задачу.
Управление прерываниями (irqbalance, smp_affinity)
Для обеих нагрузок: Привязка сетевых прерываний и прерываний дисковой подсистемы к выделенным ядрам. Освобождает основные ядра для обработки запросов, улучшая предсказуемость производительности.
Политики NUMA (numactl, numa_balancing)
Для больших серверов: Отключение numa_balancing и ручная привязка экземпляра PostgreSQL к одному узлу NUMA. Уменьшает задержки при доступе к памяти, что важно для интенсивных нагрузок.
Производительность CPU тесно связана с корректной настройкой памяти и ввода-вывода в PostgreSQL.
Память: shared_buffers (25-40% RAM) и work_mem. Недостаток work_mem приводит к записи временных данных на медленный диск, что создает очередь процессов в состоянии D (b), висящую на iowait, и имитирует проблему с CPU.
Ввод-вывод: random_page_cost (понизить для SSD), effective_io_concurrency. Правильные настройки заставляют планировщик чаще выбирать индексные сканы, снижая нагрузку на CPU.
Определите профиль нагрузки с помощью мониторинга (например, pg_stat_statements).
Начните с настройки PostgreSQL, особенно параметров памяти и autovacuum.
Задайте CPU governor в performance — это безопасно и почти всегда дает положительный эффект.
Для OLAP-нагрузки активируйте и настройте параллельные запросы в PostgreSQL.
Если проблема сохраняется, используйте мониторинг (top, perf, vmstat) для выявления узких мест: высокой очереди (runqueue), iowait или переключений контекста. Только затем тонко настраивайте параметры ядра (C-states, планировщик).
Протестируйте каждое изменение на нерабочем стенде. Используйте нагрузочное тестирование, например, pgbench.
В целом, для OLTP ключевыми являются стабильно высокая частота CPU и минимизация латентности (governor, C-states). Для OLAP — максимальная пропускная способность параллельных вычислений (параметры параллелизма Postgres). Настройка параметров ОС (планировщик, изоляция) становится критичной на высоконагруженных системах или при смешанной нагрузке.
Параметры vm.dirty_background_bytes и vm.dirty_bytes работают в паре, устанавливая два порога. Первый активирует фоновую запись, а второй вызывает блокирующую запись, останавливающую процессы.
vm.dirty_background_bytes: максимальный объем «грязной» памяти в байтах, при достижении которого ядро начинает фоновую запись данных на диск.
vm.dirty_bytes: абсолютный лимит в байтах. При его достижении все процессы, генерирующие новые «грязные» данные, будут приостановлены до завершения записи.
Цели настройки:
Для интерактивных десктопов/серверов с латентностью: минимизировать задержки, установив низкие пороги для частой записи.
Для серверов с высокой пропускной способностью записи : установить высокие пороги, чтобы накапливать большие порции данных для эффективной записи.
Предотвращение внезапных блокировок I/O: dirty_bytes должен быть значительно больше dirty_background_bytes, чтобы у фоновых потоков было время на очистку.
ВАЖНО: dirty_background_bytes и dirty_background_ratio (а также dirty_bytes и dirty_ratio) являются взаимоисключающими парами. При установке значения в байтах соответствующий параметр в процентах автоматически обнуляется, и наоборот.
Перед настройкой необходимо собрать данные о системе и ее текущем состоянии.
1. Анализ текущих значений и конфигурации ОС:
Посмотреть актуальные значения параметров:
sysctl vm.dirty_background_bytes vm.dirty_bytes vm.dirty_background_ratio vm.dirty_ratio
Определить общий объем оперативной памяти (RAM):
grep MemTotal /proc/meminfo
Ключевые метрики:
wkB/s или MB_wrtn/s — скорость записи.
%util — загрузка устройства (близко к 100% указывает на насыщение).
await (в частности, w_await) — среднее время ожидания операции записи (высокое значение указывает на проблемы).
3. Оценка давления на память и ввод-вывод с помощью vmstat:
Ключевые метрики для диагностики проблем с dirty pages:
memory: swpd, free, buff, cache — если free мало, а cache велик, это может указывать на активное использование страниц.
swap: si, so — ненулевые значения могут указывать на нехватку памяти, влияющую на политику записи.
cpu: wa — высокий процент времени ожидания ввода-вывода (wa) часто коррелирует с блокировками процессов при достижении лимита dirty_bytes.
Шаг 1: Определение целевого времени сброса данных
Основная идея — связать объем данных со скоростью диска, чтобы контролировать максимальное время, за которое данные могут быть записаны.
Рекомендуется, чтобы фоновая запись (dirty_background_bytes) могла завершиться за 100-500 мс. Это предотвращает длительные блокировки при достижении верхнего лимита.
Для расчета используйте пиковую скорость записи (write_speed_mb_ps), полученную из iostat.
Шаг 2: Расчет vm.dirty_background_bytes
Формула:
vm.dirty_background_bytes = target_writeback_time_ms * write_speed_mb_ps * 1024 * 1024 / 1000
Пример для SSD (скорость ~200 МБ/с, целевое время 250 мс):
250 мс * 200 МБ/с * 1048576 / 1000 ≈ 52428800 байт (50 МБ)
Это значение можно округлить до 50-60 МБ.
Шаг 3: Расчет vm.dirty_bytes
Верхний лимит должен давать буфер поверх фонового порога.
Минимальный множитель: 2x от dirty_background_bytes.
Рекомендуемый диапазон: 4x-8x от dirty_background_bytes.
Формула:
vm.dirty_bytes = N * vm.dirty_background_bytes, где N от 4 до 8.
Пример (продолжение):
vm.dirty_bytes = 6 * 50 МБ = 300 МБ (314572800 байт)
Слишком низкие значения:
Симптомы: высокий %system и cs в vmstat, низкая общая пропускная способность записи.
Решение: увеличьте dirty_background_bytes (и, соответственно, dirty_bytes), чтобы позволить накапливаться большим пакетам данных.
Слишком высокие значения:
Симптомы: длительные пики wa в vmstat при всплесках записи, ощутимые «подвисания» системы.
Решение: уменьшите оба параметра, особенно dirty_background_bytes, чтобы активировать запись раньше.
Активное использование свопа (si/so > 0):
Проблема может быть не в dirty pages, а в общем дефиците памяти. Рассмотрите возможность увеличения RAM или настройки vm.swappiness.
В мире IT-мониторинга и DevOps сложился своеобразный культ метрик. Среди них «CPU Utilization» (загрузка процессора) долгое время занимала трон главного короля, чье малейшее движение к 100% вызывало панику и триггерило спасательные операции. Однако в современной, сложной и распределенной инфраструктуре слепая вера в эту метрику не просто устарела — она стала вредной. Высокая утилизация CPU сама по себе не является инцидентом; это лишь симптом, требующий не аварийного реагирования, а профессиональной диагностики. Непонимание этого проистекает из фундаментальных недостатков самой метрики и приводит к ложным выводам, тогда как фокус должен сместиться на анализ метрик производительности.
Само понятие «утилизации» в контексте современных процессоров крайне условно. Процессор — не линейный и не однородный ресурс, подобный оперативной памяти. Его работа включает разные состояния (idle, user, system, iowait, steal в Linux), разные ядра и технологии вроде Hyper-Threading. Метрика «средней утилизации за 1-5 минут» — это грубое усреднение, стирающее важнейшие детали.
· Контекст решает всё: 90% утилизации на веб-сервере, обрабатывающем пиковую нагрузку, — это признак здоровья и эффективного использования дорогого железа. Те же 90% на базе данных, выполняющей тяжелый аналитический запрос, могут быть нормой, а могут — следствием плохого индекса. 10% утилизации при нулевом трафике — норма, но те же 10% при ожидаемой высокой нагрузке — тревожный сигнал о проблемах (блокировки, deadlock, ожидание I/O), которые метрика CPU просто не покажет.
· Проклятие iowait и steal: Высокий iowait (процессор простаивает в ожидании операций ввода/вывода) формально может давать общую высокую «загрузку», хотя CPU на самом деле не занят полезной работой. В виртуальных средах steal-время показывает, что гипервизор забирает ресурсы у вашей виртуальной машины. Реагировать на это увеличением лимитов CPU — бесполезно, проблема лежит на уровне инфраструктуры.
Таким образом, «CPU utilization» без контекста похожа на измерение температуры двигателя без знания, стоит машина в пробке или мчится по автобану. И то, и другое дает высокие показания, но причины и последствия радикально разные.
Истинная катастрофа производительности часто происходит при низких показателях CPU.
Это классические сценарии:
1. Блокировки (lock contention) или deadlock в приложении или СУБД: потоки выстроились в очередь, ожидая доступа к ресурсу. CPU простаивает, запросы таймаутятся, пользователи страдают, а метрика загрузки процессора спокойно показывает 15%.
2. Проблемы с внешними зависимостями (медленные API, сбойные микросервисы, лаговые диски): приложение проводит время в ожидании ответа, не нагружая CPU.
3. Проблемы планировщика ОС или JVM (для Java-приложений).
В этих случаях мониторинг, зацикленный на утилизации, будет молчать, пока бизнес теряет деньги. Это наглядно доказывает его нерелевантность как индикатора инцидента.
Ключевой сдвиг парадигмы заключается в отказе от метрик утилизации ресурсов в пользу метрик производительности и удовлетворенности пользователей. На первое место должны выходить:
1. Latency (задержка): P95, P99 времена ответа приложения. Рост задержек — это прямой сигнал о проблеме, независимо от того, как ведет себя CPU.
2. Throughput (пропускная способность): RPS (запросов в секунду), TPS (транзакций). Падение throughput при стабильной или растущей нагрузке — явный инцидент.
3. Rate of Errors: Процент ошибок (5xx, 4xx, таймауты). Это конечный результат многих проблем, которые CPU может и не заметить.
4. Saturation (насыщение): Длина очередей, количество ожидающих потоков. Это более точный показатель «перегруженности», чем утилизация CPU. Очередь на 1000 запросов — инцидент, даже если CPU загружен на 60%.
Это — метрики бизнеса. Они отвечают на вопрос «Что чувствует пользователь?», а не «Как поживает наше железо?». Высокая утилизация CPU становится проблемой только тогда и только в том случае, когда она отрицательно коррелирует с этими ключевыми метриками: вызывает рост latency, падение throughput или увеличение ошибок.
Поэтому объявлять инцидент по факту превышения порога в 80-90% утилизации CPU — архаичная и опасная практика. Она ведет к «холиварам» между разработчиками и сисопами, бессмысленному масштабированию «вслепую» и игнорированию реальных, но тихих катастроф.
· Деградировать «CPU Utilization» до вспомогательной, диагностической метрики. Ее место на информационных дашбордах, а не в правилах алертинга.
· Строить алерты на основе метрик производительности (Latency, Errors, Saturation). Это страхует от пропуска реальных инцидентов.
· Использовать утилизацию CPU в связке с другими данными (профилировщики, трейсинг, логи) для последующего анализа причин возникших проблем с производительностью. Высокая утилизация — не причина звонить в колокол, а повод взять в руки отладчик и профилировщик, когда проблема уже обнаружена другими средствами.
Таким образом, переход от религии утилизации к культу производительности — это признак зрелости инженерной культуры. Это понимание, что цель инфраструктуры — не быть красивой и ненагруженной, а эффективно и предсказуемо обслуживать бизнес-логику. И судить о ее здоровье нужно по конечному результату, а не по абстрактной загруженности одной из ее многочисленных шестеренок.
Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).
Настоящее исследование осуществлено с применением инструментария pg_expecto, обеспечивающего строгую методологию репрезентативного нагрузочного тестирования. Данный инструмент позволил провести сравнительный анализ двух дискретных конфигураций СУБД PostgreSQL в контролируемых и идентичных условиях, моделирующих устойчивую OLAP-нагрузку. Ниже представлено краткое изложение методологии эксперимента, включая описание стенда, генерации нагрузочного паттерна и ключевых варьируемых параметров, что обеспечивает полную воспроизводимость и верифицируемость полученных результатов. Основной целью являлась эмпирическая проверка гипотезы о влиянии реконфигурации областей памяти (shared_buffers и work_mem) на комплексные показатели производительности системы.
Для данной OLAP-нагрузки и текущей конфигурации сервера снижение размера shared_buffers с 4 ГБ до 1-2 ГБ, с одновременным увеличением work_mem, приведет к росту общей производительности системы. Основная цель — не просто уменьшить кэш БД, а перенаправить высвободившуюся оперативную память на выполнение операций в памяти и ослабить нагрузку на подсистему ввода-вывода.
vm.dirty_expire_centisecs = 3000
vm.dirty_ratio = 30
vm.dirty_background_ratio = 10
vm.vfs_cache_pressure = 100
vm.swappiness = 10
read_ahead_kb = 4096
work_mem
----------
32MB
shared_buffers
----------------
4GB
work_mem
----------
256MB
shared_buffers
----------------
2GB
Среднее снижение операционной скорости при shared_buffers=2GB(work_mem=256MB) составило 38.38%.
Среднее увеличение ожиданий типа IO при shared_buffers=2GB(work_mem=256MB) составило 22.70%.
Среднее снижение ожиданий типа IPC при shared_buffers=2GB(work_mem=256MB) составило 4.78%.
Среднее снижение IOPS при shared_buffers=2GB(work_mem=256MB) составило 3.29%.
Среднее снижение пропускной способности(MB/s) при shared_buffers=2GB(work_mem=256MB) составило 313.74%.
Нагрузка соответствует OLAP-сценарию (аналитические запросы, большие объёмы данных).
В обоих экспериментах наблюдался рост нагрузки (Load average увеличился с 5 до 22).
Параметры экспериментов:
Эксперимент-1: shared_buffers = 4GB, work_mem = 32MB
Эксперимент-2: shared_buffers = 2GB, work_mem = 256MB
Высокий I/O wait (wa): 100% наблюдений с wa > 10%.
Корреляция ожиданий IO и записи (bo): высокая (0.6533), система ограничена производительностью записи на диск.
Состояние процессов (b): слабая корреляция с ожиданиями IO (0.2611), количество процессов в состоянии непрерываемого сна не возрастает значительно.
Отношение прочитанных блоков к изменённым: 177.98, подтверждение OLAP-нагрузки.
Высокий I/O wait (wa): 97.27% наблюдений с wa > 10%.
Корреляция ожиданий IO и записи (bo): высокая (0.6719), система также ограничена записью.
Состояние процессов (b): очень высокая корреляция с ожиданиями IO (0.8774), процессы всё чаще переходят в состояние непрерываемого сна (ожидание диска).
Отношение прочитанных блоков к изменённым: 268.01, нагрузка ещё более ориентирована на чтение.
Уменьшение shared_buffers с 4GB до 2GB привело к усилению корреляции между ожиданием IO и блокированными процессами.
В обоих случаях система ограничена производительностью записи, но во втором эксперименте дисковые ожидания сильнее влияют на состояние процессов.
Свободная RAM: менее 5% в 100% наблюдений.
Свопинг (swap in/out): используется незначительно (в 9.01% и 1.8% наблюдений соответственно).
Свободная RAM: менее 5% в 100% наблюдений.
Свопинг: не используется (0% наблюдений).
Оба эксперимента показывают критически низкое количество свободной RAM.
Свопинг практически отсутствует, что может указывать на эффективное использование файлового кэша ОС.
Hit Ratio: 55.36% (критически низкий).
Корреляция hit/read: очень высокая (0.9725), кэширование связано с большим чтением с диска.
Hit Ratio: 38.58% (ещё ниже, критически низкий).
Корреляция hit/read: очень высокая (0.8698), аналогичная картина.
Уменьшение shared_buffers с 4GB до 2GB привело к снижению Hit Ratio на ~16.78%.
В обоих случаях кэширование недостаточно эффективно для данной нагрузки.
Корреляция LWLock и user time: очень высокая (0.9775).
Корреляция LWLock и system time: очень высокая (0.9092).
Очередь процессов (r): превышение числа ядер CPU в 16.22% наблюдений.
System time (sy): не превышает 30% (все наблюдения).
Корреляция LWLock и user time: очень высокая (0.8574).
Корреляция LWLock и system time: высокая (0.6629).
Очередь процессов (r): превышение числа ядер CPU в 3.64% наблюдений.
System time (sy): не превышает 30% (все наблюдения).
В Эксперименте-1 выше корреляция LWLock с системным временем, что может указывать на большее количество системных вызовов и переключений контекста.
Очередь процессов (r) чаще превышает число ядер CPU в Эксперименте-1, но в обоих случаях это не является критичным.
Уменьшение shared_buffers с 4GB до 2GB:
Привело к снижению Hit Ratio (с 55.36% до 38.58%).
Усилило корреляцию между ожиданием IO и блокированными процессами.
Не вызвало существенных изменений в использовании свопинга и свободной RAM.
Увеличение work_mem с 32MB до 256MB:
Не компенсировало снижение эффективности кэширования при уменьшении shared_buffers.
Не привело к значительным изменениям в поведении CPU и очереди процессов.
Общий характер нагрузки (OLAP) подтверждается высоким отношением чтения к записи и сильной зависимостью производительности от операций ввода-вывода.
Диск данных: vdd (100 ГБ, LVM-том 99 ГБ, точка монтирования /data)
Конфигурация сервера:
8 CPU ядер
8 ГБ RAM
Отдельные диски для WAL (/wal) и логов (/log)
Параметры сравнения:
Эксперимент 1: shared_buffers = 4 ГБ, work_mem = 32 МБ
Эксперимент 2: shared_buffers = 2 ГБ, work_mem = 256 МБ
Продолжительность тестов: ≈110 минут каждый
Эксперимент 1 (shared_buffers=4GB, work_mem=32MB):
Средняя утилизация диска: 90-94% → 80% (снижение к концу теста)
Средний IOPS: ≈3500 операций/сек
Средняя пропускная способность: ≈130 МБ/с → 180 МБ/с (рост к концу)
Среднее время ожидания чтения: 9-14 мс
Среднее время ожидания записи: 6-7 мс
Средняя длина очереди: ≈43
Средняя загрузка CPU на IO: ≈24%
Эксперимент 2 (shared_buffers=2GB, work_mem=256MB):
Средняя утилизация диска: 93-97% (стабильно высокая)
Средний IOPS: ≈3400 операций/сек
Средняя пропускная способность: ≈139 МБ/с → 95-149 МБ/с (колебания)
Среднее время ожидания чтения: 10-19 мс
Среднее время ожидания записи: 7-10 мс
Средняя длина очереди: ≈33 → 61 (рост)
Средняя загрузка CPU на IO: ≈28% → 9% (снижение)
Эксперимент 1:
Тип ограничения: Пропускная способность диска
Корреляция скорость-MB/s: Очень высокая (0.8191)
Корреляция скорость-IOPS: Слабая (0.4128)
Вывод: Производительность определяется объемом передаваемых данных
Эксперимент 2:
Тип ограничения: Количество операций ввода-вывода
Корреляция скорость-IOPS: Очень высокая (0.9256)
Корреляция скорость-MB/s: Слабая (0.1674)
Вывод: Нагрузка чувствительна к количеству IO операций
Эксперимент 1 (shared_buffers=4GB):
Утилизация диска снижается с 94% до 80% к концу теста
Пропускная способность растет с 132 МБ/с до 180 МБ/с
Загрузка CPU на IO снижается с 28% до 18%
Стабильные показатели IOPS и времени отклика
Эксперимент 2 (shared_buffers=2GB):
Высокая и стабильная утилизация диска (93-97%)
Колебания пропускной способности (139 → 95 → 149 МБ/с)
Значительный рост длины очереди (33 → 61)
Увеличение времени ожидания чтения (10 → 19 мс)
Снижение загрузки CPU на IO (28% → 9%)
Утилизация диска: Повысилась и стабилизировалась на высоком уровне
Время отклика: Увеличилось время ожидания операций чтения
Длина очереди: Выросла в 1.8 раза к концу теста
Загрузка CPU на IO: Снизилась в 3 раза
Характер нагрузки: Сместился с пропускной способности на IOPS-ограниченный режим
Стабильность пропускной способности: Ухудшилась, появились значительные колебания
Обеспечивает более предсказуемую пропускную способность
Демонстрирует улучшение производительности в ходе теста
Оптимальна для операций, требующих последовательного чтения больших объемов данных
Меньшая длина очереди и время отклика
Создает более высокую и стабильную нагрузку на диск
Приводит к увеличению времени отклика операций
Смещает характер нагрузки в сторону большего количества мелких операций
Снижает нагрузку на CPU для операций ввода-вывода
Увеличивает глубину очереди запросов к диску
Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).
В условиях растущих требований к обработке больших данных и аналитическим нагрузкам (OLAP) критически важной становится не только настройка самой СУБД, но и тонкая оптимизация операционной системы, на которой она работает. Однако в современных исследованиях и практических руководствах наблюдается значительный пробел: рекомендации по настройке PostgreSQL часто ограничиваются параметрами самой СУБД, в то время как влияние параметров ядра Linux на производительность базы данных остаётся малоизученной областью.
Данная работа направлена на заполнение этого пробела. Фокус исследования сосредоточен на влиянии параметра ядра Linux vm.vfs_cache_pressure на производительность PostgreSQL под синтетической OLAP-нагрузкой. Этот параметр контролирует агрессивность, с которой ядро освобождает кэш файловой системы (VFS cache), что в теории может напрямую влиять на поведение СУБД, активно работающей с файлами данных.
Исследование носит экспериментальный характер и построено на методологии нагрузочного тестирования с использованием специализированного инструмента pg_expecto. В качестве тестовой среды используется конфигурация, типичная для небольших аналитических серверов: 8 CPU, 8 GB RAM, дисковая подсистема, подверженная ограничениям пропускной способности. Это позволяет смоделировать условия, в которых грамотная настройка ОС может стать ключом к раскрытию дополнительной производительности или, наоборот, источником проблем.
Ценность данной работы заключается в её практической ориентированности. Она предоставляет администраторам баз данных и системным инженерам не только конкретные данные о влиянии настройки, но и методологию анализа комплексного поведения системы (СУБД + ОС) под нагрузкой, выходящую за рамки простого мониторинга TPS (транзакций в секунду).
Отсутствие специализированных исследований: Поиск в научных базах данных (Google Scholar, IEEE Xplore) и технических блогах по запросам "vfs_cache_pressure PostgreSQL performance", "Linux kernel tuning for database workload" не выявил работ, фокусирующихся на экспериментальном изучении данного конкретного взаимодействия. Основная масса материалов предлагает общие советы или рассматривает настройку памяти PostgreSQL в отрыве от тонких параметров ОС.
Оценить влияние изменения параметра vm.vfs_cache_pressure на производительность СУБД и инфраструктуры при синтетической нагрузке, имитирующей OLAP.
vm.dirty_expire_centisecs=3000
vm.dirty_ratio=30
vm.dirty_background_ratio=10
vm.swappiness=10
read_ahead_kb=4096
shared_buffers = '4GB'
effective_cache_size = '6GB'
work_mem = '32MB'
Отношение прочитанных блоков shared_buffers к измененным блокам shared_buffers (OLAP):
vm.vfs_cache_pressure = 100 : 177.98
vm.vfs_cache_pressure = 50 : 184.26
vm.vfs_cache_pressure = 150 : 172.22
Медианные значения операционной скорости:
vm.vfs_cache_pressure = 100 : 15 154 (baseline)
vm.vfs_cache_pressure = 50 : 16 185 (-11.27%)
vm.vfs_cache_pressure = 150 : 15 095 (+8.65%)
Медианные значения ожиданий типа IO:
vm.vfs_cache_pressure = 100 : 16 716 (baseline)
vm.vfs_cache_pressure = 50 : 19 411 (+16,12%)
vm.vfs_cache_pressure = 150 : 16 762 (+0,27%)
Медианные значения ожиданий типа LWLock:
vm.vfs_cache_pressure = 100 : 178(baseline)
vm.vfs_cache_pressure = 50 : 113 (-36,52%)
vm.vfs_cache_pressure = 150 : 167 (-6,46%)
Медианные значения IOPS:
vm.vfs_cache_pressure = 100 : 3 502(baseline)
vm.vfs_cache_pressure = 50 : 3 479(-0,66%)
vm.vfs_cache_pressure = 150 : 3 582 (+2,28%)
Медианные значения MB/s:
vm.vfs_cache_pressure = 100 : 125(baseline)
vm.vfs_cache_pressure = 50 : 103(-17,60%)
vm.vfs_cache_pressure = 150 : 135 (+8,00%)
Входные данные для анализа
Сводный отчета по нагрузочному тестированию подготовленный pg_pexpecto по окончании нагрузочного тестирования:
Метрики производительности и ожиданий СУБД
Метрики vmstat
Метрики iostat
Корреляционный анализ ожиданий СУБД
Корреляционный анализ метрик vmstat
Корреляционный анализ метрик iostat
Общая проблема: Во всех трёх экспериментах 100% наблюдений показывают wa > 10%, что свидетельствует о системном ограничении дисковой подсистемы.
Сравнение корреляций при разных значениях vm.vfs_cache_pressure:
vm.vfs_cache_pressure=50:
Корреляция IO-wa: -0,0772 (отсутствует/отрицательная) ✅
Корреляция IO-b: 0,0609 (слабая/средняя) ℹ️
Корреляция IO-bi: 0,3650 (слабая/средняя) ℹ️
Корреляция IO-bo: 0,2693 (слабая/средняя) ℹ️
vm.vfs_cache_pressure=100:
Корреляция IO-wa: -0,9020 (отсутствует/отрицательная) ✅
Корреляция IO-b: 0,2611 (слабая/средняя) ℹ️
Корреляция IO-bi: 0,2730 (слабая/средняя) ℹ️
Корреляция IO-bo: 0,6533 (высокая) ⚠️
vm.vfs_cache_pressure=150:
Корреляция IO-wa: -0,7379 (отсутствует/отрицательная) ✅
Корреляция IO-b: 0,0000 (отсутствует/отрицательная) ✅
Корреляция IO-bi: 0,5074 (высокая) ⚠️
Корреляция IO-bo: 0,5532 (высокая) ⚠️
Вывод: Увеличение vfs_cache_pressure усиливает корреляцию IO-ожиданий с операциями чтения/записи (bi/bo), что указывает на более агрессивное управление кэшем файловой системы.
Наблюдаемый феномен:
· При vfs_cache_pressure=50: ALARM по регрессионной линии (R²=0,7, угол наклона 39,83)
· При vfs_cache_pressure=100: R²=0,03, угол наклона 10,38 (норма)
· При vfs_cache_pressure=150: R²=0,00, угол наклона 0,00 (норма)
Объяснение с точки зрения управления кэшем:
При низком значении vfs_cache_pressure(50) ядро менее агрессивно вытесняет кэш файловой системы
Это приводит к накоплению большего объёма кэшированных данных
При OLAP-нагрузке с интенсивным чтением это вызывает:
Более частые блокировки процессов в состоянии D при обращении к диску
Увеличение времени ожидания из-за конкуренции за IO-ресурсы
При значениях 100 и 150 кэш вытесняется активнее, что снижает конкуренцию и количество процессов в состоянии D
Общие характеристики нагрузки (все эксперименты):
Соотношение чтения к записи: ~180:1 (типичный OLAP-паттерн)
Очень высокая корреляция скорости операций с чтением (0,85-0,88)
Очень высокая корреляция скорости операций с записью (0,98-0,99)
Система ограничена производительностью диска
Влияние pressure на эффективность shared buffers:
HIT RATIO shared buffers: 55-58% (критически низкий во всех случаях)
Корреляция shared_blks_hit - shared_blks_read: 0,96-0,97 (очень высокая)
Вывод: vfs_cache_pressure практически не влияет на HIT RATIO PostgreSQL, так как shared buffers управляются отдельно от кэша файловой системы
Лучшие показатели у pressure=100:
Отсутствие роста процессов в состоянии D
Умеренные корреляции с операциями чтения/записи
Стабильное поведение системы
Проблемные зоны (все эксперименты):
Критически низкий HIT RATIO shared buffers (55-58%)
100% наблюдений с wa > 10%
Система ограничена производительностью диска
Рекомендации по оптимизации для OLAP-нагрузки
1. Настройки операционной системы:
Установить vm.vfs_cache_pressure = 100 (компромиссное значение)
Пересмотреть настройки vm.dirty_*:
Уменьшить vm.dirty_background_ratio с 10 до 5
Уменьшить vm.dirty_ratio с 30 до 20
Это снизит латентность записи
Проверить и оптимизировать параметры файловой системы
2. Настройки PostgreSQL для OLAP:
Увеличить shared_buffers с 4GB до 6GB (при 8GB RAM)
Увеличить work_mem с 32MB до 128-256MB для сложных сортировок
Увеличить effective_cache_size до 6-7GB
Рассмотреть увеличение max_parallel_workers_per_gather с 1 до 2-4
Установить random_page_cost = 1.0 (если используются SSD)
3. Аппаратные улучшения:
Рассмотреть переход на более быстрые диски (NVMe SSD)
Увеличить объём оперативной памяти с 8GB
Проверить балансировку нагрузки между дисками данных и WAL
Общая ситуация:
Во всех экспериментах свободная RAM < 5% в более 50% наблюдений - это норма для сервера с активной нагрузкой
Оперативная память практически полностью используется (7-7.2GB из 8GB)
Динамика memory_swpd (использование свопа):
vfs_cache_pressure=50: Рост с 209 MB до 347 MB (+138 MB за 110 минут)
vfs_cache_pressure=100: Рост с 260 MB до 328 MB (+68 MB за 111 минут)
vfs_cache_pressure=150: Рост с 246 MB до 338 MB (+92 MB за 110 минут)
Анализ скорости роста:
Наиболее медленный рост swpd при vfs_cache_pressure=100 (68 MB за период)
Наиболее быстрый рост при vfs_cache_pressure=50 (138 MB за период)
Промежуточный рост при vfs_cache_pressure=150 (92 MB за период)
Стабильность использования памяти:
Наиболее стабильное поведение при vfs_cache_pressure=100:
Наименьший рост использования свопа
Плавное изменение memory_swpd без резких скачков
Более предсказуемое управление памятью
Наименее стабильное поведение при vfs_cache_pressure=50:
Быстрый рост использования свопа
Более агрессивное вытеснение данных в своп
Статистика по экспериментам:
vfs_cache_pressure=50:
swap in: 10% наблюдений
swap out: 6.36% наблюдений
Баланс смещен в сторону чтения из свопа
При vfs_cache_pressure=100:
swap in: 9.01% наблюдений
swap out: 1.80% наблюдений
Минимальный объем записи в своп
vfs_cache_pressure=150:
swap in: 10% наблюдений
swap out: 11.82% наблюдений
Наибольший объем записи в своп
Объяснение различий:
1. vfs_cache_pressure=50:
Низкое давление на кэш файловой системы
Ядро менее агрессивно освобождает кэш
Чаще приходится читать из свопа (высокий swap in)
Относительно низкий swap out - меньше данных вытесняется
2. vfs_cache_pressure=100:
Оптимальный баланс
Кэш управляется эффективно
Минимальный swap out - редко требуется запись в своп
Умеренный swap in - меньше обращений к свопу
3. vfs_cache_pressure=150:
Высокое давление на кэш файловой системы
Ядро агрессивно освобождает кэш
Высокий swap out - активная запись в своп
Высокий swap in - частые чтения из свопа
Взаимодействие vfs_cache_pressure с настройками vm.dirty_*:
Текущие настройки:
vm.dirty_ratio=30 (запись блокируется при 30% dirty pages)
vm.dirty_background_ratio=10 (фоновая запись при 10%)
read_ahead_kb=4096 (4MB read-ahead)
Влияние pressure на dirty pages:
1. vfs_cache_pressure=50:
Медленное освобождение кэша
Больше данных остается в памяти
Более высокий риск достижения dirty_ratio
Потенциальные блокировки записи при всплесках нагрузки
2. vfs_cache_pressure=100:
Сбалансированное управление
Кэш освобождается своевременно
Меньше риск блокировок из-за dirty pages
Оптимально для текущих настроек dirty_*
3. vfs_cache_pressure=150:
Быстрое освобождение кэша
Меньше данных в кэше файловой системы
Чаще требуется чтение с диска
Возможна излишняя агрессивность для OLAP
Для OLAP с большим чтением рекомендуется:
vfs_cache_pressure=100-120 (компромиссное значение)
read_ahead_kb=8192-16384 (увеличение для последовательного чтения)
vm.dirty_background_ratio=5 (более частая фоновая запись)
vm.dirty_ratio=20 (раньше начинать синхронную запись)
Обоснование:
OLAP характеризуется последовательным чтением больших объемов данных
Большой read-ahead улучшает производительность последовательного чтения
Более низкие dirty_* значения снижают латентность записи
vfs_cache_pressure=100 обеспечивает баланс между кэшированием и доступной памятью
Ключевые наблюдения:
Все эксперименты показывают очень высокую корреляцию LWLock с user time (0.96-0.98)
Все эксперименты показывают очень высокую корреляцию LWLock с system time (0.91-0.95)
Распределение CPU времени по экспериментам:
vfs_cache_pressure=50:
us (user time): 21-61% (среднее ~30%)
sy (system time): 5-10% (среднее ~7%)
wa (I/O wait): 17-31% (среднее ~27%)
id (idle): 12-42% (среднее ~35%)
vfs_cache_pressure=100:
us (user time): 25-57% (среднее ~35%)
sy (system time): 5-10% (среднее ~7%)
wa (I/O wait): 18-29% (среднее ~25%)
id (idle): 14-41% (среднее ~33%)
vfs_cache_pressure=150:
us (user time): 22-58% (среднее ~32%)
sy (system time): 5-10% (среднее ~7%)
wa (I/O wait): 16-28% (среднее ~24%)
id (idle): 13-41% (среднее ~34%)
Влияние vfs_cache_pressure:
User time: Наиболее высокий при pressure=100 (среднее 35%)
System time: Практически идентичен во всех случаях (~7%)
I/O wait: Наименьший при pressure=150 (среднее 24%)
Idle time: Наибольший при pressure=50 (среднее 35%)
Вывод: Увеличение pressure снижает I/O wait, но незначительно увеличивает user time, что указывает на более активную обработку данных приложением.
Общая картина:
Высокая корреляция переключений контекста с прерываниями (cs-in) во всех экспериментах (0.95-0.97)
При vfs_cache_pressure=150 появляется слабая/средняя корреляция cs-sy (0.0244)
Влияние управления кэшем на переключения контекста:
Механизм влияния:
1. vfs_cache_pressure=50:
Менее агрессивное управление кэшем
Меньше системных вызовов для управления памятью
Переключения контекста в основном вызваны прерываниями от дисковых операций
2. vfs_cache_pressure=100:
Сбалансированное управление кэшем
Умеренное количество системных вызовов для управления памятью
Прерывания остаются основной причиной переключений контекста
3. vfs_cache_pressure=150:
Агрессивное управление кэшем
Увеличение системных вызовов для управления памятью
Появление корреляции cs-sy указывает на рост времени ядра на управление памятью
Объяснение корреляции cs-sy при pressure=150:
Ядро тратит больше времени на:
Вытеснение страниц из кэша файловой системы
Управление списками страниц памяти
Обработку запросов на выделение/освобождение памяти
Это приводит к увеличению system time и связанных с ним переключений контекста
Статистика по экспериментам:
vfs_cache_pressure=50:
Проценты превышения ядер CPU: 7.27%
Максимальное значение procs_r: 10 процессов
Более стабильная очередь выполнения
vfs_cache_pressure=100:
Проценты превышения ядер CPU: 16.22%
Максимальное значение procs_r: 11 процессов
Наименее стабильная очередь выполнения
vfs_cache_pressure=150:
Проценты превышения ядер CPU: 14.55%
Максимальное значение procs_r: 11 процессов
Промежуточная стабильность
Анализ стабильности:
Наиболее стабильная очередь при pressure=50:
Наименьший процент превышения ядер CPU (7.27%)
Более равномерное распределение нагрузки
Меньше конкуренции за CPU ресурсы
Наименее стабильная очередь при pressure=100:
Наибольший процент превышения ядер CPU (16.22%)
Более выраженная конкуренция за CPU
Возможные задержки в обработке запросов
1. Оптимальный диапазон значений: vfs_cache_pressure = 90-110
Обоснование:
Компромисс между производительностью и стабильностью:
vfs_cache_pressure=50: лучшая стабильность очереди выполнения, но выше I/O wait
vfs_cache_pressure=150: ниже I/O wait, но выше нагрузка на ядро (system time)
vfs_cache_pressure=100: баланс между этими крайностями
2. Сопутствующие настройки для OLAP-нагрузки:
Настройки операционной системы:
vm.swappiness = 10 (уже установлено, оптимально для серверов)
vm.dirty_background_ratio = 5 (уменьшить с 10 для более частой фоновой записи)
vm.dirty_ratio = 20 (уменьшить с 30 для снижения латентности записи)
read_ahead_kb = 16384 (увеличить для последовательного чтения OLAP)
Настройки PostgreSQL для 8 CPU ядер:
max_parallel_workers_per_gather = 2-4 (увеличить с 1 для OLAP)
max_worker_processes = 16 (уже установлено, оптимально)
max_parallel_workers = 16 (уже установлено, оптимально)
work_mem = 64-128MB (увеличить с 32MB для сложных сортировок)
Проанализировать параметра vm.vfs_cache_pressure на производительность подсистемы IO для дискового устройства, используемого файловой системой /data.
Сводный отчета по нагрузочному тестированию подготовленный pg_pexpecto по окончании нагрузочного тестирования:
Метрики iostat для дискового устройства vdd
Корреляция скорость–IOPS: слабая (0,4128).
Корреляция скорость–MB/s: очень высокая (0,8191).
Тип нагрузки: аналитическая/ETL, так как наблюдается высокая зависимость от пропускной способности диска, а не от IOPS.
Ограничивающий фактор: пропускная способность диска (MB/s).
Дополнительные наблюдения:
Утилизация диска стабильно высокая (89–94%).
Задержки чтения/записи умеренные (9–14 мс).
Нагрузка на CPU в режиме ожидания I/O (wa) составляет 18–29%.
Корреляция скорость–IOPS: отрицательная (-0,2879).
Корреляция скорость–MB/s: очень высокая (0,8017).
Тип нагрузки: аналитическая/ETL с выраженной зависимостью от пропускной способности диска.
Ограничивающий фактор: пропускная способность диска (MB/s).
Дополнительные наблюдения:
Утилизация диска близка к максимальной (95–96%).
Задержки чтения растут со временем (до 16 мс).
Отрицательная корреляция с IOPS указывает на возможные проблемы с CPU, блокировками или памятью.
Нагрузка на CPU в режиме ожидания I/O (wa) достигает 31%.
Корреляция скорость–IOPS: слабая (0,5930).
Корреляция скорость–MB/s: очень высокая (0,9735).
Тип нагрузки: аналитическая/ETL с сильной зависимостью от пропускной способности диска.
Ограничивающий фактор: пропускная способность диска (MB/s).
Дополнительные наблюдения:
Утилизация диска стабильно высокая (89–95%).
Задержки чтения/записи низкие (6–11 мс).
Нагрузка на CPU в режиме ожидания I/O (wa) снижается к концу теста (до 16%).
1. Все три эксперимента показывают схожую картину:
Производительность ограничена пропускной способностью диска (MB/s), а не IOPS.
Нагрузка носит аналитический/ETL-характер (последовательное чтение/запись больших объёмов данных).
2. Влияние vm.vfs_cache_pressure:
Изменение параметра не оказало значительного влияния на тип нагрузки и ограничивающий фактор.
Наилучшие показатели задержек и утилизации CPU наблюдаются при значении 150.
3. Рекомендации:
Увеличить пропускную способность дисковой подсистемы .
Настроить параметры PostgreSQL для аналитических нагрузок (work_mem, maintenance_work_mem, effective_io_concurrency).
Рассмотреть использование партиционирования таблиц и параллельного выполнения запросов.
vm.vfs_cache_pressure = 50:
utilization: 95,1%
r_await: 13,8 мс
w_await: 6,6 мс
IOPS: 3 490
MB/s: 116,1
aqu_sz: 43,8
cpu_wa: 27,3%
vm.vfs_cache_pressure = 100:
utilization: 92,7%
r_await: 12,5 мс
w_await: 7,0 мс
IOPS: 3 513
MB/s: 129,6
aqu_sz: 40,5
cpu_wa: 25,4%
vm.vfs_cache_pressure = 150:
utilization: 92,7%
r_await: 9,8 мс
w_await: 7,3 мс
IOPS: 3 570
MB/s: 137,5
aqu_sz: 33,5
cpu_wa: 23,6%
Задержки и утилизация диска:
r_await последовательно снижается с ростом параметра: 13,8 мс (50) → 12,5 мс (100) → 9,8 мс (150)
w_await незначительно увеличивается: 6,6 мс (50) → 7,0 мс (100) → 7,3 мс (150)
Утилизация диска максимальна при значении 50 (95,1%), при 100 и 150 стабилизируется на уровне 92,7%
Наилучшие показатели задержек чтения достигаются при максимальном значении 150
Связь с пропускной способностью и IOPS:
Пропускная способность (MB/s) монотонно растёт: 116,1 (50) → 129,6 (100) → 137,5 (150)
IOPS также увеличивается: 3 490 (50) → 3 513 (100) → 3 570 (150)
Наблюдается чёткая тенденция: чем выше vfs_cache_pressure, тем выше производительность по пропускной способности
Поведение очереди запросов (aqu_sz):
Длина очереди последовательно уменьшается: 43,8 (50) → 40,5 (100) → 33,5 (150)
Это свидетельствует о более эффективной обработке запросов при высоких значениях параметра
Уменьшение очереди коррелирует со снижением времени ожидания CPU (cpu_wa)
Увеличение vfs_cache_pressure до 150 даёт наиболее сбалансированные результаты:
Наименьшие задержки чтения (9,8 мс против 13,8 мс при 50)
Наибольшая пропускная способность (137,5 MB/s против 116,1 при 50)
Самая короткая очередь запросов (33,5 против 43,8 при 50)
Наименьшая нагрузка на CPU в режиме ожидания (23,6% против 27,3% при 50)
Параметр vfs_cache_pressure оказывает существенное влияние на производительность дисковой подсистемы:
Более высокие значения способствуют более агрессивному освобождению кэша
Это снижает contention за память и уменьшает задержки
Однако может незначительно увеличить задержки записи
Для данной аналитической нагрузки оптимальным является значение 150, которое обеспечивает лучшую пропускную способность при меньших задержках и нагрузке на систему.
Проведённое комплексное исследование убедительно демонстрирует, что параметр ядра Linux vm.vfs_cache_pressure оказывает статистически значимое и многогранное влияние на производительность PostgreSQL при OLAP-нагрузке, имитирующей последовательное чтение больших объёмов данных.
Ключевые обобщённые выводы:
Тип нагрузки является определяющим: Во всех экспериментах система упиралась в пропускную способность диска (MB/s), а не в IOPS, что характерно для аналитических (OLAP) паттернов с последовательным доступом. Это главный ограничивающий фактор в данной конфигурации.
Влияние на кэширование и память:
Параметр практически не влияет на hit ratio внутреннего кэша PostgreSQL (shared buffers), что подтверждает их независимое управление.
Однако он существенно влияет на управление кэшем файловой системы (VFS cache) и подкачкой (swap). Более низкие значения (50) приводят к меньшей агрессивности вытеснения кэша, что вызывает более быстрый рост использования свопа и большее количество процессов, блокированных в состоянии ожидания ввода-вывода (D-состояние). Более высокие значения (150) заставляют ядро активнее освобождать кэш.
Влияние на производительность диска: Наблюдается чёткая тенденция: с ростом vfs_cache_pressure увеличивается пропускная способность (MB/s) и снижаются задержки чтения (r_await). Наилучшие показатели дисковых операций были достигнуты при значении 150.
Влияние на загрузку CPU и стабильность: Значение параметра также влияет на баланс загрузки процессора. Более высокие значения снижают время ожидания ввода-вывода (wa), но могут незначительно повысить системное время (sy) из-за активного управления памятью и привести к менее стабильной очереди выполнения процессов (run queue).
Недостатки тестовой конфигурации: Исследование выявило системные проблемы, общие для всех тестов:
Критически низкий hit ratio shared buffers (55-58%), указывающий на недостаточный объём оперативной памяти для данной рабочей нагрузки.
Постоянно высокий уровень ожидания ввода-вывода (wa > 10%), подтверждающий, что диск является узким местом.
Общие рекомендации для OLAP-нагрузок на PostgreSQL:
Аппаратные улучшения (более быстрые NVMe SSD, увеличение RAM) имеют высший приоритет для снятия выявленных ограничений.
Оптимизация ОС: Уменьшение vm.dirty_* соотношений для снижения латентности записи и увеличение read_ahead_kb для ускорения последовательного чтения.
Оптимизация PostgreSQL: Увеличение shared_buffers, work_mem, effective_cache_size и настройка параметров параллельного выполнения.
В исследовании содержится кажущееся противоречие: в Части 2 оптимальным названо значение 100, а в Части 3 — 150. Причина этих разных рекомендаций заключается не в ошибке, а в разном фокусе анализа и приоритетах, которые они отражают. Это наглядная иллюстрация того, что процесс оптимизации — это всегда выбор компромиссного решения из набора альтернатив.
Рекомендация из Части 2: vm.vfs_cache_pressure = 100
Фокус анализа: Общая стабильность системы, поведение процессов, управление памятью и свопом.
Ключевые аргументы:
Стабильность процессов: Отсутствие аномального роста процессов в состоянии D (блокировка).
Управление памятью: Наиболее стабильное и предсказуемое использование свопа (наименьший рост).
Сбалансированность: Умеренные корреляции между метриками, отсутствие экстремальных паттернов.
Компромисс: Оптимальный баланс между удержанием данных в кэше и их своевременным освобождением.
Приоритет: Надёжность и предсказуемость долгосрочной работы системы.
Рекомендация из Части 3: vm.vfs_cache_pressure = 150
Фокус анализа: Максимальная производительность дисковой подсистемы, задержки и пропускная способность.
Ключевые аргументы:
Производительность диска: Наивысшая пропускная способность (137.5 MB/s) и наименьшие задержки чтения (9.8 мс).
Эффективность очереди: Самая короткая очередь запросов к диску, что указывает на более эффективную обработку.
Разгрузка CPU: Наименьшая нагрузка процессора в режиме ожидания I/O (wa).
Механизм: Агрессивное освобождение кэша снижает конкуренцию (contention) за оперативную память.
Приоритет: Максимальная скорость обработки данных и минимизация времени выполнения задач.
Заключительный вывод по выбору значения
Обе рекомендации верны в своих контекстах. Выбор между 100 и 150 — это классический инженерный компромисс между «быстро» и «стабильно».
Для продакшен-среды, где критически важны предсказуемость, стабильность и отсутствие аномалий (внезапные блокировки процессов), следует придерживаться рекомендации vm.vfs_cache_pressure = 100 (или диапазон 90-110).
Для выделенных ETL-задач или пакетной аналитической обработки, где ключевая цель — минимизировать время выполнения и диск является подтверждённым узким местом, можно обоснованно применить значение vm.vfs_cache_pressure = 150 для получения максимальной пропускной способности, отдавая себе отчёт в потенциально возросшей нагрузке на подсистему памяти ядра.
Таким образом, исследование не даёт единственно верного ответа, а предоставляет администратору обоснованный выбор в зависимости от конкретных бизнес-требований и приоритетов, подчёркивая, что эффективная оптимизация — это всегда поиск баланса между конфликтующими целями системы.