Налаштування Connection Pooling (PgBouncer/ProxySQL) для веб-додатку
Ми часто стикаємося з ситуацією, коли без пулінгу з'єднань кожен HTTP-запит до PostgreSQL або MySQL відкриває окреме TCP-з'єднання. Встановлення з'єднання займає 5–50 мс і потребує виділення ~5–10 MB пам'яті на стороні бази. При 500 одночасних запитах це 500 з'єднань, кожне з яких тримає фоновий процес. Без пулера база даних швидко впирається в ліміт max_connections, що призводить до помилок 500 і падіння продуктивності. Connection pooling за допомогою PgBouncer або ProxySQL — це стандарт для промислових веб-додатків. Налаштування пулінгу окупається за 2–3 місяці за рахунок зниження витрат на хмарні сервери до 70%, що економить від $1000 на місяць. У цій статті ми розповімо, як налаштувати PgBouncer для PostgreSQL і ProxySQL для MySQL, щоб усунути ці проблеми. Наш багаторічний досвід показує, що правильно налаштований connection pooler може знизити навантаження на БД на 50–80% і позбавити від простоїв. Transaction mode в PgBouncer збільшує пропускну здатність у 5–10 разів порівняно з session mode, а PgBouncer у 20 разів легше за ProxySQL за споживанням пам'яті (2 MB проти 40 MB). Замовте безкоштовний аудит — підберемо оптимальне рішення під ключ.
Коли це потрібно
Симптоми проблеми зі з'єднаннями: max_connections в PostgreSQL досягає ліміту (за замовчуванням 100), додаток отримує помилку FATAL: remaining connection slots are reserved, час відповіді бази зростає нелінійно при навантаженні. Для MySQL/MariaDB аналогічно — Too many connections. Пулінг потрібен при піковій кількості воркерів додатку > 50 і при використанні PHP-FPM, Gunicorn, Unicorn — тобто там, де кожен процес тримає своє з'єднання. Оптимізація підключень до БД дозволяє заощадити до 70% бюджету на хмарні бази даних.
Як PgBouncer знижує навантаження на PostgreSQL?
PgBouncer — легковаговий проксі (один процес, ~2 MB RAM) з трьома режимами пулінгу. Найчастіше ми використовуємо transaction mode: з'єднання займається лише на час транзакції. Це дає максимальну ефективність, але потребує адаптації prepared statements.
Кроки з налаштування PgBouncer
- Встановлення пакету:
apt install pgbouncer - Редагування конфігурації
/etc/pgbouncer/pgbouncer.ini(див. нижче) - Створення файлу користувачів
/etc/pgbouncer/userlist.txt - Перезапуск служби:
systemctl restart pgbouncer - Налаштування додатку на порт 6432
Конфігурація /etc/pgbouncer/pgbouncer.ini:
[databases]
myapp = host=127.0.0.1 port=5432 dbname=myapp
[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 20
min_pool_size = 5
reserve_pool_size = 5
reserve_pool_timeout = 3
server_idle_timeout = 600
При default_pool_size = 20 PgBouncer тримає максимум 20 реальних з'єднань до PostgreSQL, приймаючи до 1000 клієнтських. Підбирати розмір пулу потрібно під навантаження: формула — (кількість ядер CPU сервера БД) * 2 + кількість дисків. База з пулінгом витримує 10 000 запитів/с замість 1000.
Підключення додатку через PgBouncer
У Laravel .env:
DB_HOST=127.0.0.1
DB_PORT=6432
DB_DATABASE=myapp
DB_USERNAME=myapp
DB_PASSWORD=mysecret
Важливий момент для Laravel у transaction mode: відключити prepared statements. У config/database.php:
'pgsql' => [
'driver' => 'pgsql',
'options' => [
PDO::ATTR_EMULATE_PREPARES => true,
],
],
Для Django — аналогічно, використовувати CONN_MAX_AGE = 0.
Коли використовувати ProxySQL замість PgBouncer?
ProxySQL — значно потужніший за PgBouncer: вміє роутинг запитів, read/write split, автоматичне перемикання при падінні мастера. Він незамінний, якщо у вас MySQL-кластер з репліками або потрібне гнучке розподілення навантаження. ProxySQL обробляє запити в 10 разів швидше за конкурентів.
Кроки з налаштування ProxySQL
- Завантаження та встановлення пакету
- Запуск служби
systemctl start proxysql - Підключення до адмінського інтерфейсу
mysql -h 127.0.0.1 -P 6032 -u admin -padmin - Додавання серверів та правил
# Встановлення ProxySQL
wget https://github.com/sysown/proxysql/releases/download/v2.6.3/proxysql_2.6.3-ubuntu22_amd64.deb
dpkg -i proxysql_2.6.3-ubuntu22_amd64.deb
systemctl start proxysql
# Налаштування через admin-інтерфейс
mysql -h 127.0.0.1 -P 6032 -u admin -padmin
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (0, '127.0.0.1', 3306);
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
Read/write split через query rules — весь SELECT (крім FOR UPDATE) на репліку, решта на мастер.
Порівняння PgBouncer та ProxySQL
| Характеристика | PgBouncer | ProxySQL |
|---|---|---|
| Підтримувані СУБД | PostgreSQL | MySQL/MariaDB |
| Режими пулінгу | Session, Transaction, Statement | Connection pool (один режим) |
| Read/write split | Ні | Так (гнучкі правила) |
| Prepared statements | Проблеми в transaction mode | Повна підтримка |
| Моніторинг | Prometheus exporter | Stats schema + Grafana |
| Складність налаштування | Низька | Середня |
Режими пулінгу PgBouncer
| Режим | Опис | Застосування |
|---|---|---|
| Session | Одне з'єднання закріплене за клієнтом на всю сесію | Тільки якщо потрібен повний доступ до всіх можливостей |
| Transaction | З'єднання утримується лише на час транзакції | Рекомендується для веб-додатків з короткими транзакціями |
| Statement | З'єднання повертається після кожного запиту | Несумісний з транзакціями, рідко застосовний |
Типові проблеми при connection pooling
При використанні transaction mode можливі такі труднощі:
- Prepared statements можуть створюватися в одному з'єднанні, а виконуватися в іншому. Рішення: увімкнути емуляцію prepared statements на рівні драйвера (PDO::ATTR_EMULATE_PREPARES).
- Тимчасові таблиці та pg_temp не працюють, тому варто використовувати CTE або постійні таблиці.
- Довгі транзакції (понад 30 секунд) знижують ефективність пулу — необхідно оптимізувати запити.
Що входить у налаштування під ключ?
- Аудит поточної конфігурації БД та додатку.
- Налаштування пулера (PgBouncer або ProxySQL) під ваше навантаження.
- Інтеграція з додатком (Laravel, Django, Symfony та ін.).
- Тестування під навантаженням з моніторингом.
- Документація з експлуатації.
- Навчання команди.
- Підтримка протягом місяця після запуску.
Строки та вартість
Базове налаштування PgBouncer з тестуванням — 1 робочий день, вартість від $500. ProxySQL з read/write split та моніторингом — 2–3 дні, від $1200. Якщо потрібна інтеграція з існуючим додатком та усунення проблем з prepared statements — плюс 1 день на налагодження (від $300). Ми гарантуємо, що після налаштування кількість одночасних з'єднань перестане бути вузьким місцем. Пам'ять сервера БД скорочується на 80%. Напишіть нам для безкоштовного аудиту — допоможемо підібрати оптимальне рішення для вашого навантаження під ключ за 3 дні.







