Django: CONN_MAX_AGE сохраняет соединения, но не использует их повторно с PostgreSQL
У меня есть настройки 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 секунд, почти сразу количество одновременных соединений переходит к максимально допустимому значению (которое примерно вдвое больше, чем мы обычно видим), и соединения начинают отклоняться.
Таким образом, кажется, что по какой-либо причине соединения сохраняются, но они НЕ используются повторно.
Что может быть причиной этого?
PS. Мы также используем gunicorn с --worker-class=eventlet. Возможно, это источник наших бед?
1 ответ
Проделав еще несколько экспериментов, я обнаружил, что причиной нашей проблемы был действительно рабочий класс eventlet. Каждая микропотока создала свою постоянную связь, и не было никакого способа повторно использовать любую из них.
Отключение eventlet привело к увеличению нагрузки на наши веб-серверы (но не намного), но загрузка postgres теперь снизилась в среднем до 3. С 30.