Django: CONN_MAX_AGE сохраняет соединения, но не использует их повторно с PostgreSQL

17

У меня есть настройки django, которые используют Django 1.6.7 и Postgres 9.3 на Ubuntu 14.04 LTS.

В любой момент времени сайт получает около 250 одновременных подключений к базе данных PostgreSQL, которая представляет собой Quad Core Xeon E5-2670 с тактовой частотой 2,5 ГГц и имеет 16 ГБ оперативной памяти. Средняя нагрузка на эту конкретную машину в течение дня составляет от 20 до 30.

Время от времени я получаю письма от часовых о задержке соединений с базой данных, и я полагаю, что включение какого-либо пула соединений поможет смягчить эту проблему, а также немного снизить нагрузку на базу данных.

Поскольку мы используем Django 1.6, у нас есть встроенный пул. Однако, когда я устанавливаю CONN_MAX_AGE равным 10 секундам или 60 секундам, почти сразу количество одновременных подключений переходит к максимально допустимому значению (которое примерно вдвое больше, чем мы обычно видим), и соединения начинают отклоняться.

Таким образом, оказывается , для того, что когда - либо причине, соединения ARE сохраняющиеся, но они НЕ повторного использования.

Что может быть причиной этого?

PS. Мы также используем gunicorn с --worker-class = eventlet. Возможно, это источник наших бед?

synic
источник

Ответы:

18

Проделав еще несколько экспериментов, я обнаружил, что причиной нашей проблемы был действительно рабочий класс eventlet. Каждая микропотока создала свою постоянную связь, и не было никакого способа повторно использовать любую из них.

Отключение eventlet привело к увеличению нагрузки на наши веб-серверы (но не намного), но загрузка postgres теперь снизилась в среднем до 3. С 30.

synic
источник
2
Вы только что сэкономили нам массу времени! Мы наблюдаем точно такое же поведение, и мы используем eventlet. Попробую переключиться на пул соединений и посмотреть, как это будет работать.
Silentser
3
Обновление: пул соединений с базой данных с помощью pgBouncer, похоже, решил проблему (мы все еще используем eventlet)
silentser
По-видимому, есть также psycogreen: pypi.python.org/pypi/psycogreen/1.0 (я не пробовал его, так как после того, как я установил значение CONN_MAX_AGE на ноль, нашей системе требуется 20 мс, чтобы установить соединение с БД, поэтому нам просто не нужен пул)
Даррен
1
Мне потребовалось некоторое время, чтобы найти ответ на ту же проблему, что и у нас.
Alper