Короткий ответ
Connection pool — это заранее созданный и переиспользуемый набор открытых соединений к БД, который избегает дорогостоящего создания нового TCP/TLS-соединения на каждый запрос; если все соединения в пуле заняты и достигнут лимит, новые запросы либо ждут освобождения соединения с таймаутом, либо сразу получают ошибку.
Как это работает подробнее
Пул выдаёт соединение по запросу (checkout), приложение выполняет запросы и возвращает соединение в пул (checkin) по завершении работы; при превышении лимита без доступных соединений вызывающий код блокируется до pool_timeout или получает исключение пула.
Пример кода
example.py
from sqlalchemy import create_engine
engine = create_engine(
"postgresql+psycopg2://user:pass@localhost/db",
pool_size=10,
max_overflow=5,
pool_timeout=30, # секунд ожидания свободного соединения, прежде чем выбросить исключение
)
# При 15 одновременных долгих запросах 16-й запрос будет ждать до 30с, затем получит TimeoutErrorЧто использовать на практике
- Практика. Размер пула подбирают с учётом числа воркеров приложения, ограничения max_connections на стороне PostgreSQL и реального профиля конкурентности; для большого числа коротких подключений часто ставят внешний пулер (PgBouncer) перед PostgreSQL.
Подводные камни
- Ошибка. Забывают возвращать соединение/сессию в пул (не закрывают сессию в finally), из-за чего пул постепенно «утекает»; ставят слишком большой pool_size на каждый инстанс при множестве инстансов, в сумме превышая max_connections БД.