Рубрики
Без рубрики

Масштабирование Django/postgres с Pgbouncer на Heroku

У вас есть приложение на Heroku с помощью Postgres? У вас заканчивается подключения к базе данных? Может быть, вы … с меткой Python, Heroku, Pgbouncer, Django.

У вас есть приложение на Heroku с помощью Postgres? У вас заканчивается подключения к базе данных? Может быть, вы уже пробовали настройку Conn_max_age , но это помогло только на некоторое время. Пришло время для PGBouncer, де -факто стандарта для Postgres Connection Pooling. В этой статье мы рассмотрим, как использовать PGBouncer, чтобы масштабировать ваше приложение на Heroku. Мы будем использовать Django, популярную веб -структуру Python, в качестве примера для настройки. Однако шаги установки для PGBouncer и концепций должны работать для любого приложения на Heroku.

Чему вы узнаете

Несмотря на то, что настройка PGBouncer проста, поиск правильных настроек для вашего конкретного варианта использования может быть проблемой. Не существует универсального решения для конфигурации PGBouncer.

Эта статья покажет вам:

  • Как выбрать режим и тип развертывания PGBouncer Pool
  • Как установить Pgbouncer на Heroku, добавив PGBouncer BuildPack к вашему существующему приложению Django
  • Как контролировать статистику выполнения PGBouncer, чтобы помочь точно настроить ваши настройки
  • общие ошибки и вещи, которые нужно остерегаться

Вы можете найти образец проекта на GitHub в https://github.com/steuke/heroku-pgbouncer-django-demo Анкет

Примечание. Чтобы использовать это руководство, ваше приложение должно использовать Database_url Переменная среда для настройки его подключения базы данных. Это важно. Если вы настроите свою базу данных вручную, вам сначала нужно будет переключиться на использование Database_url Анкет Для Джанго взгляните на DJ-Database-Url и Образец проекта , что делает это очень легко. Вы можете проверить образцо проекта, чтобы лучше понять, как это можно сделать.

Что учитывать, прежде чем начать

Выбор правильного типа развертывания PGBouncer

PGBouncer можно развернуть по -разному. Heroku поддерживает развертывание как серверной и клиентской стороны. Реализация на стороне сервера на Heroku все еще находится в бета-версии, несколько ограничена параметрами конфигурации и поддерживает только транзакционный режим (см. Следующий раздел). Следовательно, в этом руководстве используется подход на стороне клиента, который развертывает PGBouncer на той же Dyno, что и ваше приложение Django, и дает вам больше контроля над каждой настройкой.

Если вы не уверены, какой тип развертывания использовать, Официальная документация Heroku поможет вам решить, подходит ли вам на стороне клиента развертывание .

Выбор правильного режима PGBouncer Pool и настройки Django

Pgbouncer имеет Три типа режимов пула соединений перечислены здесь от большинства вежливых до наиболее агрессивного обмена соединением: сеанс, транзакция и режим операторов.

Вот что вам нужно знать при рассмотрении различных режимов пула для использования с вашим приложением Django:

  • Сеанс-режим (Соединение возвращается в пул только тогда, когда пользовательский сеанс закрыт): этот режим является наиболее консервативным. Если вы используете этот режим, вам не нужно ничего менять в вашем приложении Django. Если другие режимы не работают с вашим приложением, этот режим может решить проблемы. Этот режим поддерживает все функции Postgres.
  • Режим транзакции (Соединение возвращается в пул, как только транзакция завершена): Это режим по умолчанию Heroku Pgbouncer BuildPack. Этот режим требует от вас отключения использования курсоров на стороне сервера. В Джанго отключите их, установив Disable_server_side_cursors . Этот режим должен работать с большинством приложений, но обратите внимание, что некоторые важные функции Postgres, такие как подготовленные утверждения, прослушивание/уведомление, и другие , не поддерживаются. Если вы используете какие -либо из этих функций (или вы полагаетесь на библиотеку, которая использует эти функции), вы рискуете разбить свое приложение или напрягать производительность некоторых запросов.
  • Режим оператора (Соединение возвращается в пул, как только заявление будет выполнено): это даже более агрессивно, чем режим транзакции. В этом режиме вы не можете использовать транзакции с несколькими установками. Много государственные транзакции приведут к ошибке («Сервер неожиданно закрыл соединение»). Если вам нужен этот режим для определенных вариантов использования, рассмотрите возможность настройки нескольких пулов PGBouncer с различными настройками.

В качестве наилучшей практики начните с использования режима транзакций и убедитесь, что ваше приложение все еще работает. После этого не стесняйтесь экспериментировать с другими режимами и их влияние на производительность и использование ресурсов.   Например, если вы испытываете ошибки, потому что в вашем приложении используются функции, которые не поддерживаются, попробуйте переключиться на сеанс-режим. Если вы не испытываете ошибок, и вы хотите продвинуть производительность вашего приложения, вы можете попытаться использовать режим оператора. Более подробную информацию можно найти в документации Heroku.

