Асинхронный драйвер MySQL есть ли?

174 views
Skip to first unread message

Andy

unread,
Dec 4, 2012, 7:40:14 AM12/4/12
to
Сейчас используем EMySQL. Сервер (некоторое время уже) перегружен, основная нагрузка (с моей стороны) - это вставка и обновление. Сейчас пишут в базу воркеры, обслуживающие устройства. Раньше был пул MySQL воркеров (поверх пула EMySQL). Случаются таймауты. Хотелось бы запускать запросы асинхронно, впоследствии получая подтверждения; при этом не хочется городить пул отдельных воркеров для этого (как раньше было): душа не лежит. Один из вариантов: использовать функции EMySQL более низкого уровня. Но, может быть, есть уже библиотека для асинхронной работы (OTP based)? Ближайший аналог - RabbitMQ erlang client, Cowboy/Ranch.

Dmitry Belyaev

unread,
Dec 4, 2012, 7:57:37 AM12/4/12
to erlang-...@googlegroups.com
Протокол общения с mysql, когда я его смотрел пару лет назад, был синхронным. Что-то изменилось?

-- 
Dmitry Belyaev

On 04.12.2012, at 16:39, Andy <avel...@positrace.com> wrote:

Сейчас используем EMySQL. Сервер (некоторое время уже) перегружен, основная нагрузка (с моей стороны) - это вставка и обновление. Сейчас пишут в базу воркеры, обслуживающие устройства. Раньше был пул MySQL воркеров (поверх пула EMySQL). Случаются таймауты. Хотелось бы запускать запросы асинхронно, впоследствии получая подтверждения; при этом не хочется городить пул отдельных воркеров для этого (как раньше было): душа не лежит. Один из вариантов: использовать функции EMySQL более низкого уровня. Но, может быть, есть уже библиотека для асинхронной работы? Ближайший аналог - RabbitMQ erlang client.

--
--
Страница рассылки: http://groups.google.com/group/erlang-russian
Новости: http://erlanger.ru
Чат: xmpp://erl...@conference.jabber.ru
Чат для оффтопа: xmpp://erlang...@conference.jabber.ru
Правила, действующие в чате и рассылке: http://erlanger.ru/ru/erlang-at-conference-jabber-ru
 
Написать письмо: erlang-...@googlegroups.com
Отписаться: erlang-russia...@googlegroups.com
 
 

Yuri Zhloba

unread,
Dec 4, 2012, 7:57:33 AM12/4/12
to erlang-...@googlegroups.com
> Протокол общения с mysql, когда я его смотрел пару лет назад, был
> синхронным. Что-то изменилось?
>
При этом асинхронный драйвер все равно можно сделать )

Dmitry Belyaev

unread,
Dec 4, 2012, 8:17:29 AM12/4/12
to erlang-...@googlegroups.com
Разве что динамическим расширением пула. Это то, что требуется?

--
Dmitry Belyaev

Anton Fedorov

unread,
Dec 4, 2012, 8:19:56 AM12/4/12
to erlang-...@googlegroups.com
Еще можно очередью запросов.

В письме от Втр, 04 Дек 2012, 20:17 Dmitry Belyaev пишет:
--
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)]

sui

unread,
Dec 4, 2012, 8:26:53 AM12/4/12
to erlang-...@googlegroups.com
думаю что под асинхронностью подразумевается то что процесс который хочет выполнить запрос не блочится, а результат выполнения запроса получает потом в виде колбека или сообщения.

только вот если база не справляется, то очередь запросов будет только разрастаться. в таких случаях лучше однотипные INSERT-ы накапливать и потом вставлять одним запросом. Или если это не возможно переносить эти данные в nosql решение

Andy

unread,
Dec 4, 2012, 9:13:39 AM12/4/12
to erlang-...@googlegroups.com

