172 похожих чатов

Добрый день. подскажите пожалуйста, насколько хорошая идея использовать hikariCP в

джава приложениях совместно с pg_bouncer? столкнулись с проблемой, при работе с постгресом в кластере (patroni, keepalived, pg_bouncer), при переезде мастера и переключения коннектов на боунсер другой ноды - подключения задваиваются, тем самым забивая пул боунсера. через час они сами терминируются, возможно это параметр таймаута хикари. или спасает также перезагрузить боунсер после смены ноды мастера. все параметры боунсера я перепробовал, добиться результатов не вышло.

21 ответов

73 просмотра

вроде, pg_bouncer изначально создавался как коннекшн пулер для бедных (например, для сайтов на php, которые каждый раз новое подключение открывают). Чтобы использовать его в системе, где есть свой коннекш пул, нужно обоснование. Например - у вас несколько нод на java используют одни и те-же подключения к БД когда нагрузки особой нет (сомнительный вариант, т.к. при пиковой нагрузке всё равно понадобятся все подключения).

Anton-Olifir Автор вопроса
Radist
вроде, pg_bouncer изначально создавался как коннек...

относительно боунсера есть много мнений все же, но спасибо за аргументацию, приму к сведению.

Anton Olifir
относительно боунсера есть много мнений все же, но...

Теоретически, pg_bouncer с pool_mode = transaction может позволить в непиковое время поддерживать суммарно меньшее число сессий. Если pool_mode = session, смысла ставить баунсер перед пулом в java вообще не понимаю. Только одни минусы (в частности, в БД будет видно адрес клиента 127.0.0.1 вместо реального IP).

Anton-Olifir Автор вопроса
Radist
Теоретически, pg_bouncer с pool_mode = transaction...

если в базу ходят не только java но и другие приложения, которые в пул пока не умеют

Anton Olifir
если в базу ходят не только java но и другие прило...

вот можно другие приложения пускать через баунсер, а java пусть напрямую ходит

Radist
вот можно другие приложения пускать через баунсер,...

Два коннекшн пула это конечно не дело, но почему вы в таком случае отдаёте предпочтение hikaricp? При смене мастера джава приложение никак не узнает об этом (потому что по дефолту keepalive отключен в hikaricp), до тех пор пока какой-то поток не получит коннект из пула и не попытается им воспользоваться, упав при этом с ошибкой. С другой стороны, если оставить только pgbouncer, его в момент файловера можно пнуть через хук и заставить переконнектиться. Что вы об этом думаете?

Vitaly Ustinov
Два коннекшн пула это конечно не дело, но почему в...

Я обычно пулы настраиваю так, чтобы перед получением коннект тестировался

Radist
Я обычно пулы настраиваю так, чтобы перед получени...

ну это же лишний roundtrip в базу и обратно. как минимум дороговато, а для высоких rps просто неприемлемо.

Radist
Я обычно пулы настраиваю так, чтобы перед получени...

И кстати, как это сдeлать для HikariCP ? Не помню чтоб он предоставлял такую возможность. Периодический keepalive можно включить, но вот именно тестирование коннекта каждый раз перед использованием - как?

Vitaly Ustinov
ну это же лишний roundtrip в базу и обратно. как м...

Другого способа гарантированно (ну пусть будет 99.9%) получить рабочий коннект. Либо писать код, чтобы он повторял попытку, если падает первый запрос. Есть вариант с проверкой коннектов в фоне, но он не даёт таких гарантий (при высоких rps вы наткнётесь на половину битых подключений до того, как maintenance thread их удалит сам). По поводу возможностей hikaricp надо смотреть, я последний раз его настраивал 3 года назад.

