Как Работает Пул Подключений В Django?
Если я не ошибаюсь, в настоящее время существует два способа объединения подключений в Django:
- Собственный пул подключений (Django 5.x)
- Использование PGBouncer
Я хочу знать, как работает пул соединений за кулисами в Django.
В FastAPI есть один "постоянный" процесс, который обрабатывает все запросы. Мы можем создать пул подключений, используя, например, драйвер asyncpg. В своей простейшей форме он создает около 10 подключений к базе данных Postgresql (используя 10 сокетных подключений unix), затем, когда сопрограмма запрашивает соединение, она выдает его из пула.
+-------------------------+
| +------------+ | ---------------> +------------+
| | | | | |
| FastAPI | Connection | | ---------------> | Database |
| | Pool | | | |
| | (asyncpg) | | ---------------> +------------+
| +------------+ |
+-------------------------+
Но в Django нет единого постоянного процесса. Если мы используем Gunicorn с sync workers, каждый worker создает экземпляр приложения Django для обработки одного запроса за раз. Между ними нет общей памяти.
Как драйвер psycopg3 может создать пул подключений для одного рабочего, и все остальные рабочие будут взаимодействовать с ним?
Я предполагаю, что PGBouncer - это отдельный процесс, который создает пул подключений в своей памяти, тогда все рабочие Django могут взаимодействовать с ним.
Django worker ---\
-----\ +------------+ ---------------> +------------+
-----\ | | | |
Django worker ------------------> | PBbouncer | ---------------> | Database |
-----/ | | | |
-----/ +------------+ ---------------> +------------+
Django worker ---/
Правильно ли я понимаю, что оба способа объединения соединений в Django являются прямыми и для промежуточного процесса существует дополнительная задержка?
Django изначально не поддерживает объединение баз данных, вы можете воспользоваться такими инструментами, как: https://github.com/jneight/django-db-geventpool
С другой стороны, какой Django поддерживает Persistent connections с атрибутом CONN_MAX_AGE.
Мне кажется, что этот вопрос возникает из-за отсутствия ясности в отношении различных способов запуска приложения Django. Я попытаюсь перечислить соответствующие способы здесь:
- Синхронные рабочие процессы.
- Синхронные рабочие процессы с потоковой передачей
- Асинхронные рабочие процессы
В каждом из вышеперечисленных случаев рабочие процессы управляются сервером, подобным Gunicorn.
В первом случае каждый работник обрабатывает по одному запросу за раз. В этом случае вы также можете не использовать пул подключений и вместо этого использовать постоянные соединения, поскольку одновременно можно использовать только одно соединение из пула подключений.
Во втором случае в одном процессе может быть несколько потоков, выполняющих функции рабочих. Каждый из этих потоков может обслуживать запрос одновременно.
В третьем случае процесс может обрабатывать несколько запросов одновременно, используя цикл обработки событий и переключение контекста во время ввода-вывода.
Функция пула подключений подходит для второго и третьего случаев. Что касается внутренней части работы пула подключений, то Django использует пулы подключений из psycopg_pool, есть рабочий поток, который управляет подключениями, поэтому работа аналогична вашей схеме для FastAPI с asyncpg.