проблемы с драйвером epgsql на стресс тестах

243 views
Skip to first unread message

Yuri Zhloba

unread,
Jul 9, 2012, 7:13:54 AM7/9/12
to erlang-...@googlegroups.com
Привет.

На стресс тестах вылезли некоторые проблемы с драйвером 
epgsql Погуглил, поискал, вроде бы проблема в том, что один и тот же Connection используют разные процессы. Но я не уверен, что именно в этом. Посему вопрос, как правильно использовать эти Connection?

У меня сейчас так: есть несколько штук таких Connection, которые раздаются по требованию разным процессам, и процессы делают через них свои запросы. Естественно, один Connection используется разными процессами.

Другой вариант: каждому процессу выделять свой Connection. Это вряд ли правильно :)

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

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

Еще подсказали, что 3й вариант нормальный. Тем не менее, хочу выслушать и другие мнения, как это делать идеологически правильно :)

Anton Fedorov

unread,
Jul 9, 2012, 7:20:33 AM7/9/12
to erlang-...@googlegroups.com
Я недавно на это напарывался.

Используйте последний async бранч из репозитори mabrek.
https://github.com/mabrek/epgsql/issues/1?_nid=56032235


В письме от Пнд, 09 Июл 2012, 18:13 Yuri Zhloba пишет:
> Привет.
>
> На стресс тестах вылезли некоторые проблемы с драйвером *epgsql* Погуглил,
> --
> Страница рассылки: http://groups.google.com/group/erlang-russian
> Новости: http://erlanger.ru
> Написать письмо: erlang-...@googlegroups.com
> Отписаться: erlang-russia...@googlegroups.com
>


--
Regards,
Anton Fedorov
Call2ru service
E-Mail: datac...@call2ru.com
Jabber: datac...@call2ru.com
Skype: datacompboy
ICQ: 272-35-262
Mobile: +7-913-925-7974 [SMS 24h, Call 05:00-19:00 MSKT (GMT+3)]

Anton Lebedevich

unread,
Jul 9, 2012, 7:33:00 AM7/9/12
to erlang-...@googlegroups.com
Если используется autocommit режим (не делается begin/commit/rollback),
то один коннект из https://github.com/mabrek/epgsql/ можно использовать
в нескольких процессах. В этом случае у коннекта нет состояния
(На самом деле оно есть, но но async ветка позволяет нескольким
процессам его использовать одновременно, т.к. хранит pid спросившего
вместе с запросом).

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

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

Yuri Zhloba

unread,
Jul 9, 2012, 7:34:23 AM7/9/12
to erlang-...@googlegroups.com
9 июля 2012 г., 14:20 пользователь Anton Fedorov
<datac...@call2ru.com> написал:

> Я недавно на это напарывался.
>
> Используйте последний async бранч из репозитори mabrek.
> https://github.com/mabrek/epgsql/issues/1?_nid=56032235
>

Ага, пасиб. И с ним можно работать по первому варианту?

Yuri Zhloba

unread,
Jul 9, 2012, 7:36:19 AM7/9/12
to erlang-...@googlegroups.com
> Если ручками открываются/закрываются транзакции, то состояние "в
> открытой транзакции выполнены определенные запросы" уже ничем не
> обойдешь. Третий вариант, в котором специальные процессы выполняют целые
> транзакции от начала до конца на персональных коннектах, вполне рабочий.

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

> Еще можно на специальные пулы посмотреть, например, берешь коннект у
> пула, он гарантирует, что дал его только тебе, выполняешь на нем свою
> транзакцию, отдаешь обратно в пул.

ок, подумаю

пасиб

Max Lapshin

unread,
Jul 9, 2012, 9:11:14 AM7/9/12
to erlang-...@googlegroups.com
Я Юре ещё посоветовал поставить pgbouncer и открывать по коннекту на процесс.

Но есть подозрение, что внутри pgbouncer примерно такой же код, как и
в async драйвере.

Yuri Zhloba

unread,
Jul 9, 2012, 9:22:05 AM7/9/12
to erlang-...@googlegroups.com
9 июля 2012 г., 16:11 пользователь Max Lapshin <max.l...@gmail.com> написал:

> Я Юре ещё посоветовал поставить pgbouncer и открывать по коннекту на процесс.
>
> Но есть подозрение, что внутри pgbouncer примерно такой же код, как и
> в async драйвере.
>

У меня все получилось по 3-му варианту, стресс-тесты работают, больше
ничего не падает.

Yuri Zhloba

unread,
Jul 9, 2012, 9:27:21 AM7/9/12
to erlang-...@googlegroups.com
Не думаю, что pgbouncer мне нужен. Я хочу сохранить инфраструктуру
минимальной, насколько возможно. И каждый новый компонент буду
добавлять только если он точно нужен.

Вот вылезут опять проблемы, тогда подумаю )

Sergey Yelin

unread,
Jul 9, 2012, 7:40:00 AM7/9/12
to erlang-...@googlegroups.com
Третий вариант вполне рабочий.

Anton Lebedevich

unread,
Jul 9, 2012, 10:11:43 AM7/9/12
to erlang-...@googlegroups.com
On 07/09/2012 05:11 PM, Max Lapshin wrote:
> Я Юре ещё посоветовал поставить pgbouncer и открывать по коннекту на процесс.

Любопытная идея, если pgbouncer быстро открывает коннекты. По идее
должен, но в таком сценарии я его не пробовал.

> Но есть подозрение, что внутри pgbouncer примерно такой же код, как и
> в async драйвере.

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