Установка PGBouncer на Heroku с помощью BuildPack

Слово совета: используйте разъемную среду, чтобы следовать этому руководству. Выверните это изменение в производство только после тестирования вашего приложения в стадии. Неправильные шаги могут помешать вашим приложению работать до тех пор, пока вы не решите проблему. (Вы были предупреждены!)

Хорошо, начнем. Следуйте этим пять шагов, чтобы добавить Pgbouncer в ваше приложение (в этой статье мы будем использовать heroku cli для команд):

1. Отключить использование курсоров на стороне сервера

В приложении Django просто добавьте эта строка В ваши настройки.py:

DISABLE_SERVER_SIDE_CURSORS = True  # required when using pgbouncer's pool_mode=transaction

2. Добавьте PGBouncer BuildPack

$ heroku buildpacks:add heroku/pgbouncer 

3. Добавьте Python BuildPack

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

$ heroku buildpacks:add heroku/python 

4. Измените свою прокляцию так, чтобы PGBouncer был запущен в Startup

Если вы используете Python/Django, то перед этим изменением ваше проклятие будет выглядеть примерно так:

web: gunicorn your_django_project.wsgi 

Изменить это на что -то как это :

web: bin/start-pgbouncer gunicorn your_django_project.wsgi 

Это изменение передает вашу исходную команду запуска в сценарий Bin/Start-Pgbouncer. Сценарий является частью PGBouncer BuildPack. Его основная цель – изменить переменную среды Database_url, чтобы указать на локальный пул соединений PGBouncer вместо исходной базы данных Postgres.

По этой причине ваше приложение Django должно использовать переменную среды DATABASE_URL для настройки подключения к базе данных. Если вы не используете Database_url, ваше приложение все равно будет работать, но оно не будет подключаться через PGBouncer с вашими Postgres.

5. Совершить изменения и развернуть их в Heroku

Используйте своего любимого клиента GIT, чтобы совершить изменения и подтолкнуть его к Heroku. Затем начните смотреть на журналы с Heroku Logs -t -Source App | Греп pgbouncer при запуске тестов в вашем приложении. Вы должны увидеть серию логарифмических входов, похожих на это:

2020-04-30T18:59:48.918478+00:00 app[web.1]: 2020-04-30 18:59:48.918 53 LOG C-0x56211ba01900: pgbouncer/pgbouncer@unix(63):6000 login attempt: db=pgbouncer user=pgbouncer tls=no
2020-04-30T18:59:48.919044+00:00 app[web.1]: 2020-04-30 18:59:48.919 53 LOG C-0x56211ba01900: pgbouncer/pgbouncer@unix(63):6000 closing because: client close request (age=0)

Поздравляю! Это указывает на то, что ваше приложение успешно настроено и использует PGBouncer для подключения к Postgres.

Чего вы только что достиг?

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

В следующем разделе вы узнаете, как контролировать PGBouncer.

Мониторинг PGBouncer

Есть несколько способов мониторинга PGBouncer. Один общий способ – Подключитесь к Admin-Console PGBouncer с использованием PSQL Анкет Этот раздел демонстрирует два других способа: использование журналов Heroku и запрос статистики из вашего приложения Django.

Используя журналы Heroku

PGBouncer BuildPack настроен для регистрации статистики PGBouncer с интервалами в одну минуту. Запуск следующей команды показывает самую последнюю статистику:

$ heroku logs --source app | grep "LOG Stats"

Вывод будет похож на это:

2020-04-30T19:11:25.720304+00:00 app[web.1]: 2020-04-30 19:11:25.720 54 LOG Stats: 5 xacts/s, 46 queries/s, in 5401 B/s, out 2756 B/s, xact 45640 us, query 992 us wait time 1396 us

Запрос базы данных PGBouncer из вашего приложения Django с помощью Show Stats

PGBouncer предоставляет виртуальную базу данных, содержащую ее статистику. Это также называется Консоль администратора Анкет PGBouncer BuildPack предоставляет доступ к этой виртуальной базе данных через сокет UNIX с именем/TMP, используя имя пользователя «PGBouncer» и без пароля.

Используя эти учетные данные, вы можете получить статистику PGBouncer из вашего приложения Django, используя API базы данных PsycopG2 низкого уровня. Вот пример функции pgbouncer_stats (), которая извлекает статистику, используя этот API:

def pgbouncer_stats() -> List[Dict]:
    try:
        connection = psycopg2.connect(host="/tmp/", port=6000, dbname="pgbouncer", user="pgbouncer",
                                      cursor_factory=extras.DictCursor)
        connection.autocommit = True  # must enable autocommit when querying pgbouncer stats
        cursor = connection.cursor()
        cursor.execute('SHOW STATS')
        pgbouncer_stats = [dict(row) for row in cursor]
        return pgbouncer_stats
    except Exception as e:
        return [{'error': True, 'description': 'Could not query pgbouncer stats.', 'reason': f'{e}'}]

