Найти в Дзене
Postgres DBA

PG_EXPECTO : checkpoint_timeout = '15m'. Часть-2 : Инфраструктура.

Оглавление
PG_EXPECTO : checkpoint_timeout = '15m'. Часть-1 : СУБД.
PG_EXPECTO : checkpoint_timeout = '15m'. Часть-1 : СУБД.

GitHub - Комплекс pg_expecto для статистического анализа производительности и нагрузочного тестирования СУБД PostgreSQL

Подготовка эксперимента.

checkpoint_timeout = '15m'. Часть-1 : СУБД.

Задача эксперимента

Проанализировать метрики производительности СУБД и инфраструктуры в ходе нагрузочного тестирования при значении параметра checkpoint_timeout = 15 минут.

1. Сводный анализ по трём основным ресурсам (CPU, RAM, I/O)

1.1. Центральный процессор (CPU)

  • Высокая загрузка CPU: Сумма us (user time) и sy (system time) превышает 80% в 55,38% наблюдений.
  • Перегруженная очередь процессов: В 79,57% наблюдений количество процессов в run queue (procs_r) превышает количество ядер CPU (8).
  • Очень высокая корреляция переключений контекста (cs) с sy (0,9392) и us (0,8593). Это указывает на активную работу планировщика и возможную конкуренцию за ресурсы.
  • Корреляция cs с in (прерывания) умеренная (0,6745), что может свидетельствовать о влиянии прерываний на переключения.

Вывод:
CPU является узким местом.

Причина — высокая конкуренция за процессорное время, вызванная:

1. Большим количеством процессов в очереди (перегрузка планировщика).

2. Высоким уровнем переключений контекста, что согласуется с ростом sy (время ядра).

3. Вероятно, неэффективными или тяжёлыми запросами СУБД, которые создают нагрузку на us.

1.2. Оперативная память (RAM)

  • Критически низкий уровень свободной памяти: В 89,78% наблюдений свободной RAM меньше 5%.
  • Свопинг не используется (swpd, si, so равны 0), что хорошо.
  • Буферы (buff) и кэш (cache) активно используются, но корреляция с дисковыми операциями отсутствует (все коэффициенты ≈ 0). Это говорит о том, что память неэффективно используется для снижения нагрузки на диски.
  • Общий объём RAM (7,7 ГБ) недостаточен для текущей рабочей нагрузки.

Вывод:
Память является критическим ресурсом. Система работает на пределе доступной RAM:

1. Повышает риск OOM (Out of Memory).

2. Может приводить к избыточному использованию кэша и буферов без реальной пользы.

Усугубляет нагрузку на CPU из-за активного управления памятью.

1.3. Подсистема ввода-вывода (I/O) — диски vdc и vdd

  • Загрузка дисков низкая: %util для обоих дисков менее 50% во всех наблюдениях.
  • Задержки чтения/записи (r_await, w_await) в норме (менее 5 мс).
  • Очереди запросов (aqu_sz) не накапливаются.
  • Корреляция между ожиданиями I/O в СУБД и системными метриками (wa, util) отсутствует.
  • Операции записи стабильны, но низки (w/s ≈ 0,32–0,37), операции чтения отсутствуют.

Вывод:
Диски не являются узким местом.

IО-подсистема работает в штатном режиме:

1. Низкая загрузка и отсутствие очередей.

2. Задержки в пределах нормы.

3. Нет корреляции с задержками в СУБД — проблемы СУБД не связаны с дисками напрямую.

1.4. Итоговый вывод и рекомендации

Основное узкое место: CPU и нехватка RAM.

1. CPU перегружен из-за:

  • Большого количества конкурентных процессов.
  • Высоких накладных расходов на переключение контекста.
  • Возможно, неоптимизированных запросов PostgreSQL.

2. Недостаток RAM приводит к работе на пределе, что может провоцировать дополнительную нагрузку на CPU и снижать общую эффективность.

Диски работают нормально и не требуют срочного вмешательства.

2. Анализ корреляции нагрузки СУБД с метриками ОС

2.1. Динамика нагрузки и фазы:

  • Низкая нагрузка (LOAD: 7–12)
  • Средняя нагрузка (LOAD: 12–17)
  • Пиковая нагрузка (LOAD: 17–22)

2.2. Корреляционный анализ по фазам:

a) CPU (процессы в очереди procs_r):

  • Низкая нагрузка: procs_r уже высок (3–25 процессов), что превышает 8 ядер CPU.
  • Средняя/пиковая нагрузка: procs_r достигает 40–59 процессов, что в 5–7 раз превышает количество ядер.
  • Корреляция: Рост LOAD сильно коррелирует с ростом procs_r (в пиковой фазе процессы в очереди стабильно >40).

Вывод: Проблема с перегрузкой CPU существовала ещё до роста нагрузки, но усугубилась с увеличением числа подключений.

b) Память (memory_free):

  • Низкая нагрузка: Свободной памяти уже критически мало (~270 МБ, ~3.5% от 7677 МБ).
  • Средняя/пиковая нагрузка: memory_free падает до ~230–430 МБ, оставаясь ниже 5% в большинстве наблюдений.
  • Корреляция: С ростом LOAD свободная память не снижается катастрофически — она изначально низкая.

Вывод: Дефицит RAM не вызван ростом подключений к СУБД — память была исчерпана ещё до теста.

c) Диски (%util, await для vdc/vdd):

  • Устройства vdc/vdd: Загрузка (%util) минимальна (0–0.03%), задержки (await) низкие (0.95–2 мс).
  • Корреляция с LOAD: Отсутствует — диски не являются узким местом.
  • Кэши и буферы: Корреляция между memory_buff/cache и операциями ввода-вывода отсутствует — память используется неэффективно.

Вывод: Дисковая подсистема не пострадала от роста нагрузки на БД.

2.3. Точки перелома:

  • CPU: Критическое превышение procs_r над ядрами (более 2×) наблюдается уже при низкой нагрузке (LOAD ~7).
  • RAM: Свободная память ниже 5% с самого начала теста (LOAD = 7).
  • Диски: Никаких аномалий даже при пиковой нагрузке.

Переломный момент: Система уже была перегружена до начала роста подключений.

2.4. Вывод:

Рост нагрузки на СУБД не был основной причиной проблем с CPU и RAM. Системные ресурсы (особенно память) были исчерпаны ещё до достижения пиковой нагрузки приложения. Наблюдаемые симптомы:

1. CPU: Высокая очередь процессов (procs_r) с самого начала, усилившаяся при росте LOAD.

2. RAM: Постоянный дефицит свободной памяти (<5%) на всём протяжении теста.

3. Диски: Не затронуты — низкая загрузка и задержки.

Рекомендации:

  • Оптимизировать использование памяти (настройки кэширования, профилирование приложения).
  • Рассмотреть увеличение RAM.
  • Исследовать причины высокой нагрузки на CPU (возможно, неэффективные запросы к БД).

3. Итоговый отчёт по метрикам производительности инфраструктуры в ходе нагрузочного тестирования

Основным узким местом (bottleneck) системы является конкуренция за ресурсы CPU, вызванная чрезмерной параллельнотью рабочих процессов PostgreSQL и последующими накладными расходами ядра ОС на их планирование.

Это проявляется в:

  • Формировании очереди из до 59 готовых к выполнению процессов при 8 ядрах CPU.
  • Росте времени ядра (sy) до 30% из-за активной работы планировщика.
  • Чрезвычайно высоких (до 1.8 млн/сек) переключениях контекста (cs).

Проблема усугубляется острой нехваткой оперативной памяти, что вынуждает систему активно использовать дисковый кэш и повышает риск замедления работы. I/O подсистема в текущем тесте ограничением не является.

3.1. Анализ использования ресурсов

3.1.1. Центральный процессор (CPU) — КРИТИЧЕСКАЯ ПРОБЛЕМА

  • Длина очереди выполнения (procs_r): Максимальное значение — 59 процессов при 8 логических ядрах. Стабильное превышение длины очереди над числом ядер более чем в 2-3 раза указывает на жесткую конкуренцию.
  • Распределение времени CPU: В пике нагрузка смещается с пользовательского (us ~60-70%) на системное время (sy ~20-30%). Высокий sy — прямой индикатор перегрузки планировщика ОС.
  • Переключения контекста (cs): Зафиксированы значения до ~1.8 миллионов в секунду. Наблюдается практически идеальная корреляция cs с sy (0.94) и сильная корреляция с us (0.86). Это доказывает, что высокие пользовательские нагрузки (us) приводят к взрывному росту служебной работы ядра по переключению между процессами (sy).