С уважением,
Лебедевич Антон.

Alexandr Alexeev

unread,
Jul 11, 2012, 12:15:04 AM7/11/12
to erlang-...@googlegroups.com
Однозначно третий вариант. Это общепринятая практика.

9 июля 2012 г., 18:11 пользователь Anton Lebedevich <mab...@gmail.com> написал:
--
Страница рассылки: http://groups.google.com/group/erlang-russian
Новости: http://erlanger.ru
Написать письмо: erlang-...@googlegroups.com
Отписаться: erlang-russia...@googlegroups.com



--
С уважением, Александр
Личный блог: http://eax.me/
Мой форум: http://it-talk.org/
Мой Twitter: http://twitter.com/afiskon

Yuri Zhloba

unread,
Jul 11, 2012, 1:26:29 AM7/11/12
to erlang-...@googlegroups.com
11 июля 2012 г., 7:15 пользователь Alexandr Alexeev <afi...@gmail.com> написал:

> Однозначно третий вариант. Это общепринятая практика.
>
О, пасиб. Я и хотел узнать, какова общепринятая практика.

Sergey Prochorov

unread,
Jul 11, 2012, 7:43:58 PM7/11/12
to erlang-...@googlegroups.com
Под третьим вариантом ведь понимается пул коннектов?
Т.е. API у него навроде

acquire(Pool) -> Connection
release(Pool, Connection) -> ok

И если я сделал acquire, то из пула изымается один свободный коннект (если свободных нет, то создается новый либо ждем освобождения) и выдается мне в монопольное использование до тех пор пока я его не верну через release?

понедельник, 9 июля 2012 г., 15:13:54 UTC+4 пользователь Yuri Zhloba написал:

Alexandr Alexeev

unread,
Jul 12, 2012, 12:06:12 AM7/12/12
to erlang-...@googlegroups.com
Вроде же можно функции передавать, нет? Путь передается функция, которая принимает в качестве параметра соединение и работает с ним в транзакции. Тогда вы не забудете освободить ресурс, а если постараться, то и транзакцию закрыть. (PS. Новичок в Erlang, так что извините, если пишу глупости).

12 июля 2012 г., 3:43 пользователь Sergey Prochorov <seri...@gmail.com> написал:

--
Страница рассылки: http://groups.google.com/group/erlang-russian
Новости: http://erlanger.ru
Написать письмо: erlang-...@googlegroups.com
Отписаться: erlang-russia...@googlegroups.com

Yuri Zhloba

unread,
Jul 12, 2012, 1:00:53 AM7/12/12
to erlang-...@googlegroups.com
>> Под третьим вариантом ведь понимается пул коннектов?
>> Т.е. API у него навроде
>>
>> acquire(Pool) -> Connection
>> release(Pool, Connection) -> ok
>>
>> И если я сделал acquire, то из пула изымается один свободный коннект (если
>> свободных нет, то создается новый либо ждем освобождения) и выдается мне в
>> монопольное использование до тех пор пока я его не верну через release?

Нет, это усовершенствованый первый вариант. В третьем варианте
Connection спрятан внутри специального процесса и только этот процесс
выполняет запросы к базе.

12 июля 2012 г., 7:06 пользователь Alexandr Alexeev <afi...@gmail.com> написал:


> Вроде же можно функции передавать, нет? Путь передается функция, которая
> принимает в качестве параметра соединение и работает с ним в транзакции.
> Тогда вы не забудете освободить ресурс, а если постараться, то и транзакцию
> закрыть. (PS. Новичок в Erlang, так что извините, если пишу глупости).
>

Да, типа того. Только я передаю не функцию, а сроку, содержащую SQL
запрос, и параметры для него. Но лучше передавать функцию, если нужны
транзакции.

Un Lexx

unread,
Jul 12, 2012, 10:45:36 PM7/12/12
to erlang-...@googlegroups.com
итого получается что целостность транзакции гарантируется этим процессов владельцем соединение к базе.
производительность повышается изза того что используется несколько такого типа процессов и состояние транзакции не обрывается изза вклинивания других запросов.

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

12 июля 2012 г., 11:00 пользователь Yuri Zhloba <yzh4...@gmail.com> написал:

Sergey Prochorov

unread,
Jul 13, 2012, 7:01:06 AM7/13/12
to erlang-...@googlegroups.com
ИМХО, предложенный мной вариант немного получше (с дополнением от Александра Алексеева) тем что не используется промежуточный процесс, которому все данные для запроса нужно еще передать (а это лишние копирования). А целостность гарантируется тем, что коннекшн выдается эксклюзивно.
По-моему как раз такая схема используется в epgsql_pool https://github.com/josephwecker/epgsql_pool

четверг, 12 июля 2012 г., 9:00:53 UTC+4 пользователь Yuri Zhloba написал:
>> Под третьим вариантом ведь понимается пул коннектов?
>> Т.е. API у него навроде
>>
>> acquire(Pool) -> Connection
>> release(Pool, Connection) -> ok
>>
>> И если я сделал acquire, то из пула изымается один свободный коннект (если
>> свободных нет, то создается новый либо ждем освобождения) и выдается мне в
>> монопольное использование до тех пор пока я его не верну через release?

Нет, это усовершенствованый первый вариант. В третьем варианте
Connection спрятан внутри специального процесса и только этот процесс
выполняет запросы к базе.

12 июля 2012 г., 7:06 пользователь Alexandr Alexeev <> написал:

Reply all
Reply to author
Forward
0 new messages