On Tuesday, December 4, 2012 3:26:53 PM UTC+2, sui wrote:
думаю что под асинхронностью подразумевается то что процесс который хочет выполнить запрос не блочится, а результат выполнения запроса получает потом в виде колбека или сообщения.
Да, хочется колбеков (как в Cowboy) или сообщений (RabbitMQ).


только вот если база не справляется, то очередь запросов будет только разрастаться. в таких случаях лучше однотипные INSERT-ы накапливать и потом вставлять одним запросом. Или если это не возможно переносить эти данные в nosql решение
Попутно вспомнилось еще: сейчас использую скомпилированный запрос. Насколько я понял, для него нельзя задать список параметров для нескольких инсертов сразу (если их количество заранее неизвестно). Что лучше: использовать поочередные скомпилированные инсерты или динамически сгенерированный групповой в виде текста?

NoSQL на очереди, но legacy тормозит сильно. 

Andy

unread,
Dec 4, 2012, 9:18:35 AM12/4/12
to erlang-...@googlegroups.com


On Tuesday, December 4, 2012 3:17:29 PM UTC+2, Dmitry Belyaev wrote:
Разве что динамическим расширением пула. Это то, что требуется?
Нет. Внутри библиотеки (конкретно emysql:monitor_work) используется асинхронный вызов, но только он тут же синхронизируется (аки gen_server:call). Понятно, что можно переписать emysql:monitor_work самому, но тогда придется самому и мейнтнейнить свою версию. Хотелось бы (нет, не странного) готовое решение.

sui

unread,
Dec 4, 2012, 9:21:54 AM12/4/12
to erlang-...@googlegroups.com
я так думаю что компилирование запроса это не основная проблема. Больше нагрузки создает перестройка индекса, проверка ключей и тд.
Я бы юзал динамический, не скомпилированный, и вставлял бы после того как накопится более 1000 записей, или до этого успевает сработать таймер.

Andy

unread,
Dec 4, 2012, 9:30:01 AM12/4/12
to erlang-...@googlegroups.com


On Tuesday, December 4, 2012 4:21:54 PM UTC+2, sui wrote:
я так думаю что компилирование запроса это не основная проблема. Больше нагрузки создает перестройка индекса, проверка ключей и тд.
Я бы юзал динамический, не скомпилированный, и вставлял бы после того как накопится более 1000 записей, или до этого успевает сработать таймер.
Такой подход используется в аналогичном коде, но бенчмарков не проводили. С другой стороны где-то в обосновании идеи NoSQL видел, что существенное время уходит на компиляцию запросов. Но я так понял, это если нету горлышка в виде дисковых операций. 

Max Lapshin

unread,
Dec 4, 2012, 9:37:25 AM12/4/12
to erlang-...@googlegroups.com
Насколько я помню довольно старые бенчмарки, вариант с вставлением нескольких тысяч строк одним инсертом сильно лучше, чем несколько тысяч раз дернуть инсерт.


2012/12/4 Andy <avel...@positrace.com>

Andy

unread,
Dec 4, 2012, 10:09:45 AM12/4/12
to erlang-...@googlegroups.com


On Tuesday, December 4, 2012 4:37:25 PM UTC+2, Max Lapshin wrote:
Насколько я помню довольно старые бенчмарки, вариант с вставлением нескольких тысяч строк одним инсертом сильно лучше, чем несколько тысяч раз дернуть инсерт.
Спасибо. Для моего случая, думаю, сотни-двух хватит; у меня сейчас порядка десятка записей в секунду.
А по самому первому вопросу, я так понял, новостей нет. Придумал еще архитектуру: по одному воркеру СУБД на один типовой инсерт; каждый накапливает очередь, потом группой вставляет, при этом перехватывает исключения; при наличии исключения повторяет позже.

И вдогонку: для операций обновления прокатит оптимизация с накоплением?

sui

unread,
Dec 4, 2012, 10:46:58 AM12/4/12
to erlang-...@googlegroups.com
> Придумал еще архитектуру: по одному воркеру СУБД на один типовой инсерт; каждый накапливает очередь, потом группой вставляет, при этом перехватывает исключения; при наличии исключения повторяет позже.

