Высокая доступность / масштабируемость PostgreSQL с использованием HAProxy и PGBouncer

17

У меня есть несколько серверов PostgreSQL для веб-приложения. Обычно один ведущий и несколько ведомых в режиме горячего резервирования (асинхронная потоковая репликация).

Я использую PGBouncer для пула соединений: один экземпляр установлен на каждом сервере PG (порт 6432), подключающемся к базе данных на локальном хосте. Я использую режим пула транзакций.

Для балансировки нагрузки моих подключений только для чтения на ведомых устройствах я использую HAProxy (v1.5) с conf более или менее следующим образом:

listen pgsql_pool 0.0.0.0:10001
        mode tcp
        option pgsql-check user ha
        balance roundrobin
        server master 10.0.0.1:6432 check backup
        server slave1 10.0.0.2:6432 check
        server slave2 10.0.0.3:6432 check
        server slave3 10.0.0.4:6432 check

Итак, мое веб-приложение подключается к haproxy (порт 10001), который подключается с балансировкой нагрузки к нескольким pgbouncer, настроенным на каждом ведомом PG.

Вот график представления моей текущей архитектуры:

haproxy> pgbouncer> postgresql

Это работает очень хорошо, как это, но я понимаю, что некоторые реализуют это совсем по-другому: веб-приложение подключается к одному экземпляру PGBouncer, который подключается к HAproxy, который распределяет нагрузку на несколько серверов PG:

pgbouncer> haproxy> postgresql

Какой лучший подход? Первый (мой текущий) или второй? Есть ли какие-то преимущества у одного решения над другим?

Благодарность

Николас Пайарт
источник

Ответы:

10

Ваша существующая конфигурация HAProxy -> PGBouncer -> PGServer лучше подходит. И это только работает. Вот причина: HAProxy перенаправляет соединение на разные серверы. это приводит к изменению MAC-адреса в соединении с базой данных. Поэтому, если PGBouncer находится выше HAProxy, каждый раз соединения в пуле становятся недействительными из-за изменения MAC-адреса.

Джобин Августин
источник
7

pgbouncer поддерживает соединения в пуле с сервером postgres. Время установления TCP-соединения является значительным в среде с большим объемом.

Клиенты, выполняющие большое количество запросов к БД, должны будут устанавливать соединение с удаленным PGBouncer для каждого запроса. Это дороже, чем локальный запуск PgBouncer (поэтому приложение подключается к pgbouncer локально), а pgBouncer поддерживает пул соединений с удаленным сервером PG.

Итак, IMO, PGBouncer -> HAProxy -> PGServer, кажется, лучше, чем HAProxy -> PGBouncer -> PGServer, особенно когда PGBouncer является локальным для клиентского приложения.

Донателло
источник
1

Я должен не согласиться с ответом Донателло.

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

Когда PgBouncer управляет соединениями PostgreSQL путем их объединения, время, которое ваше приложение тратит на открытие соединения, значительно уменьшается по сравнению с тем, когда соединение открывается непосредственно к БД. Это потому, что PG довольно медленно проверяет и проверяет учетные данные и все, каждый раз, когда запрашивается соединение.

Итак, подход App -> HAProxy -> [PgBouncer -> PostgreSQL] - лучший, потому что PgBouncer экономит время соединения с PG. Режим пула также важен. Вы должны знать, как ведет себя ваше приложение. Это в основном транзакционный? Или это скорее выполнение множества небольших SQL-предложений с высокой степенью параллелизма? Все эти параметры влияют на производительность.

Alvaro
источник