Возвратное значение PGBOUNCER_STATS () – это список словарей, с одним словарем для каждой базы данных, который объединяет PGBouncer:

"pgbouncer_stats":[
  {
    "database":"db1",
    "total_xact_count":220,
    "total_query_count":2750,
    "total_received":330110,
    "total_sent":168517,
    "total_xact_time":15062895,
    "total_query_time":2837299,
    "total_wait_time":84837,
    "avg_xact_count":2,
    "avg_query_count":29,
    "avg_recv":3519,
    "avg_sent":1796,
    "avg_xact_time":68467,
    "avg_query_time":1031,
    "avg_wait_time":904
  },
  {
    "database":"pgbouncer",
    "total_xact_count":110,
    "total_query_count":110,
    "total_received":0,
    "total_sent":0,
    "total_xact_time":0,
    "total_query_time":0,
    "total_wait_time":0,
    "avg_xact_count":1,
    "avg_query_count":1,
    "avg_recv":0,
    "avg_sent":0,
    "avg_xact_time":0,
    "avg_query_time":0,
    "avg_wait_time":0
  }
] 

Вы можете видеть, что база данных «DB1» имеет Total_xact_Count 220. Это указывает на то, что в общей сложности было обработано 220 транзакций. Документация PGBouncer имеет полный список статистики и их значение.

Общие ошибки и вещи, которые нужно остерегаться За

Как решить некоторые общие проблемы при начале использования PGBouncer:

  • «Фатальный: база данных ‘pgbouncer’ не существует:« Сервер, к которому вы подключаетесь, не кажется сервером PGBouncer. Вы добавили Heroku BuildPack для PGBouncer? Вы используете Database_url для настройки вашего соединения? Вы изменили Procfile, чтобы начать PGBouncer?
  • “Ошибка: нет такого пользователя: имя пользователя. «Это не должно произойти, если вы используете Heroku BuildPack. Убедитесь, что вы подключаетесь через розетку Unix в качестве пользователя «pgbouncer» без пароля. Смотрите PGBouncer-Documentation по аутентификации Больше подробностей.
  • Вам необходимо отключить SSL в параметрах базы данных Django, то есть удалить любой «SSLMode»: «Требуется». Поскольку вы используете установку на стороне клиента, трафик не покидает вашу машину и должен быть в безопасности. В качестве альтернативы см. Документы PGBouncer для обеспечения TLS-поддержки Анкет
  • Если вы подключаетесь к нескольким базам данных Postgres, вам необходимо установить переменную среды PGBOUNCER_URLS, чтобы PGBouncer знал, какие переменные среды она должна использовать для объединения соединений. Например, эта команда сообщает PGBouncer создать пулы соединений для database_url и event_database_url: heroku config: добавлять
  • Если у вас есть запросы, которые необходимо получить доступ к большим таблицам со многими строками, производительность вашего приложения может пострадать, когда вам придется отключить серверные костюмы. Одним из решений является использование нескольких пулов соединений. У вас может быть один бассейн в режиме сеанса для этих запросов с большим столом, используя второй пул в режиме транзакции для других.

Следующие шаги: монитор, тест и тонкая настройка Pgbouncer

На этом этапе PGBouncer работает на вашем динамо, обеспечивая объединение соединений с вашим приложением Django.

Что вы должны делать дальше?

  • Убедитесь, что производительность вашего приложения является прочной. Следите за статистикой PGBouncer, следя за статистикой, ориентированной на пользователя, такой как AVG_WAIT_TIME, что указывает время, которое ваше приложение ждет соединений.
  • Выполните тесты и экспериментируйте с настройками PGBouncer, а также типами бассейна. Одним из способов сделать это является использование инструмента для тестирования нагрузки, который ставит ваше приложение в растущую нагрузку. Пока нагрузка увеличивается, смотрите Maxwait-Stat’s Pgbouncer. Если это число становится все более резким, то пул не обрабатывает запросы клиентов достаточно быстро. Вы можете попытаться увеличить Pgbouncer_default_pool_size, уменьшение pgbouncer_reserve_pool_timeout Или попробуйте использовать более агрессивный режим бассейна. Если ничего из этого не поможет, возможно, на сервере заканчиваются ресурсы, что может означать, что вам нужно обновить сервер Postgres.
  • Ознакомьтесь с настройками PGBouncer, такими как MAX_CLIENT_CONN, DEFAULT_POOL_SIZE и MAX_DB_CONNECTIONS, чтобы настроить объединение соединений.

Вывод

PGBouncer – это правильный инструмент, помогающий масштабировать ваше приложение Postgres, когда количество подключений к базе данных становится проблемой. Имейте в виду, что, добавив PGBouncer в вашу настройку, приведет к дополнительной сложности для вас и вашей команды, уделяя время тщательной настройке, мониторингу и настройке вашей конфигурации, чтобы повысить производительность вашего приложения.

Оригинал: “https://dev.to/stefanukena/scaling-django-postgres-with-pgbouncer-on-heroku-1lb5”