В ходе исследования были проведены два эксперимента — базовый (Эксперимент 1) и оптимизированный (Эксперимент 8) — с целью оценки влияния настроек ввода-вывода на производительность СУБД. Анализ охватил метрики производительности, время ожиданий, корреляции, а также системные показатели (vmstat). Результаты выявили как значительные улучшения, так и новые вызовы, требующие дальнейшей оптимизации на уровне операционной системы.
GitHub - Комплекс pg_expecto для статистического анализа производительности и нагрузочного тестирования СУБД PostgreSQL
Глоссарий терминов | Postgres DBA | Дзен
Начальные настройки
Текущая оптимизация настроек инфраструктуры
Запрос
1.summary.txt - Эксперимент-1 (Базовые настройки IO)
8.summary.txt - Эксперимент-8 (Оптимизация настроек IO)
Подготовь сравнительные анализ производительности и ожиданий СУБД и метрик vmstat
Состав отчета :
**Сравнение метрик производительности и ожиданий СУБД**
**Сравнение и анализ корреляций и паттернов ожиданий СУБД**
**Сравнение проблемы производительности СУБД**
**Диагностика и сравнение узких мест СУБД**
**Сравнение метрик vmstat**
**Сравнение и анализ корреляций vmstat**
**Сравнение критических проблемы vmstat**
**Диагностика и сравнение узких мест vmstat**
**Итоговый сравнительный анализ по производительности СУБД и vmstat**
1. Сравнение метрик производительности и ожиданий СУБД
Производительность (SPEED):
- Эксперимент 1: 265 388 - 284 895 единиц
- Эксперимент 8: 433 242 - 473 502 единиц
- Улучшение: +63% (минимальное значение), +66% (максимальное значение)
Ожидания СУБД (WAITINGS):
- Эксперимент 1: 26 976 - 72 905 единиц
- Эксперимент 8: 22 990 - 68 097 единиц
- Улучшение: -15% (минимальное значение), -6.6% (максимальное значение)
Ключевые изменения:
- Значительно возросла производительность при снижении общего времени ожиданий
- Коэффициент детерминации R² для SPEED увеличился с 0.38 до 0.77, что указывает на лучшую предсказуемость производительности
- Угол наклона регрессии для SPEED стал более отрицательным (-41.32 vs -31.57), что означает более выраженную тенденцию снижения производительности при росте нагрузки
2. Сравнение и анализ корреляций и паттернов ожиданий СУБД
Корреляция SPEED-WAITINGS:
- Эксперимент 1: -0.71 (сильная отрицательная)
- Эксперимент 8: -0.93 (очень сильная отрицательная)
- Вывод: В оптимизированной конфигурации производительность стала более чувствительной к времени ожиданий
Распределение типов ожиданий:
- IO ожидания остались доминирующими в обоих экспериментах (~99%)
- В эксперименте 8 появились дополнительные типы LWLock (WALInsert, XidGen), что может указывать на более интенсивную работу с журналом транзакций
Паттерны запросов:
- QueryID 65003243407475111 (scenario1) увеличил долю вызовов с 12.3M до 21.0M
- Доля ожиданий IO для scenario1 увеличилась с 80.18% до 83.24%
3. Сравнение проблем производительности СУБД
Общие проблемы (оба эксперимента):
- IO остается главным узким местом (ожидания IO составляют ~99% всех ожиданий)
- Высокая корреляция WAITINGS-IO (1.0 в обоих случаях)
Улучшения в эксперименте 8:
- Снижение общего времени ожиданий на 15-50%
- Улучшение корреляции между различными типами ожиданий
4. Диагностика и сравнение узких мест СУБД
Эксперимент 1:
- Основная проблема: Ожидания IO (DataFileRead - 99.93%)
- Вторичные проблемы: Lock (extend - 67.61%), LWLock (ProcArray - 51.61%)
Эксперимент 8:
- Основная проблема: Ожидания IO (DataFileRead - 99.68%)
- Вторичные проблемы: более диверсифицированы (Lock: extend - 57.01%, LWLock: ProcArray - 40.61%, BufferContent - 26.66%)
5. Сравнение метрик vmstat
Процессы:
- Эксперимент 1: procs_b (блокированные) 5-14
- Эксперимент 8: procs_b 5-13
- Изменение: Незначительное улучшение
Ввод-вывод:
- Эксперимент 1: io_bi 27 584-29 457; io_bo 16 394-20 019
- Эксперимент 8: io_bi 27 570-29 939; io_bo 20 617-25 034
- Изменение: Увеличение операций записи (bo) на ~25%
CPU:
- Эксперимент 1: cpu_wa 44-50%
- Эксперимент 8: cpu_wa 39-45%
- Улучшение: Снижение времени ожидания IO на CPU
6. Сравнение и анализ корреляций vmstat
Критические корреляции:
IO-b (процессы в uninterruptible sleep):
- Эксперимент 1: 0.9755 (ALARM)
- Эксперимент 8: 0.9690 (ALARM)
- Состояние: Без изменений
IO-bo (блоки на запись):
- Эксперимент 1: 0.6559 (WARNING)
- Эксперимент 8: 0.9402 (ALARM)
- Ухудшение: Корреляция усилилась
LWLock-us (user time):
- Эксперимент 1: 0.9100 (ALARM)
- Эксперимент 8: 0.9551 (ALARM)
- Ухудшение: Корреляция усилилась
7. Сравнение критических проблем vmstat
Общие проблемы (оба эксперимента):
- Высокое время ожидания IO (wa > 10% в 100% наблюдений)
- Высокая корреляция IO-b (процессы ждут ответа от диска)
- Недостаток свободной RAM (<5% в 100% наблюдений)
Изменения в эксперименте 8:
- Появилась высокая корреляция IO-bi (0.9000, ALARM)
- Усилилась корреляция IO-bo (с 0.6559 до 0.9402)
- Незначительно снизился cpu_wa (с 44-50% до 39-45%)
8. Диагностика и сравнение узких мест vmstat
Эксперимент 1:
- Основное узкое место: Подсистема ввода-вывода
- Вторичные проблемы: Высокий user time из-за LWLock
Эксперимент 8:
- Основное узкое место: Подсистема ввода-вывода (усилившаяся проблема)
- Новая проблема: Высокая нагрузка на чтение/запись блоков (bi/bo)
- Сохраняющаяся проблема: Конкуренция за CPU из-за LWLock
9. Итоговый сравнительный анализ по производительности СУБД и vmstat
Положительные изменения после оптимизации:
- Увеличение производительности СУБД на 63-66%
- Снижение общего времени ожиданий СУБД на 6.6-15%
- Улучшение предсказуемости производительности (R² вырос с 0.38 до 0.77)
- Снижение времени ожидания IO на CPU (cpu_wa снизился на 5%)
Отрицательные изменения/сохраняющиеся проблемы:
- Усилилась корреляция между IO и операциями чтения/записи
- Возросла нагрузка на подсистему ввода-вывода (увеличились bi/bo)
- Сохраняется проблема процессов в состоянии uninterruptible sleep
- Не решена проблема нехватки свободной памяти
Выводы:
- Оптимизация настроек IO улучшила общую производительность, но выявила новые узкие места
- Подсистема ввода-вывода остается главным ограничивающим фактором, причем нагрузка на нее увеличилась
- Улучшение производительности СУБД достигнуто ценой увеличения нагрузки на IO-подсистему
- Требуется дальнейшая оптимизация для снижения корреляции между IO и операциями чтения/записи
- Проблема с памятью требует отдельного внимания, так как остается критической в обоих конфигурациях
Рекомендация: Дальнейшая оптимизация должна быть направлена на балансировку нагрузки между CPU и IO, а также на решение проблемы нехватки оперативной памяти.
Продолжение экспериментов по тонкой оптимизаций параметров операционной системы
Запрос
settings.txt - конфигурация СУБД и инфраструктуры
1.summary.vmstat.txt - Эксперимент-1 (Базовые настройки IO)
8.summary.vmstat.txt - Эксперимент-8 (Оптимизация настроек IO)
Подготовь список возможных оптимизаций со стороны операционной системы, для дальнейшей оптимизации производительности данной инфраструктуры:
**Получение текущего значения параметра настройки операционной системы**
**Обоснование изменения значения параметра настройки операционной системы**
**Изменение значения параметра настройки операционной системы**
План изменений
На основе анализа предоставленных данных (конфигурация инфраструктуры, результаты базового и оптимизированного экспериментов) можно выделить следующие критические проблемы операционной системы, требующие оптимизации:
- Высокая нагрузка на I/O подсистему (wa > 10% в 100% наблюдений, много процессов в D состоянии).
- Недостаток свободной оперативной памяти (<5% в 100% наблюдений).
- Высокое соотношение чтения к записи (OLAP-паттерн), что требует оптимизации кэширования и стратегии сброса данных на диск.
Вот список рекомендуемых оптимизаций на стороне ОС (Linux):
1. Оптимизация управления "грязной" памятью (Dirty Pages)
Проблема: Слишком агрессивные или, наоборот, пассивные настройки могут приводить к "лавинообразному" сбросу данных на диск, вызывая пики нагрузки (io_wa) и рост процессов в состоянии D (непрерываемый сон).
1️⃣Параметр: vm.dirty_background_ratio / vm.dirty_background_bytes
- Получение текущего значения: sysctl vm.dirty_background_ratio
- Обоснование: Определяет процент от общей памяти, при превышении которого система фоново начинает записывать "грязные" страницы на диск. При высоком OLAP-чтении и нехватке памяти для кэша нужно более агрессивно освобождать RAM под новые данные, но без фанатизма, чтобы не создавать избыточную фоновую запись.
- Рекомендуемое изменение: Уменьшить значение (например, с типичных 10% до 3-5%). Или задать абсолютное значение в байтах для более точного контроля.
- Изменение значения:
# Временное изменение
sysctl -w vm.dirty_background_ratio=3
# ИЛИ использование байт (например, для 150MB)
sysctl -w vm.dirty_background_bytes=157286400
# Постоянное изменение - добавить в /etc/sysctl.conf
echo "vm.dirty_background_ratio = 3" >> /etc/sysctl.conf
sysctl -p
2️⃣Параметр: vm.dirty_ratio / vm.dirty_bytes
- Получение текущего значения: sysctl vm.dirty_ratio
- Обоснование: Определяет максимальный процент "грязной" памяти, при достижении которого процессы будут блокироваться (D состояние) на время записи. Это напрямую связано с алертом IO-b. Нужно снизить этот порог, чтобы процессы блокировались реже и на более короткое время.
- Рекомендуемое изменение: Уменьшить значение (например, с типичных 20% до 10-15%).
- Изменение значения:
sysctl -w vm.dirty_ratio=10
echo "vm.dirty_ratio = 10" >> /etc/sysctl.conf
sysctl -p
3️⃣Параметр: vm.dirty_expire_centisecs
- Получение текущего значения: sysctl vm.dirty_expire_centisecs
- Обоснование: Определяет время (в сотых долях секунды), в течение которого "грязная" страница может находиться в памяти перед тем, как её необходимо записать. Уменьшение значения делает запись более частой, но менее объемной "пачками", что сглаживает нагрузку на диск.
- Рекомендуемое изменение: Уменьшить (например, с 3000 (30 сек) до 1000-1500 (10-15 сек)).
- Изменение значения:
sysctl -w vm.dirty_expire_centisecs=1000
echo "vm.dirty_expire_centisecs = 1000" >> /etc/sysctl.conf
sysctl -p
2. Оптимизация политики Swappiness
Проблема: При почти полной загрузке RAM (free < 5%) система может начать агрессивно использовать swap, даже если swap не используется явно (si/so=0 в данных). Это может создавать ненужную нагрузку на I/O и CPU.
1️⃣Параметр: vm.swappiness
- Получение текущего значения: sysctl vm.swappiness (обычно 60).
- Обоснование: Управляет склонностью ядра к вытеснению страниц из оперативной памяти в swap. Для сервера БД, где важна производительность дисковых операций, свопинг часто вреден. Поскольку данных для свопинга нет, можно резко снизить это значение, чтобы ядро в первую очередь сбрасывало на диск кэш файловой системы ("грязные" страницы), а не искало кандидатов на своп.
- Рекомендуемое изменение: Уменьшить до 1-10.
- Изменение значения:
sysctl -w vm.swappiness=5
echo "vm.swappiness = 5" >> /etc/sysctl.conf
sysctl -p
3. Выбор и настройка I/O Scheduler (планировщика дисков)
Проблема: Слишком большая очередь (procs_b) и высокий io_wa могут быть вызваны неоптимальным планировщиком. В виртуальной среде (KVM) планировщики deadline или none (noop) часто работают лучше, чем cfq (completely fair queuing).
1️⃣Параметр: I/O Scheduler для дисков данных (vdd, vdc, vdb).
- Получение текущего значения: cat /sys/block/vd[x]/queue/scheduler (например, для vdd).
- Обоснование: Для виртуальных дисков в KVM, где гостевая ОС не управляет физическим железом, накладные расходы сложных планировщиков (cfq) могут быть излишни. Планировщик deadline обеспечивает предсказуемое время отклика, а noop просто передает запросы гипервизору, что часто оптимально.
- Рекомендуемое изменение: Установить deadline или none для дисков с данными (vdd, vdc). Для системного диска (vda) можно оставить cfq или deadline.
- Изменение значения:
# Для каждого диска данных (vdd, vdc, vdb)
echo "deadline" > /sys/block/vdd/queue/scheduler
# ИЛИ для noop (часто лучше в KVM/VirtIO)
echo "none" > /sys/block/vdd/queue/scheduler
# Для автоматизации при загрузке
# Создать/отредактировать файл /etc/udev/rules.d/60-io-schedulers.rules
# Добавить правило (пример для VirtIO дисков):
ACTION=="add|change", KERNEL=="vd[b-z]", ATTR{queue/scheduler}="deadline"
# Перезапустить udev или перезагрузиться
udevadm control --reload-rules && udevadm trigger
❓4. Увеличение лимитов на количество открытых файлов и процессов (опционально)
Проблема: При высокой нагрузке и большом количестве соединений к БД (max_connections=1000) стандартные лимиты ОС могут быть исчерпаны.
Параметр: nofile (макс. число открытых файлов) и nproc (макс. число процессов) для пользователя postgres.
- Получение текущего значения: ulimit -n и ulimit -u (от пользователя postgres) или cat /etc/security/limits.conf.
- Обоснование: PostgreSQL использует много файловых дескрипторов (на каждое соединение, на каждый файл таблицы). Лимиты должны быть выше, чем max_connections + запас.
- Рекомендуемое изменение: Установить nofile не менее 65535 и nproc не менее 4096.
- Изменение значения:
# В файле /etc/security/limits.conf или лучше в /etc/security/limits.d/postgres.conf
echo "postgres soft nofile 65535" >> /etc/security/limits.d/postgres.conf
echo "postgres hard nofile 65535" >> /etc/security/limits.d/postgres.conf
echo "postgres soft nproc 8192" >> /etc/security/limits.d/postgres.conf
echo "postgres hard nproc 8192" >> /etc/security/limits.d/postgres.conf
# Также проверить системный лимит на уровне systemd (если используется)
# в /etc/systemd/system.conf или сервисном файле postgresql.service
# DefaultLimitNOFILE=65535
⚠️Порядок применения и проверки:
- Сделать бэкап текущих настроек (sysctl -a > sysctl_backup.conf, cp /etc/security/limits.conf /etc/security/limits.conf.backup).
- Вносить изменения по одному или малыми группами (например, сначала vm.dirty_*, потом swappiness, потом планировщик).
- После каждого изменения проводить нагрузочное тестирование и сравнивать метрики wa, procs_b, io_bi/bo, memory_free.
- Мониторить логи ОС (dmesg, /var/log/syslog) на предмет ошибок или предупреждений.
- Изменения через sysctl -w действуют до перезагрузки. После нахождения оптимальных значений зафиксировать их в /etc/sysctl.conf.
⚠️Важное предупреждение:
Настройки vm.dirty_* очень чувствительны и зависят от общей нагрузки и паттерна работы. Резкое уменьшение значений может, наоборот, увеличить нагрузку на I/O из-за постоянного фонового сброса. Необходим тщательный подбор на тестовой нагрузке.
ℹ️Итог:
Оптимизация настроек СУБД позволила увеличить производительность на 63–66% и снизить время ожиданий на 6,6–15%, а также улучшить предсказуемость работы системы. Однако возросла нагрузка на подсистему ввода-вывода, сохранились проблемы с нехваткой памяти и процессами в состоянии непрерываемого сна. Для дальнейшего улучшения рекомендуется оптимизация управления памятью, выбор планировщика дисков и настройка параметров ОС, направленных на балансировку нагрузки между CPU и IO.