Как Работает Пул Подключений В Django?

Если я не ошибаюсь, в настоящее время существует два способа объединения подключений в Django:

  • Собственный пул подключений (Django 5.x)
  • Использование PGBouncer

Я хочу знать, как работает пул соединений за кулисами в Django.

В FastAPI есть один "постоянный" процесс, который обрабатывает все запросы. Мы можем создать пул подключений, используя, например, драйвер asyncpg. В своей простейшей форме он создает около 10 подключений к базе данных Postgresql (используя 10 сокетных подключений unix), затем, когда сопрограмма запрашивает соединение, она выдает его из пула.

+-------------------------+                                   
|          +------------+ | ---------------> +------------+   
|          |            | |                  |            |   
| FastAPI  | Connection | | ---------------> |  Database  |   
|          | Pool       | |                  |            |   
|          | (asyncpg)  | | ---------------> +------------+   
|          +------------+ |                                   
+-------------------------+

Но в Django нет единого постоянного процесса. Если мы используем Gunicorn с sync workers, каждый worker создает экземпляр приложения Django для обработки одного запроса за раз. Между ними нет общей памяти.

  1. Как драйвер psycopg3 может создать пул подключений для одного рабочего, и все остальные рабочие будут взаимодействовать с ним?

  2. Я предполагаю, что 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.

Вернуться на верх