да я про то и говорил) Только минусы такого подхода в том что иногда измененные данные нужны немедленно. Кстати для длинных запросов обычно нужно в настройках мускуля увеличивать различные параметры типа max_allowed_packet.

По апдейтам смотря что менять. Нужно же по какому то признаку группировать запросы. Если там счетчики какие нибудь то без проблем. Универсального алгоритма, на сколько мне известно, нет. Нужно отталкиватся от текущей задачи)


>А по самому первому вопросу, я так понял, новостей нет.

для erlang я таких модулей не видел. Да и не факт что асинк тут поможет. Скорее всего очередь просто копится будет. По мне, так асинк для работы с базой это лишний геморой.

Andrei Dziahel

unread,
Dec 4, 2012, 10:51:27 AM12/4/12
to erlang-...@googlegroups.com
А если собирать здоровенный запрос лень или нельзя, можно завернуть пачку инсертов в транзакцию — производительность будет почти идентична.


2012/12/4 Max Lapshin <max.l...@gmail.com>



--
Regards,
Andrei Dziahel

Boris Timokhin

unread,
Dec 4, 2012, 11:09:49 AM12/4/12
to erlang-...@googlegroups.com


4 декабря 2012 г., 19:09 пользователь Andy <avel...@positrace.com> написал:



On Tuesday, December 4, 2012 4:37:25 PM UTC+2, Max Lapshin wrote:
Насколько я помню довольно старые бенчмарки, вариант с вставлением нескольких тысяч строк одним инсертом сильно лучше, чем несколько тысяч раз дернуть инсерт.
Спасибо. Для моего случая, думаю, сотни-двух хватит; у меня сейчас порядка десятка записей в секунду.
А по самому первому вопросу, я так понял, новостей нет. Придумал еще архитектуру: по одному воркеру СУБД на один типовой инсерт; каждый накапливает очередь, потом группой вставляет, при этом перехватывает исключения; при наличии исключения повторяет позже.


У вас множество клиентов, каждый со своей транзакцией и вы планируете их все вместе вставлять? Что здесь от ACID остается?

Sergey Prokhorov

unread,
Dec 4, 2012, 6:54:45 PM12/4/12
to erlang-...@googlegroups.com
Правильно понял, что тормозит на 10 инсертов/апдейтов в секунду? Какая-то скромная совсем цифра... Или там запросы сложные? Или слишком строгие настройки бд?
Просто у меня Postgres, пул подключений - 10 постоянных и с динамическим расширением до 20, вообще без каких-то проблем делает 150 инсертов в секунду (причем каждый в транзакцию завернут, запросы без предварительной компиляции).

вторник, 4 декабря 2012 г., 19:09:45 UTC+4 пользователь Andy написал:

Andy

unread,
Dec 5, 2012, 2:09:38 AM12/5/12
to erlang-...@googlegroups.com


On Wednesday, December 5, 2012 1:54:45 AM UTC+2, Sergey Prokhorov wrote:
Правильно понял, что тормозит на 10 инсертов/апдейтов в секунду? Какая-то скромная совсем цифра... Или там запросы сложные? Или слишком строгие настройки бд?
Моя подсистема (пока) обеспечивает довольно скромный вклад в общее дело :)

Andy

unread,
Dec 5, 2012, 2:12:09 AM12/5/12
to erlang-...@googlegroups.com


On Tuesday, December 4, 2012 6:09:49 PM UTC+2, Boris Timokhin wrote:


4 декабря 2012 г., 19:09 пользователь Andy <avel...@positrace.com> написал:


On Tuesday, December 4, 2012 4:37:25 PM UTC+2, Max Lapshin wrote:
Насколько я помню довольно старые бенчмарки, вариант с вставлением нескольких тысяч строк одним инсертом сильно лучше, чем несколько тысяч раз дернуть инсерт.
Спасибо. Для моего случая, думаю, сотни-двух хватит; у меня сейчас порядка десятка записей в секунду.
А по самому первому вопросу, я так понял, новостей нет. Придумал еще архитектуру: по одному воркеру СУБД на один типовой инсерт; каждый накапливает очередь, потом группой вставляет, при этом перехватывает исключения; при наличии исключения повторяет позже.


У вас множество клиентов, каждый со своей транзакцией и вы планируете их все вместе вставлять? Что здесь от ACID остается?
??? Элементарные инсерты (конкретно один инсерт в одну таблицу на одну точку) нельзя группировать? Вроде ж ACID для связанных операций предназначался (хорошо помню связанные транзакции по бухгалтерии)?

Boris Timokhin

unread,
Dec 5, 2012, 3:30:51 AM12/5/12
to erlang-...@googlegroups.com


5 декабря 2012 г., 11:12 пользователь Andy <avel...@positrace.com> написал:



On Tuesday, December 4, 2012 6:09:49 PM UTC+2, Boris Timokhin wrote:


4 декабря 2012 г., 19:09 пользователь Andy <avel...@positrace.com> написал:



On Tuesday, December 4, 2012 4:37:25 PM UTC+2, Max Lapshin wrote:
Насколько я помню довольно старые бенчмарки, вариант с вставлением нескольких тысяч строк одним инсертом сильно лучше, чем несколько тысяч раз дернуть инсерт.
Спасибо. Для моего случая, думаю, сотни-двух хватит; у меня сейчас порядка десятка записей в секунду.
А по самому первому вопросу, я так понял, новостей нет. Придумал еще архитектуру: по одному воркеру СУБД на один типовой инсерт; каждый накапливает очередь, потом группой вставляет, при этом перехватывает исключения; при наличии исключения повторяет позже.


У вас множество клиентов, каждый со своей транзакцией и вы планируете их все вместе вставлять? Что здесь от ACID остается?
??? Элементарные инсерты (конкретно один инсерт в одну таблицу на одну точку) нельзя группировать? Вроде ж ACID для связанных операций предназначался (хорошо помню связанные транзакции по бухгалтерии)?


Я не знаю что там в бухгалтерии и какое у вас приложение. Если вы уверены, что последствия ваших инсертов, вообще никак не пересекаются в приложении, то конечно.
А если одни процессы делают "элементарные" инсерты, а другие процессы принимают решения об инсертах (может опосредованно) на основании состояния БД "сейчас"?
Надуманный пример: У вас "сайт". Заходит посетитель, хочет зарегестрироваться. Вбивает емаил, пароль. Вы ему "окей, можете залогиниться". Он оказывается на странице авторизации и не может войти со своим емаил и паролем, потому что его "элементарный" инсерт в какой-то очереди. Он оказывается опять у формы регистрации и опять вбивает тотже самый емаил и пароль. В итоге ещё одна запись попадает в ваш "групповой" инсерт. Вы получите в таблице двух пользователей с одним email. А если на уровне БД проверяется уникальность емаил, то ваше решение беконечно долго будет: "....группой вставляет, при этом перехватывает исключения; при наличии исключения повторяет позже...."

Наложите надуманный пример на ваше приложение.

Andy

unread,
Dec 6, 2012, 5:14:18 AM12/6/12
to erlang-...@googlegroups.com


On Wednesday, December 5, 2012 10:30:51 AM UTC+2, Boris Timokhin wrote:
Я не знаю что там в бухгалтерии и какое у вас приложение. Если вы уверены, что последствия ваших инсертов, вообще никак не пересекаются в приложении, то конечно.
...
Наложите надуманный пример на ваше приложение.
Нет, у меня асинхронный поток данных от устройств, ситуация непохожая. Но намек про правильный подбор  таймаутов для записи понял.

Reply all
Reply to author
Forward
0 new messages