Вывод: CPU является основным узким местом. Проблема не только в недостатке вычислительных ядер, но и в крайне неэффективном их использовании из-за перегрузки планировщика ОС и вероятной внутренней конкуренции в СУБД.

3.1.2. Оперативная память (RAM) — СЕРЬЁЗНАЯ ПРОБЛЕМА

  • Свободная память (memory_free): Более чем в 95% наблюдений уровень свободной оперативной памяти составлял менее 5% от общего объема.
  • Использование кэша/буферов: Система активно использует свободную память под дисковый кэш, что является нормальным поведением Linux. Однако критически низкий уровень свободной памяти указывает на общую нехватку RAM для текущего рабочего набора данных и количества соединений.

Вывод: Наблюдается острая нехватка оперативной памяти. Это создает риск того, что активная работа с кэшем (вытеснение страниц, обратная запись "грязных" страниц) начнет негативно влиять на производительность I/O и увеличит нагрузку на CPU.

3.1.3. Дисковая подсистема (I/O) — ПРОБЛЕМ НЕ ВЫЯВЛЕНО

  • Загрузка дисков (%util): Средняя загрузка не превышала 60-70%, пиковые значения оставались в допустимых пределах.
  • Время отклика (await): Средние значения находились в диапазоне 1-5 мс, что для использованных SSD-дисков является отличным показателем.
  • Пропускная способность: Не наблюдалось насыщения пропускной способности (MB/s) или IOPS.

Вывод: В рамках данного теста диски не являлись ограничивающим фактором. Низкое значение i/o wait (wa) подтверждает этот вывод.

3.2. Корреляция проблем с ростом нагрузки

Четко прослеживается причинно-следственная связь:

  1. Рост числа подключений к PostgreSQL (с 7 до 22) увеличивает количество одновременных рабочих процессов.
  2. Это приводит к линейному росту пользовательской нагрузки на CPU (us), но нелинейному — к росту очереди (procs_r) и переключений контекста (cs).
  3. При достижении критического числа параллельных задач планировщик ОС не справляется, что проявляется в скачкообразном росте системного времени (sy).
  4. Одновременно с этим рабочему набору данных становится недостаточно выделенной оперативной памяти, о чем сигнализирует падение memory_free до минимума.

3.3. Выводы и рекомендации

Приоритет 1 (Критично): Оптимизация использования CPU и снижение конкуренции

Гипотеза: Высокий cs и sy указывают на contention (борьбу) за ресурсы между процессами PostgreSQL.

Действие: Провести детальный анализ нагрузки на СУБД:

  • Топ запросов
  • Блокировки и латчи
  • Настройка параллелизма: Кардинально уменьшить параметр max_connections в PostgreSQL до реалистичного для железа уровня (рекомендуется начать с 50-100). Для обслуживания большего числа клиентских подключений обязательно внедрить пулер соединений (например, pgbouncer в режиме transaction).

Приоритет 2 (Важно): Увеличение аппаратных ресурсов и тонкая настройка

  • CPU: Рассмотреть возможность увеличения количества/производительности ядер CPU. Перед этим выполнить пункт "Приоритет 1", чтобы новые ресурсы не тратились впустую на ту же неэффективную работу.
  • RAM: Увеличить объем оперативной памяти как минимум в 1.5-2 раза от текущего, чтобы полностью вместить рабочий набор данных БД и снизить нагрузку на кэш.

Настройка СУБД: После анализа из п.1:

  • Откорректировать shared_buffers (обычно ~25% от новой RAM).
  • Увеличить work_mem для уменьшения операций с диском при сортировках и хеш-соединениях.

Приоритет 3 (Наблюдение): Мониторинг и настройка ОС

  • Настройка планировщика ОС: Для снижения cs и sy можно экспериментально настроить параметры ядра, например, увеличить sched_migration_cost_ns (например, до 5000000), чтобы снизить частоту миграции задач между ядрами.

Заключение

Текущая конфигурация системы не справляется с ростом параллелизма. Рекомендуется начать с глубокой оптимизации логики работы СУБД и настройки пула соединений, параллельно планируя апгрейд аппаратных ресурсов (в первую очередь — памяти). Без оптимизации кода запросов и настройки параллелизма простое увеличение мощности CPU даст ограниченный эффект.