Radist
Другого способа гарантированно (ну пусть будет 99....

https://github.com/brettwooldridge/HikariCP#gear-configuration-knobs-baby connectionTestQuery

Radist
https://github.com/brettwooldridge/HikariCP#gear-c...

это не то. во первых, это для фоновых keepalive запросов по таймеру (см. keepaliveTime), который по умолчанию отключен. а во вторых, там ведь жирным текстом написано "we strongly recommend not setting this property"

Vitaly Ustinov
это не то. во первых, это для фоновых keepalive за...

Как я понял, этот запрос выполняется перед выдачей подключения из пула. При этом, если этот параметр не установлен, значит он должен вызывать Connection.isValid(), по идее

Radist
Как я понял, этот запрос выполняется перед выдачей...

Да, проверяется при выдаче, но не чаще чем 1 раз в 500 мс. Есть недокументированный параметр "aliveBypassWindowMs". Если хотите проверять каждый раз, то установите его в ноль. https://github.com/brettwooldridge/HikariCP/blob/ed2da5f1f4ef19f871fac12effc0b199706905dc/src/main/java/com/zaxxer/hikari/pool/HikariPool.java#L170

Vitaly Ustinov
Два коннекшн пула это конечно не дело, но почему в...

> Два коннекшн пула это конечно не дело, но почему вы в таком случае отдаёте предпочтение hikaricp? Отвечу более развёрнуто. Передо мной не стояла задача автопереключения, но если бы стояла, то hikaricp предоставляет на каждый датасорс по два бина доступных по JMX (один для мониторинга, второй для настройки). Там, правда, именно переключение не сделать (мб. потому что я внутри подсовываю Datasource из jdbc-драйвера PostgreSQL), но никто не мешает сделать такую переключалку самому. С другой стороны, при использовании баунсера, в момент, когда мне понадобилось подключение, нужно было бы тратить время на собственно установку TCP-подключения (если настроено шифрование - это еще доп.затраты на SSL), аутентификацию и начальную настройку сессии. В случае пула работающего в JVM, у меня уже пачка готовых подключений. По итогу, даже если делать тестовый запрос перед отдачей подключения из пула, локальный пул получается выгоднее.

Radist
> Два коннекшн пула это конечно не дело, но почему...

Пачка готовых соединений в пуле может быть и преимуществом и недостатком. Например, если у вас множество микросервисов, и у каждого свой собственный пул, то у вас точно будет висеть впустую множество idle коннектов на всякий случай. Топикстартер изначально спрашивал как раз про авто-переподключение к БД после смены мастера. Мне кажется, что с внешним пулером это сделать проще, потому что можно отработать событие смены мастера и автоматом сбросить весь пул. И приложение про это даже не узнает. Хотя, смена мастера тоже происходит не мгновенно, так что приложение, весьма вероятно, успеет нахватать ошибок коннекта к БД. Опять же, зависит от конкретного сетапа. А ещё бывает схема с несколькими pgbouncer и перед ними фронт-балансер (haproxy), который слушает сразу два порта (read-write, read-only) и делает роутинг, т.к. всегда знает где мастер и где hot standby реплики. Это позволяет в приложении сделать умную фабрику (AbstractRoutingDataSource в спринге), чтобы она в зависимости от флага readOnly транзакции получала коннекты через правильный порт haproxy и таким образом снимала read-only нагрузку с мастера. При таком раскладе понадобилось бы целых 2 пула в джаве, а это еще больше накладных расходов и еще больше проблем при смене мастера. Что думаете?

Vitaly Ustinov
Пачка готовых соединений в пуле может быть и преим...

если у нас пачка микросервисов, которые смотрят в одну бд, им самое место в одном сервере приложений (всё равно бд - общая точка отказа всех этих микросервисов) с централизованно настраиваемыми датасорсами (соответственно, пул будет единый). Если же бд разные, то сделать меньше коннектов не получится и с баунсером. Если же требуется прям по отдельной машине на каждый сервис выделять, то опять-же, hikaricp хорош тем, что его не обязательно настраивать на использование больших значений постоянно поддерживаемых подключений, т.к. он достаточно быстро выдаёт новые подключения при увеличении запросов (не дожидаясь, пока очередная пачка подключений создастся). С другой стороны, idle-подключения особо ресурсов не жрут (помимо памяти на процесс, которую всё равно пришлось бы зарезервировать для пиковых нагрузок). В любом случае, есть какое-то количество микросервисов, после которого вариант локальных пулов будет проблемным, но мне кажется, что раньше потребуется их на разные сервера БД рассаживать (хотя, конечно, тут абстрактно судить нет смысла, все проекты разные). Что касается схемы со снятием read-only нагрузки, не вижу принципиальной проблемы держать два пула, пока они смотрят на разные сервера БД. Какие сложности при этом могут быть у spring-ов с ними не в курсе, предпочитаю немного другой стек в jvm.

Radist
если у нас пачка микросервисов, которые смотрят в ...

но замечу, что я больше базист, в java выношу то, что неудобно/трудно/нежелательно делать в хранимках, так что работать с десятков разрозненных сервисов на одной бд не приходилось. Знаю только то, что проблемы использования двух пулов (один в java, второй рядом с БД) возможны, но проявятся ли они при использовании конкретно hikaricp+bouncer покажет только тестирование. У нас было развёрнуто приложение на прод-стенде как раз с такой комбинацией, но там в случае проблем с БД тупо всё откатывалось и затем повторялась попытка (это был не онлайн-сервис, а обработчик очереди задач), какие-то проблемы заметили только когда сконфигурировали число потоков большее, чем предел числа коннектов в пуле, но гарантировать, что там не было других проблем я не смогу, т.к. мы тупо могли не заметить в силу офлайновости приложения.

Radist
если у нас пачка микросервисов, которые смотрят в ...

Спасибо за ответ! По поводу объединения микросервисов в один монолит из-за общей БД не могу с вами согласиться. Их пилят разные команды, со своим собственным релмзным циклом. Какие-то микросервисы лишь иногда взаимодействуют с БД, а по большей части общаются через mq, или же проводят сложные расчёты требующие множества ядер, оттого их могут прямо на живом проде скейлить по разному. По остальному тоже есть что возразить, но не вижу смысла, ведь мы не спорим, а высказываем мнения. Конечно же нужно сначала знать все нюансы дизайна чтобы углубиться в детальное обсуждение.

Radist
но замечу, что я больше базист, в java выношу то, ...

👍 Идея каскадного пула звучит как потенциальная проблема

Vitaly Ustinov
Спасибо за ответ! По поводу объединения микросерви...

Ну для офлайновых сервисов, которые с внешним миром напрямую не контактируют, а с БД работают лишь иногда, по идее, скорость получения подключения к БД не должна играть большого значения, а значит действительно можно попробовать обойтись без своего пула прямым подключениям к БД. Локальный пул используют когда подключение к БД обязательная часть обработки каждой исполняемой задачи (будь то элемент очереди или веб-запрос). Если такого нет - просто берётся простой datasoure, без пула, либо настраивается минимальный таймаут, чтобы невостребованное подключение через пол минуты закрывалось. Что касается каскадного пула - по идее, если эти пулы спроектированы с учетом возможности каскада, то проблем не должно быть (собственно, я сходу не назову возможную причину проблем, но читал о проблемах двух конкретных реализаций (одна из них была в wls вроде)). Пулинг на сервере бд вполне применяемая практика (pgbouncer, у oracle есть своё решение, правда не уверен, что оно используется для jdbc), так что, по идее, в пулах общего назначения это должно учитываться. Но как на деле - не знаю. Да, спасибо за беседу. Очень познавательно узнать о примерах предусловий, заставляющих принимать решения отличные от тех, которые сам принимаешь

Похожие вопросы

Обсуждают сегодня

30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Карта сайта