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. Корреляция проблем с ростом нагрузки
Четко прослеживается причинно-следственная связь:
- Рост числа подключений к PostgreSQL (с 7 до 22) увеличивает количество одновременных рабочих процессов.
- Это приводит к линейному росту пользовательской нагрузки на CPU (us), но нелинейному — к росту очереди (procs_r) и переключений контекста (cs).
- При достижении критического числа параллельных задач планировщик ОС не справляется, что проявляется в скачкообразном росте системного времени (sy).
- Одновременно с этим рабочему набору данных становится недостаточно выделенной оперативной памяти, о чем сигнализирует падение 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 даст ограниченный эффект.