Пишем часть системы, которая работает с базой данных Mnesia. Набор функций для работы с базой в общем-то написали,
но есть сомнения в одном месте по эффективности.
А вот и функция выбирающая данные из этой таблицы:
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?
[cut] A> Вопрос заключается в том, насколько эффективно так работать с Mnesia?
А сделать тесты и посмотреть не пробовали?
Ну и зачем мнезия-то в принципе нужна, если фактически простой буфер вы организуете?
Здравствуйте, Курилка, Вы писали:
A>> Вопрос заключается в том, насколько эффективно так работать с Mnesia? К>А сделать тесты и посмотреть не пробовали?
Интересно узнать в принципе применять сортировку при высокой нагрузке можно?
Пока не тестировали.
К>Ну и зачем мнезия-то в принципе нужна, если фактически простой буфер вы организуете?
Нужно чтобы данные не потерялись при сбое одного компьютера в mnesia. Это сообщения пользователей.
То есть только в кэше их держать нельзя.
Здравствуйте, avostrjakov, Вы писали:
A>Здравствуйте, Курилка, Вы писали:
A>>> Вопрос заключается в том, насколько эффективно так работать с Mnesia? К>>А сделать тесты и посмотреть не пробовали?
A> Интересно узнать в принципе применять сортировку при высокой нагрузке можно?
Можно всё, нужно ли — вот в чём вопрос.
Ложить в мнезию, а потом пересортировывать мне кажется не очень естественным.
Я бы скорее держал список сообщений в памяти в виде queue, который можно выкидывать в mnesia, если есть боязнь за сохранность данных (на эти сценарии тоже нужны тесты на мой взгляд). A>Пока не тестировали.
Имхо тут без тестов выкладывать код в продакшн по меньшей мере не очень профессионально.
К>>Ну и зачем мнезия-то в принципе нужна, если фактически простой буфер вы организуете?
A> Нужно чтобы данные не потерялись при сбое одного компьютера в mnesia. Это сообщения пользователей. A>То есть только в кэше их держать нельзя.
Как рядом спросил гапертон — а нафига disc_copies? Если речь про сбой одного компьютера, то значит их несколько у вас? ram_copies ведь аналогично реплицируются, только на диск не выгружаются (т.е. выкидываем лишний оверхэд на дисковый I/O)
Здравствуйте, Gaperton, Вы писали:
G>Каковы типичные сценарии применения этой штуковины?
В данной таблицы храняться сообщения от одного пользователя другому. Храняться пока не доставяться
к конечному пользователю, что иногда может быть долгим процессом.
G>Сколько процессов пишут/читают?
Пока это все прототип. Пишет и читает один процесс. В будущем будет много: сотни.
G>В чем мотивация применения Мнезии?
Мотивация, что она распределенная, то есть можно легко обеспечивается отказоустойчивость за счет распеределения данных на нескольких нодах. Повторю, что пока это все прототип.
G>Зачем нужно disk_copies?
В память все это может не влезть, т.к. сообщения достаточно большие. Во-вторых, в случае падения легче восстановиться с диска.
Здравствуйте, avostrjakov, Вы писали:
G>>Каковы типичные сценарии применения этой штуковины?
A> В данной таблицы храняться сообщения от одного пользователя другому. Храняться пока не доставяться A>к конечному пользователю, что иногда может быть долгим процессом.
Я не до конца понимаю, что у вас за задача, но у меня есть стойкое ощущение, что вы делаете что-то не так. Очень уж странно как-то получается.
G>>Сколько процессов пишут/читают?
A> Пока это все прототип. Пишет и читает один процесс. В будущем будет много: сотни.
Сколько точно будет процессов? По одному на пользователя, нет? Короче говоря, пока вы задачу не опишете, вряд-ли кто-то сможет вам прокомментировать по сути.
G>>Зачем нужно disk_copies?
A> В память все это может не влезть, т.к. сообщения достаточно большие. Во-вторых, в случае падения легче восстановиться с диска.
Во-первых, вся таблица целиком хранится в памяти даже в случае disc_copies — на диск пишутся только изменения, и последовательно. disc_copies применяется только для восстановления таблицы при старте. "По настоящему" на диске это будет лежать только в случае disc_only. Насчет disc_only надо еще сказать, что одна таблица не может превышать 2GB в любом случае — придется fragmented tables использовать, чтобы это обойти.
Во-вторых, мнезия должна после падения прекрасно восстановится и с другой машины — не понятно, почему с диска восстановится "легче". Она же умеет и так и так, и она железная, ей все равно как восстанавливаться, нет?
Здравствуйте, Курилка, Вы писали:
К>Здравствуйте, avostrjakov, Вы писали:
A>>Здравствуйте, Курилка, Вы писали:
A>>>> Вопрос заключается в том, насколько эффективно так работать с Mnesia? К>>>А сделать тесты и посмотреть не пробовали?
A>> Интересно узнать в принципе применять сортировку при высокой нагрузке можно? К>Можно всё, нужно ли — вот в чём вопрос. К>Ложить в мнезию, а потом пересортировывать мне кажется не очень естественным.
Такой вопрос: mnesia гарантирует, что если я создам несколько записей в таблице и потом выберу их оттуда, то порядок записей сохраниться?
Если да, то сортировка не нужна будет.
К>Я бы скорее держал список сообщений в памяти в виде queue, который можно выкидывать в mnesia, если есть боязнь за сохранность данных (на эти сценарии тоже нужны тесты на мой взгляд).
Ладно, давай так. В пределе эта система должна выдерживать нагрузку в 3 миллиона пользователей, скажем по три сообщения от каждого. Размер каждого сообщения в среднем 100 кб (это графика). А тут сортировка
Queue выдержит? Mnesia выдержит?
A>>Пока не тестировали. К>Имхо тут без тестов выкладывать код в продакшн по меньшей мере не очень профессионально.
Да, ты что Какой продакшен Прототип пишем. Мнезию изучаем пораллельно. Вот вопросы задаю умным людям здесь
К>>>Ну и зачем мнезия-то в принципе нужна, если фактически простой буфер вы организуете?
A>> Нужно чтобы данные не потерялись при сбое одного компьютера в mnesia. Это сообщения пользователей. A>>То есть только в кэше их держать нельзя. К>Как рядом спросил гапертон — а нафига disc_copies? Если речь про сбой одного компьютера, то значит их несколько у вас? ram_copies ведь аналогично реплицируются, только на диск не выгружаются (т.е. выкидываем лишний оверхэд на дисковый I/O)
Здравствуйте, 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>Во-вторых, мнезия должна после падения прекрасно восстановится и с другой машины — не понятно, почему с диска восстановится "легче". Она же умеет и так и так, и она железная, ей все равно как восстанавливаться, нет?
Про восстановление мнезии согласен. Когда я отвечал, то думал, что ты предлагаешь использовать некий кэш в памяти, а не мнезию.
Здравствуйте, avostrjakov, Вы писали:
A> Такой вопрос: mnesia гарантирует, что если я создам несколько записей в таблице и потом выберу их оттуда, то порядок записей сохраниться? A>Если да, то сортировка не нужна будет.
Вопрос в том, зачем тебе перекладывать расходы на сортировку на мнезию, если тебе нужен "естественный" (по мере поступления) порядок сообщений.
Т.е. зачем тебе такие накладные расходы, без которых элементарно можно обойтись?
К>>Я бы скорее держал список сообщений в памяти в виде queue, который можно выкидывать в mnesia, если есть боязнь за сохранность данных (на эти сценарии тоже нужны тесты на мой взгляд).
A> Ладно, давай так. В пределе эта система должна выдерживать нагрузку в 3 миллиона пользователей, скажем по три сообщения от каждого. Размер каждого сообщения в среднем 100 кб (это графика). А тут сортировка A> Queue выдержит? Mnesia выдержит?
По 3 сообщения одновременно? Или в час?
Сформулируй более точно: какова средняя нагрузка и пиковая.
Ну и если queue не выдержит, то мнезия сразу пойдёт лесом, т.к. к памяти у мнезии ещё большие требования.
Если уж совсем элементарно: если в память не влезет, то тебе ничто не поможет
К чему вопрос про сортировку я не понял.
В случае с queue у тебя будут данные гарантированно отсортированы, для мнезии же они будут сортированы если используешь ordered_set, но вставка возможно будет тупить, т.к. никто не ожидает от тебя упорядоченных данных (т.е. будет искаться место в таблице куда будет вставляться строка).
A>>>Пока не тестировали. К>>Имхо тут без тестов выкладывать код в продакшн по меньшей мере не очень профессионально.
A> Да, ты что Какой продакшен Прототип пишем. Мнезию изучаем пораллельно. Вот вопросы задаю умным людям здесь
Дак если прототип, то производительность по-моему первое, что надо мерять, если конечно вам не пофигу как быстро оно будет работать.
Здравствуйте, Курилка, Вы писали:
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>> Да, ты что Какой продакшен Прототип пишем. Мнезию изучаем пораллельно. Вот вопросы задаю умным людям здесь
К>Дак если прототип, то производительность по-моему первое, что надо мерять, если конечно вам не пофигу как быстро оно будет работать.
Будем, как напишем прототип. Пока он еще не закончен.
Здравствуйте, 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. Где конкретно написано — не помню, но пока это так.
Здравствуйте, 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. Где конкретно написано — не помню, но пока это так.
A> Извини, но мы ушли уже далеко от первоначального вопроса. Мне было интересно узнать, насколько вообще возможно применять сортировку в mnesia в случае, когда база находиться на нескольких нодах, кол-во записей в таблице большое (предвидя вопрос, около 4 миллионов записей) и большой нагрузке на базу (возьмем 100 тысяч одновременных запросов в базу, запросы разные, не только к таблице с сообщениями).
Изначально вроде же было всего 10 000
И вопрос первоначальный выглядел иначе...
G>>2Gb — это ограничение на размер таблицы dets, которая применяется mnesia в случае disc_only. Где конкретно написано — не помню, но пока это так.
A> Спасибо, нашел, где написано про это: A>http://www.erlang.org/doc/man/dets.html
Ну не всё так уж совсем грустно, есть варианты (via Mamut )
Здравствуйте, avostrjakov, Вы писали:
A>Здравствуйте, Курилка, Вы писали:
К>>В случае с queue у тебя будут данные гарантированно отсортированы, для мнезии же они будут сортированы если используешь ordered_set, но вставка возможно будет тупить, т.к. никто не ожидает от тебя упорядоченных данных (т.е. будет искаться место в таблице куда будет вставляться строка).
A> Понял. Queue не подойдет, сообщения могут достаточно долгое время лежать в таблице, пока клиент, которому они предназначаются их не попросит. То есть НЕ сервер отправляет сообщения клиенту сам, а клиент запрашивает свои сообщения у сервера.
Смотрю ТЗ как обычно всё меняется и меняется
Предлагаю тогда другой вариант — в queue хранить некую "ключевую" информацию по сообщениям, а сами уже где-нибудь "оффлайн" дабы не засорять рабочее пространство (файлы или мнезия, решения могут быть разные). Ну и можно изобразить что-то типа GC, когда долго лежащие сообщения будут скидываться на диск (например если в течении минуты были невостребованы).
Но это всё мои домыслы, без понимания задачи целиком (e.g. что за запросы и когда появляются) тут трудно что-либо советовать.
Основная мысль у меня всё та же — зачем тебе сортировать если можно не сортировать?
К>>Дак если прототип, то производительность по-моему первое, что надо мерять, если конечно вам не пофигу как быстро оно будет работать.
A> Будем, как напишем прототип. Пока он еще не закончен.
Мой совет — делайте тесты как можно раньше, потом просто на них или забъёте, или окажется что слишком сложно их прикрутить, так и получится невнятный результат в итоге...
Здравствуйте, avostrjakov, Вы писали:
G>>Один процесс на пользователя, пользователи посылают друг другу сообщения. Вопрос: зачем все сообщения хранить в одной таблице? Почему не завести отдельный inbox для каждого пользователя, что мешает? Еще вопрос: что означает "одновременно передаваемых сообщений"? Вы хотели сказать, пользователей у вас в системе 100 тысяч, так?
A> Извини, но мы ушли уже далеко от первоначального вопроса. Мне было интересно узнать, насколько вообще возможно применять сортировку в mnesia в случае, когда база находиться на нескольких нодах, кол-во записей в таблице большое (предвидя вопрос, около 4 миллионов записей) и большой нагрузке на базу (возьмем 100 тысяч одновременных запросов в базу, запросы разные, не только к таблице с сообщениями).
Извини, я думал тебе интересно, как твою задачу правильно на Эрланге решать. А тебе оказывается интересна работа Мнезии в специфическом режиме, неадекватном задаче- над этим я думать не хочу. В чем проблема — меряй свой прототип. Ты ведь именно за этим его и пишешь.