[Erlang] Эффективная работа с Mnesia
От: avostrjakov  
Дата: 03.07.08 08:09
Оценка:
Привет!

Пишем часть системы, которая работает с базой данных Mnesia. Набор функций для работы с базой в общем-то написали,
но есть сомнения в одном месте по эффективности.

Код создающий таблицу в базе:

    -record(artmessage, {id, authorId, recipientId, sendDate, messageData, deliveryStateId = 0}).

    mnesia:create_table(artmessage,
        [{disc_copies, [node()]},
         {index, [authorId, recipientId]},
         {attributes, record_info(fields, artmessage)}]),



А вот и функция выбирающая данные из этой таблицы:
selectNextArtMessage(RecipientId) -> 
    F = fun() -> 
       QH = qlc:sort(
                  qlc:q([{M, size(M#artmessage.messageData)} || 
            M <- mnesia:table(artmessage),
                M#artmessage.recipientId == RecipientId, M#artmessage.deliveryStateId == 0]), 
              {order, fun(A,B)-> A#artmessage.sendDate < B#artmessage.sendDate end}),
       QC = qlc:cursor(QH),
       Result = qlc:next_answers(QC, 1),
       qlc:delete_cursor(QC),
       Result
    end,
    mnesia:transaction(F).


В таблице храняться сообщения. Важно чтобы выборка сообщений происходила в том же порядке в котором они туда добавляются.
Поэтому данные выбираются в отсортированном виде по дате создания записи в таблице (предположим, что дата создания храниться
в виде обычного целого числа). Записей в таблице может быть около 10 тысяч (после отправки сообщения соответствующая запись
удаляется из таблицы).
Вопрос заключается в том, насколько эффективно так работать с Mnesia?

Anatoly Vostryakov
Re: [Erlang] Эффективная работа с Mnesia
От: Курилка Россия http://kirya.narod.ru/
Дата: 03.07.08 08:15
Оценка:
Здравствуйте, avostrjakov, Вы писали:

[cut]
A> Вопрос заключается в том, насколько эффективно так работать с Mnesia?
А сделать тесты и посмотреть не пробовали?
Ну и зачем мнезия-то в принципе нужна, если фактически простой буфер вы организуете?
Re[2]: [Erlang] Эффективная работа с Mnesia
От: avostrjakov  
Дата: 03.07.08 17:55
Оценка:
Здравствуйте, Курилка, Вы писали:

A>> Вопрос заключается в том, насколько эффективно так работать с Mnesia?

К>А сделать тесты и посмотреть не пробовали?

Интересно узнать в принципе применять сортировку при высокой нагрузке можно?
Пока не тестировали.

К>Ну и зачем мнезия-то в принципе нужна, если фактически простой буфер вы организуете?


Нужно чтобы данные не потерялись при сбое одного компьютера в mnesia. Это сообщения пользователей.
То есть только в кэше их держать нельзя.
Re: [Erlang] Эффективная работа с Mnesia
От: Gaperton http://gaperton.livejournal.com
Дата: 03.07.08 18:36
Оценка:
Здравствуйте, avostrjakov, Вы писали:

Каковы типичные сценарии применения этой штуковины? Сколько процессов пишут/читают? В чем мотивация применения Мнезии? Зачем нужно disk_copies?
Re[3]: [Erlang] Эффективная работа с Mnesia
От: Курилка Россия http://kirya.narod.ru/
Дата: 04.07.08 05:26
Оценка:
Здравствуйте, avostrjakov, Вы писали:

A>Здравствуйте, Курилка, Вы писали:


A>>> Вопрос заключается в том, насколько эффективно так работать с Mnesia?

К>>А сделать тесты и посмотреть не пробовали?

A> Интересно узнать в принципе применять сортировку при высокой нагрузке можно?

Можно всё, нужно ли — вот в чём вопрос.
Ложить в мнезию, а потом пересортировывать мне кажется не очень естественным.
Я бы скорее держал список сообщений в памяти в виде queue, который можно выкидывать в mnesia, если есть боязнь за сохранность данных (на эти сценарии тоже нужны тесты на мой взгляд).
A>Пока не тестировали.
Имхо тут без тестов выкладывать код в продакшн по меньшей мере не очень профессионально.

К>>Ну и зачем мнезия-то в принципе нужна, если фактически простой буфер вы организуете?


A> Нужно чтобы данные не потерялись при сбое одного компьютера в mnesia. Это сообщения пользователей.

A>То есть только в кэше их держать нельзя.
Как рядом спросил гапертон — а нафига disc_copies? Если речь про сбой одного компьютера, то значит их несколько у вас? ram_copies ведь аналогично реплицируются, только на диск не выгружаются (т.е. выкидываем лишний оверхэд на дисковый I/O)
Re[2]: [Erlang] Эффективная работа с Mnesia
От: avostrjakov  
Дата: 04.07.08 10:00
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Каковы типичные сценарии применения этой штуковины?


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

G>Сколько процессов пишут/читают?


Пока это все прототип. Пишет и читает один процесс. В будущем будет много: сотни.

G>В чем мотивация применения Мнезии?


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

G>Зачем нужно disk_copies?


В память все это может не влезть, т.к. сообщения достаточно большие. Во-вторых, в случае падения легче восстановиться с диска.
Re[3]: [Erlang] Эффективная работа с Mnesia
От: Gaperton http://gaperton.livejournal.com
Дата: 06.07.08 09:40
Оценка:
Здравствуйте, avostrjakov, Вы писали:

G>>Каковы типичные сценарии применения этой штуковины?


A> В данной таблицы храняться сообщения от одного пользователя другому. Храняться пока не доставяться

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

Я не до конца понимаю, что у вас за задача, но у меня есть стойкое ощущение, что вы делаете что-то не так. Очень уж странно как-то получается.

G>>Сколько процессов пишут/читают?


A> Пока это все прототип. Пишет и читает один процесс. В будущем будет много: сотни.


Сколько точно будет процессов? По одному на пользователя, нет? Короче говоря, пока вы задачу не опишете, вряд-ли кто-то сможет вам прокомментировать по сути.

G>>Зачем нужно disk_copies?


A> В память все это может не влезть, т.к. сообщения достаточно большие. Во-вторых, в случае падения легче восстановиться с диска.


Во-первых, вся таблица целиком хранится в памяти даже в случае disc_copies — на диск пишутся только изменения, и последовательно. disc_copies применяется только для восстановления таблицы при старте. "По настоящему" на диске это будет лежать только в случае disc_only. Насчет disc_only надо еще сказать, что одна таблица не может превышать 2GB в любом случае — придется fragmented tables использовать, чтобы это обойти.

Во-вторых, мнезия должна после падения прекрасно восстановится и с другой машины — не понятно, почему с диска восстановится "легче". Она же умеет и так и так, и она железная, ей все равно как восстанавливаться, нет?
Re[4]: [Erlang] Эффективная работа с Mnesia
От: avostrjakov  
Дата: 07.07.08 20:26
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Здравствуйте, avostrjakov, Вы писали:


A>>Здравствуйте, Курилка, Вы писали:


A>>>> Вопрос заключается в том, насколько эффективно так работать с Mnesia?

К>>>А сделать тесты и посмотреть не пробовали?

A>> Интересно узнать в принципе применять сортировку при высокой нагрузке можно?

К>Можно всё, нужно ли — вот в чём вопрос.
К>Ложить в мнезию, а потом пересортировывать мне кажется не очень естественным.

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

К>Я бы скорее держал список сообщений в памяти в виде queue, который можно выкидывать в mnesia, если есть боязнь за сохранность данных (на эти сценарии тоже нужны тесты на мой взгляд).


Ладно, давай так. В пределе эта система должна выдерживать нагрузку в 3 миллиона пользователей, скажем по три сообщения от каждого. Размер каждого сообщения в среднем 100 кб (это графика). А тут сортировка
Queue выдержит? Mnesia выдержит?

A>>Пока не тестировали.

К>Имхо тут без тестов выкладывать код в продакшн по меньшей мере не очень профессионально.

Да, ты что Какой продакшен Прототип пишем. Мнезию изучаем пораллельно. Вот вопросы задаю умным людям здесь


К>>>Ну и зачем мнезия-то в принципе нужна, если фактически простой буфер вы организуете?


A>> Нужно чтобы данные не потерялись при сбое одного компьютера в mnesia. Это сообщения пользователей.

A>>То есть только в кэше их держать нельзя.
К>Как рядом спросил гапертон — а нафига disc_copies? Если речь про сбой одного компьютера, то значит их несколько у вас? ram_copies ведь аналогично реплицируются, только на диск не выгружаются (т.е. выкидываем лишний оверхэд на дисковый I/O)
Re[4]: [Erlang] Эффективная работа с Mnesia
От: avostrjakov  
Дата: 07.07.08 20:35
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Здравствуйте, avostrjakov, Вы писали:


G>>>Каковы типичные сценарии применения этой штуковины?


A>> В данной таблицы храняться сообщения от одного пользователя другому. Храняться пока не доставяться

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

G>Я не до конца понимаю, что у вас за задача, но у меня есть стойкое ощущение, что вы делаете что-то не так. Очень уж странно как-то получается.


G>>>Сколько процессов пишут/читают?


A>> Пока это все прототип. Пишет и читает один процесс. В будущем будет много: сотни.


G>Сколько точно будет процессов? По одному на пользователя, нет? Короче говоря, пока вы задачу не опишете, вряд-ли кто-то сможет вам прокомментировать по сути.


Ок, Возьмем по максимуму. Считаем, что один процесс на пользователя. Одновременно передаваемых сообщений скажем 100 тысяч. Каждое сообщение размером примерно 100 Кб. В таблице может находиться примерно 4 миллиона записей. Одни процессы кладут туда записи, другие забирают данные (см. мой первоночальный пост).

G>>>Зачем нужно disk_copies?


A>> В память все это может не влезть, т.к. сообщения достаточно большие. Во-вторых, в случае падения легче восстановиться с диска.


G>Во-первых, вся таблица целиком хранится в памяти даже в случае disc_copies — на диск пишутся только изменения, и последовательно. disc_copies применяется только для восстановления таблицы при старте. "По настоящему" на диске это будет лежать только в случае disc_only. Насчет disc_only надо еще сказать, что одна таблица не может превышать 2GB в любом случае — придется fragmented tables использовать, чтобы это обойти.


2 GB — это ограничение мнезии? Подскажи пожайлуста, где про это написано.

G>Во-вторых, мнезия должна после падения прекрасно восстановится и с другой машины — не понятно, почему с диска восстановится "легче". Она же умеет и так и так, и она железная, ей все равно как восстанавливаться, нет?


Про восстановление мнезии согласен. Когда я отвечал, то думал, что ты предлагаешь использовать некий кэш в памяти, а не мнезию.
Re[5]: [Erlang] Эффективная работа с Mnesia
От: Курилка Россия http://kirya.narod.ru/
Дата: 08.07.08 05:15
Оценка:
Здравствуйте, avostrjakov, Вы писали:

A> Такой вопрос: mnesia гарантирует, что если я создам несколько записей в таблице и потом выберу их оттуда, то порядок записей сохраниться?

A>Если да, то сортировка не нужна будет.

Вопрос в том, зачем тебе перекладывать расходы на сортировку на мнезию, если тебе нужен "естественный" (по мере поступления) порядок сообщений.
Т.е. зачем тебе такие накладные расходы, без которых элементарно можно обойтись?

К>>Я бы скорее держал список сообщений в памяти в виде queue, который можно выкидывать в mnesia, если есть боязнь за сохранность данных (на эти сценарии тоже нужны тесты на мой взгляд).


A> Ладно, давай так. В пределе эта система должна выдерживать нагрузку в 3 миллиона пользователей, скажем по три сообщения от каждого. Размер каждого сообщения в среднем 100 кб (это графика). А тут сортировка

A> Queue выдержит? Mnesia выдержит?

По 3 сообщения одновременно? Или в час?
Сформулируй более точно: какова средняя нагрузка и пиковая.
Ну и если queue не выдержит, то мнезия сразу пойдёт лесом, т.к. к памяти у мнезии ещё большие требования.
Если уж совсем элементарно: если в память не влезет, то тебе ничто не поможет
К чему вопрос про сортировку я не понял.
В случае с queue у тебя будут данные гарантированно отсортированы, для мнезии же они будут сортированы если используешь ordered_set, но вставка возможно будет тупить, т.к. никто не ожидает от тебя упорядоченных данных (т.е. будет искаться место в таблице куда будет вставляться строка).

A>>>Пока не тестировали.

К>>Имхо тут без тестов выкладывать код в продакшн по меньшей мере не очень профессионально.

A> Да, ты что Какой продакшен Прототип пишем. Мнезию изучаем пораллельно. Вот вопросы задаю умным людям здесь


Дак если прототип, то производительность по-моему первое, что надо мерять, если конечно вам не пофигу как быстро оно будет работать.
Re[6]: [Erlang] Эффективная работа с Mnesia
От: avostrjakov  
Дата: 08.07.08 20:59
Оценка:
Здравствуйте, Курилка, Вы писали:

A>> Такой вопрос: mnesia гарантирует, что если я создам несколько записей в таблице и потом выберу их оттуда, то порядок записей сохраниться?

A>>Если да, то сортировка не нужна будет.

К>Вопрос в том, зачем тебе перекладывать расходы на сортировку на мнезию, если тебе нужен "естественный" (по мере поступления) порядок сообщений.

К>Т.е. зачем тебе такие накладные расходы, без которых элементарно можно обойтись?

Мы, как опытные евреи можем долго друг другу задавать свои вопросы и не отвечать на вопросы другого Давай так, нам интересно с тобой будет пообщаться по скайпу или лично. Так как похоже ты разбираешься в этом вопросе. Мой скайп-аккаунт: magic_tolik. Мой e-mail: vostrjakov @ майл.ru
Выходи на связь. Все расскажем про свою задачу и пообщаемся за одно. Возможно и проект наш тебе будет интересен

К>>>Я бы скорее держал список сообщений в памяти в виде queue, который можно выкидывать в mnesia, если есть боязнь за сохранность данных (на эти сценарии тоже нужны тесты на мой взгляд).


A>> Ладно, давай так. В пределе эта система должна выдерживать нагрузку в 3 миллиона пользователей, скажем по три сообщения от каждого. Размер каждого сообщения в среднем 100 кб (это графика). А тут сортировка

A>> Queue выдержит? Mnesia выдержит?

К>По 3 сообщения одновременно? Или в час?

К>Сформулируй более точно: какова средняя нагрузка и пиковая.
К>Ну и если queue не выдержит, то мнезия сразу пойдёт лесом, т.к. к памяти у мнезии ещё большие требования.
К>Если уж совсем элементарно: если в память не влезет, то тебе ничто не поможет
К>К чему вопрос про сортировку я не понял.
К>В случае с queue у тебя будут данные гарантированно отсортированы, для мнезии же они будут сортированы если используешь ordered_set, но вставка возможно будет тупить, т.к. никто не ожидает от тебя упорядоченных данных (т.е. будет искаться место в таблице куда будет вставляться строка).

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

A>>>>Пока не тестировали.

К>>>Имхо тут без тестов выкладывать код в продакшн по меньшей мере не очень профессионально.

A>> Да, ты что Какой продакшен Прототип пишем. Мнезию изучаем пораллельно. Вот вопросы задаю умным людям здесь


К>Дак если прототип, то производительность по-моему первое, что надо мерять, если конечно вам не пофигу как быстро оно будет работать.


Будем, как напишем прототип. Пока он еще не закончен.
Re[5]: [Erlang] Эффективная работа с Mnesia
От: Gaperton http://gaperton.livejournal.com
Дата: 09.07.08 09:55
Оценка:
Здравствуйте, avostrjakov, Вы писали:

G>>Сколько точно будет процессов? По одному на пользователя, нет? Короче говоря, пока вы задачу не опишете, вряд-ли кто-то сможет вам прокомментировать по сути.


A> Ок, Возьмем по максимуму. Считаем, что один процесс на пользователя. Одновременно передаваемых сообщений скажем 100 тысяч. Каждое сообщение размером примерно 100 Кб. В таблице может находиться примерно 4 миллиона записей. Одни процессы кладут туда записи, другие забирают данные (см. мой первоночальный пост).


Один процесс на пользователя, пользователи посылают друг другу сообщения. Вопрос: зачем все сообщения хранить в одной таблице? Почему не завести отдельный inbox для каждого пользователя, что мешает? Еще вопрос: что означает "одновременно передаваемых сообщений"? Вы хотели сказать, пользователей у вас в системе 100 тысяч, так?

G>>Во-первых, вся таблица целиком хранится в памяти даже в случае disc_copies — на диск пишутся только изменения, и последовательно. disc_copies применяется только для восстановления таблицы при старте. "По настоящему" на диске это будет лежать только в случае disc_only. Насчет disc_only надо еще сказать, что одна таблица не может превышать 2GB в любом случае — придется fragmented tables использовать, чтобы это обойти.


A> 2 GB — это ограничение мнезии? Подскажи пожайлуста, где про это написано.


2Gb — это ограничение на размер таблицы dets, которая применяется mnesia в случае disc_only. Где конкретно написано — не помню, но пока это так.
Re[6]: [Erlang] Эффективная работа с Mnesia
От: avostrjakov  
Дата: 09.07.08 16:11
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>>>Сколько точно будет процессов? По одному на пользователя, нет? Короче говоря, пока вы задачу не опишете, вряд-ли кто-то сможет вам прокомментировать по сути.


A>> Ок, Возьмем по максимуму. Считаем, что один процесс на пользователя. Одновременно передаваемых сообщений скажем 100 тысяч. Каждое сообщение размером примерно 100 Кб. В таблице может находиться примерно 4 миллиона записей. Одни процессы кладут туда записи, другие забирают данные (см. мой первоночальный пост).


G>Один процесс на пользователя, пользователи посылают друг другу сообщения. Вопрос: зачем все сообщения хранить в одной таблице? Почему не завести отдельный inbox для каждого пользователя, что мешает? Еще вопрос: что означает "одновременно передаваемых сообщений"? Вы хотели сказать, пользователей у вас в системе 100 тысяч, так?


Извини, но мы ушли уже далеко от первоначального вопроса. Мне было интересно узнать, насколько вообще возможно применять сортировку в mnesia в случае, когда база находиться на нескольких нодах, кол-во записей в таблице большое (предвидя вопрос, около 4 миллионов записей) и большой нагрузке на базу (возьмем 100 тысяч одновременных запросов в базу, запросы разные, не только к таблице с сообщениями).

G>>>Во-первых, вся таблица целиком хранится в памяти даже в случае disc_copies — на диск пишутся только изменения, и последовательно. disc_copies применяется только для восстановления таблицы при старте. "По настоящему" на диске это будет лежать только в случае disc_only. Насчет disc_only надо еще сказать, что одна таблица не может превышать 2GB в любом случае — придется fragmented tables использовать, чтобы это обойти.


A>> 2 GB — это ограничение мнезии? Подскажи пожайлуста, где про это написано.


G>2Gb — это ограничение на размер таблицы dets, которая применяется mnesia в случае disc_only. Где конкретно написано — не помню, но пока это так.


Спасибо, нашел, где написано про это:
http://www.erlang.org/doc/man/dets.html
Re[7]: [Erlang] Эффективная работа с Mnesia
От: Курилка Россия http://kirya.narod.ru/
Дата: 09.07.08 16:48
Оценка:
Здравствуйте, avostrjakov, Вы писали:



A> Извини, но мы ушли уже далеко от первоначального вопроса. Мне было интересно узнать, насколько вообще возможно применять сортировку в mnesia в случае, когда база находиться на нескольких нодах, кол-во записей в таблице большое (предвидя вопрос, около 4 миллионов записей) и большой нагрузке на базу (возьмем 100 тысяч одновременных запросов в базу, запросы разные, не только к таблице с сообщениями).


Изначально вроде же было всего 10 000
И вопрос первоначальный выглядел иначе...

G>>2Gb — это ограничение на размер таблицы dets, которая применяется mnesia в случае disc_only. Где конкретно написано — не помню, но пока это так.


A> Спасибо, нашел, где написано про это:

A>http://www.erlang.org/doc/man/dets.html

Ну не всё так уж совсем грустно, есть варианты (via Mamut )
Re[7]: [Erlang] Эффективная работа с Mnesia
От: Курилка Россия http://kirya.narod.ru/
Дата: 09.07.08 16:58
Оценка:
Здравствуйте, avostrjakov, Вы писали:

A>Здравствуйте, Курилка, Вы писали:


К>>В случае с queue у тебя будут данные гарантированно отсортированы, для мнезии же они будут сортированы если используешь ordered_set, но вставка возможно будет тупить, т.к. никто не ожидает от тебя упорядоченных данных (т.е. будет искаться место в таблице куда будет вставляться строка).


A> Понял. Queue не подойдет, сообщения могут достаточно долгое время лежать в таблице, пока клиент, которому они предназначаются их не попросит. То есть НЕ сервер отправляет сообщения клиенту сам, а клиент запрашивает свои сообщения у сервера.


Смотрю ТЗ как обычно всё меняется и меняется
Предлагаю тогда другой вариант — в queue хранить некую "ключевую" информацию по сообщениям, а сами уже где-нибудь "оффлайн" дабы не засорять рабочее пространство (файлы или мнезия, решения могут быть разные). Ну и можно изобразить что-то типа GC, когда долго лежащие сообщения будут скидываться на диск (например если в течении минуты были невостребованы).
Но это всё мои домыслы, без понимания задачи целиком (e.g. что за запросы и когда появляются) тут трудно что-либо советовать.
Основная мысль у меня всё та же — зачем тебе сортировать если можно не сортировать?

К>>Дак если прототип, то производительность по-моему первое, что надо мерять, если конечно вам не пофигу как быстро оно будет работать.


A> Будем, как напишем прототип. Пока он еще не закончен.


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

P.S. на почту отписал.
Re[7]: [Erlang] Эффективная работа с Mnesia
От: Gaperton http://gaperton.livejournal.com
Дата: 09.07.08 20:54
Оценка: +1
Здравствуйте, avostrjakov, Вы писали:

G>>Один процесс на пользователя, пользователи посылают друг другу сообщения. Вопрос: зачем все сообщения хранить в одной таблице? Почему не завести отдельный inbox для каждого пользователя, что мешает? Еще вопрос: что означает "одновременно передаваемых сообщений"? Вы хотели сказать, пользователей у вас в системе 100 тысяч, так?


A> Извини, но мы ушли уже далеко от первоначального вопроса. Мне было интересно узнать, насколько вообще возможно применять сортировку в mnesia в случае, когда база находиться на нескольких нодах, кол-во записей в таблице большое (предвидя вопрос, около 4 миллионов записей) и большой нагрузке на базу (возьмем 100 тысяч одновременных запросов в базу, запросы разные, не только к таблице с сообщениями).


Извини, я думал тебе интересно, как твою задачу правильно на Эрланге решать. А тебе оказывается интересна работа Мнезии в специфическом режиме, неадекватном задаче- над этим я думать не хочу. В чем проблема — меряй свой прототип. Ты ведь именно за этим его и пишешь.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.