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

Cloudflare управляет высокодоступными производственными кластерами Postgres в нескольких центрах обработки данных, поддерживая транзакционные рабочие нагрузки наших основных предложений услуг, таких как DNS Resolver, брандмауэр и защита от DDoS.
Несколько экземпляров PgBouncer находятся перед уровнем шлюза в каждом кластере, выступая в качестве прокси-сервера TCP, который обеспечивает пул соединений Postgres. Объединение в пул PgBouncer позволяет вышестоящим приложениям подключаться к Postgres без необходимости постоянно открывать и закрывать соединения (дорогие) на уровне базы данных, а также сокращать количество используемых соединений Postgres. Каждый арендатор получает подключения на стороне клиента от PgBouncer, а не напрямую от Postgres.

PgBouncer будет хранить пул максимального количества подключений на стороне сервера к Postgres, распределяя их между несколькими арендаторами, чтобы предотвратить нехватку подключений Postgres. Отсюда PgBouncer будет перенаправлять внутренние запросы на HAProxy, который распределяет нагрузку между первичной репликой Postgres и репликой чтения.
Будучи стажером в Cloudflare, я работал над улучшением того, как наши кластеры баз данных ведут себя под нагрузкой, и открывал исходный код полученного кода.
Мы запускаем нашу инфраструктуру Postgres в неконтейнерных средах с «голым железом», что, следовательно, приводит к многопользовательской конкуренции за ресурсы между пользователями Postgres. Чтобы обеспечить более строгую изоляцию производительности арендатора на уровне базы данных (используемое время ЦП, потребление памяти, дисковые операции ввода-вывода), мы хотели бы настроить и применить ограничения на количество подключений для каждого пользователя и пула подключений в PgBouncer.
Для этого нам пришлось добавить функции и исправить ошибки в PgBouncer. Вместо того, чтобы продолжать поддерживать частный форк, мы открываем исходный код для использования другими.
Отказ в аутентификации
Пул соединений PgBouncer предлагает параметры для принудительного применения ограничений размера пула соединений сервера (эффективный параллелизм) для каждого пользователя посредством статической конфигурации. Однако из-за ошибки аутентификации восходящего потока эти функции не работали корректно, когда Postgres был настроен на использование аутентификации HBA. Администраторы, которые разумно используют аутентификацию на стороне сервера, не могут воспользоваться этими функциями на уровне пользователя.
С этой постоянной проблемой также сталкивались другие участники сообщества открытого исходного кода:
https://github.com/pgbouncer/pgbouncer/issues/484
https://github.com/pgbouncer/pgbouncer/issues/596
Первопричина
PgBouncer требуется пароль пользователя Postgres при проксировании отправленных запросов от клиентского соединения к соединению с сервером Postgres. PgBouncer извлечет пароль пользователя Postgres, определенный в userlist.txt (auth_file), когда пользователь впервые войдет в систему, чтобы сравнить его с предоставленным паролем. Однако, если пользователь не указан в userlist.txt, Pgbouncer для сравнения извлечет его пароль из системного представления Postgres pg_shadow. Этот пароль будет использоваться, когда PgBouncer впоследствии будет пересылать запросы от этого пользователя в Postgres. То же самое применимо, когда Postgres настроен на использование аутентификации HBA.
После серьезных усилий по отладке и времени, проведенного в GDB, мы обнаружили, что несколько пользовательских объектов обычно создаются для одного реального пользователя: через загрузку конфигурации из [users] разделе и при первом входе пользователя. В PgBouncer любые пользователи, которым требуется теневой запрос аутентификации, будут храниться в соответствующем экземпляре структуры базы данных, тогда как любой пользователь с паролем, определенным в userlist.txt, будет храниться глобально. Поскольку неаутентифицированный пользователь уже существовал в памяти после анализа из [users] раздел, PgBouncer предположил, что пользователь был определен в userlist.txt, где запрос теневой аутентификации можно было пропустить. Он не удосужился получить и установить пароль пользователя при первом входе в систему, что привело к пустому паролю пользователя. Вот почему последующие запросы, отправленные пользователем, будут отклонены с ошибкой аутентификации в Postgres.
Чтобы решить эту проблему, мы упростили код для глобального хранения всех пользователей в одном месте, а не для хранения разных типов пользователей (требующих разных методов аутентификации) в дезагрегированном виде для каждой базы данных или глобально. Кроме того, вместо того, чтобы предполагать, что пользователь аутентифицирован, если он просто существует, мы отслеживаем, требует ли пользователь аутентификации с помощью запроса аутентификации или путем получения своего пароля из userlist.txt. Это зависит от того, как они были созданы.
Мы увидели ценность в поиске и устранении этих проблем; это открыло бы целый класс функций PgBouncer для наших вариантов использования, а также принесло бы пользу многим в сообществе открытого исходного кода.
Новые особенности
Мы также проделали работу по реализации и поддержке дополнительных функций в PgBouncer, чтобы обеспечить более строгую изоляцию производительности арендатора.
Раньше PgBouncer только предотвращал превышение арендаторами предварительно настроенных лимитов, что не особенно полезно, когда уже слишком поздно, а пользователь ведет себя неправильно или уже имеет слишком много подключений. PgBouncer теперь поддерживает принудительное применение или сокращение ограничений пула соединений пользователя во время выполнения. там, где это наиболее остро необходимо чтобы задушить арендаторов, которые выдают всплеск дорогостоящих запросов или перехватывают подключения от других арендаторов. Мы также внедрили новые административные команды для ограничения максимального количества подключений на пользователя или на пул во время выполнения.
PgBouncer также теперь поддерживает статическую настройку и динамическое применение ограничений на количество подключений для каждого пула подключений. Эта функция чрезвычайно важна для детального регулирования пула соединений клиента, который ведет себя неправильно, без регулирования и снижения доступности других пулов, которые не работают неправильно.
Конфигурация PgBouncer
[users]
dns_service_user = max_user_connections=60
firewall_service_user = max_user_connections=80
[pools]
user1.database1 = pool_size=90
Команды выполнения PgBouncer
SET USER dns_service_user = ‘max_user_connections=40’;
SET POOL dns_service_user.dns_db = ‘pool_size=30’;
Эти новые функции потребовали серьезного рефакторинга в отношении того, как PgBouncer хранит пользователей, базы данных слабо ссылаются и хранят пароли разных пользователей, а также того, как мы принудительно отключаем соединения на стороне сервера, пока они все еще используются.
Вывод
Мы стремимся улучшать PgBouncer с открытым исходным кодом и делиться всеми нашими функциями на благо более широкого сообщества. Если вы заинтересованы, рассмотрите возможность внести свой вклад в наш форк PgBouncer с открытым исходным кодом. В конце концов, именно сообщество делает возможным использование PgBouncer!