Какая кластерная база данных NoSQL для хранения сообщений?

Еще один вопрос, какой выбрать NoSQL. Однако я еще не нашел кого-то, кто просил бы о такой цели, хранении сообщений ...

У меня есть чат-сервер на Erlang, я уже использую MySQL для хранения списка друзей и информации "JOIN required".

Я хотел бы сохранить сообщения (этот пользователь не получил, потому что он был в автономном режиме ...) и получить их.

Я сделал предварительный выбор NoSQL, я не могу использовать такие вещи, как MongoDB, из-за его парадигмы, ориентированной на оперативную память, и не могу кластеризоваться, как другие. Я сократил свой список до трех вариантов, я думаю:

  • Hbase
  • Риак
  • Кассандра

Я знаю, что их модели совершенно разные: одна использует ключ / значение, другая - SuperColumns и т. Д.

До сих пор я предпочитал Riak из-за его стабильной клиентской библиотеки для Erlang.

Я знаю, что могу использовать Cassandra с Thrift, но это не очень стабильно с Erlang (у меня нет хороших результатов по этому поводу)

Я действительно ничего не знаю о HBase прямо сейчас, просто знаю, что он существует и основан на Dynamo, как Cassandra и Riak.

Итак, вот что мне нужно сделать:

  • Хранить от 1 до X сообщений на одного зарегистрированного пользователя.
  • Получите количество сохраненных сообщений на пользователя.
  • получать сразу все сообщения от пользователя.
  • удалить сразу все сообщения от пользователя.
  • удалить все сообщения старше X месяцев

Прямо сейчас я действительно новичок в этих NoSQL DB, я всегда был поклонником MySQL. Вот почему я задаю вам этот вопрос, как новичок, может ли кто-нибудь, у кого больше опыта, чем у меня, помочь мне выбрать, какой из них лучше , и позволил бы мне делать все, что я хочу, без особых хлопот ...

Спасибо !


person TheSquad    schedule 23.04.2012    source источник
comment
@BrianRoach: Похоже, они так не думают по этому вопросу stackoverflow.com/questions/2892729/mongodb-vs-cassandra это тот же вопрос.   -  person TheSquad    schedule 23.04.2012
comment
тот факт, что один вопрос не был отклонен и закрыт, как должно было быть, не влияет на тот факт, что ... он не подходит согласно FAQ и мета. Кроме того, это было 2 года назад - с тех пор все изменилось с добавлением других сайтов.   -  person Brian Roach    schedule 24.04.2012


Ответы (3)


Я не могу говорить от имени Кассандры или Hbase, но позвольте мне коснуться части Riak.

Да, Riak подойдет для вашего сценария (и я видел, как несколько компаний и социальных сетей использовали его для аналогичных целей).

Чтобы реализовать это, вам потребуются простые операции Riak Key / Value, а также какой-то механизм индексации. Ваши варианты (в приблизительном порядке предпочтений):

  1. Наборы CRDT. Если размер вашей коллекции 1-N имеет разумный размер (скажем, на пользователя меньше 50 сообщений или что-то еще), вы можете сохранить ключи дочерней коллекции в CRDT Set Data Type.

  2. Поиск Riak. Если размер вашей коллекции большой, и особенно если вам нужно искать объекты в произвольных полях, вы можете использовать Riak Search. Он запускает Apache Solr в фоновом режиме и индексирует ваши объекты в соответствии с определенной вами схемой. У него отличный поиск, агрегирование и статистика, геопространственные возможности и т. Д.

  3. Вторичные индексы. Вы можете запустить Riak поверх Серверная часть хранилища eLevelDB и включите Вторичный индекс (2i) функциональность.

Выполните несколько тестов производительности, чтобы выбрать самый быстрый подход.

Что касается схемы, я бы рекомендовал использовать два сегмента (для описываемой вами настройки): сегмент пользователя и сегмент сообщений.

Индексируйте корзину сообщений. (Либо связав с ним поисковый индекс, либо сохранив user_key через 2i). Это позволяет вам выполнять все необходимые операции (при этом журнал сообщений не должен умещаться в памяти):

  • Хранить от 1 до X сообщений для каждого зарегистрированного пользователя. После создания объекта User и получения ключа пользователя сохранить произвольное количество сообщений для каждого пользователя будет легко, они будут напрямую записываться в корзину сообщений. , каждое сообщение хранит соответствующий user_key в качестве вторичного индекса.
  • Получите количество сохраненных сообщений на пользователя - нет проблем. Получите список ключей сообщений, принадлежащих пользователю (с помощью поискового запроса, путем получения объекта Set, в котором вы храните ключи, или с помощью запроса 2i для user_key). Это позволяет получить счет на стороне клиента.
  • получить сразу все сообщения от пользователя - см. предыдущий элемент. Получите список ключей всех сообщений, принадлежащих пользователю (с помощью поиска, наборов или 2i), а затем получите фактические сообщения для этих ключей путем множественной выборки значений для каждого ключа (все официальные клиенты Riak имеют возможность multiFetch, сторона клиента).
  • удалить сразу все сообщения пользователя - очень похоже. Получить список ключей сообщений для пользователя, выдать им удаления на стороне клиента.
  • удалить все сообщения старше X месяцев - вы можете добавить индекс по дате. Затем получите все ключи сообщений старше X месяцев (с помощью поиска или 2i) и выполните для них удаления на стороне клиента.
person Dmitri Zagidulin    schedule 21.10.2012
comment
Забавные вещи в жизни ... Через 3 года после того, как я задаю этот вопрос, я начинаю другой проект, и мне нужно было ответить на несколько вопросов. Скорее всего, вы им ответили! Итак, 3 года спустя, подтвержденный вопрос и +1 за видение будущего ;-) - person TheSquad; 02.11.2015
comment
Я отредактировал ответ, чтобы учесть пару новых функций Riak, которые появились с тех пор, в частности, поиск и типы данных. - person Dmitri Zagidulin; 03.11.2015
comment
Спасибо за редактирование ответа на сегодняшние функции. Да, я собирался проверить Riak Search. Solr - это здорово, если вы знаете, как его использовать. - person TheSquad; 03.11.2015

Я вообще не могу разговаривать с Риаком, но сомневаюсь, что ты выбрал Монго. Это неплохо, если вы оставите журналирование выключенным и не будете полностью лишать его оперативной памяти.

Я довольно много знаю о HBase, и похоже, что он легко удовлетворит ваши потребности. Может быть слишком много, в зависимости от того, сколько у вас пользователей. Он тривиально поддерживает такие вещи, как хранение большого количества сообщений для каждого пользователя, и имеет функцию автоматического истечения срока записи. В зависимости от того, как вы создаете свою схему, она может быть или не быть атомарной, но это не имеет значения для вашего варианта использования.

Недостатком является то, что для его правильной настройки требуется много накладных расходов. Вам нужно знать Hadoop, запустить HDFS, убедиться, что ваш namenode надежен, и т. Д., Прежде чем устанавливать HBase.

person Chris Shain    schedule 23.04.2012
comment
Я предполагаю, что MongoDB также будет хорошим выбором, но я действительно хотел бы иметь модель, основанную на Dynamo (без единой точки отказа), AFAIK MongoDB не основан на этом, но я могу ошибаться, правда? Что для вас недостаток в Кассандре? - person TheSquad; 23.04.2012
comment
Моя идея не останавливается, говоря об отказе от MongoDB, но прямо сейчас я действительно не был убежден, что это лучшее решение для кластеризованной БД ... кажется, что 3, которые я выбрал на данный момент, лучше всего подходят по этому основному пункту , Тебе не кажется? - person TheSquad; 23.04.2012
comment
При сегментировании и репликации каждого мангала Mongo не имеет SPOF. HBase делает - HDFS NameNode. Я недостаточно знаю о Cassandra, чтобы много говорить, кроме того, что у нее нет SPOF и она очень похожа по возможностям на HBase. - person Chris Shain; 23.04.2012

Я бы рекомендовал использовать распределенное хранилище ключей / значений, такое как Riak или Couchbase, и сохранять весь журнал сообщений для каждого пользователя, сериализованный (в двоичные термины Erlang или JSON / BSON) как одно значение.

Итак, с вашими вариантами использования это будет выглядеть так:

  • Хранить от 1 до X сообщений для каждого зарегистрированного пользователя - когда пользователь выходит в сеть, создается gen_server с отслеживанием состояния, который получает из хранилища и десериализует весь журнал сообщений при запуске, получает новые сообщения, добавляет их в свою копию журнала, в конце сеанса он завершается, сериализует измененный журнал и отправляет его в хранилище.
  • Получить количество сохраненных сообщений на пользователя - выйти из системы, десериализовать, подсчитать; или, может быть, хранить счетчик рядом в отдельной паре k / v.
  • получить все сообщения от пользователя сразу - просто вытащите его из хранилища.
  • удалить сразу все сообщения от пользователя - просто удалите значение из хранилища.
  • удалить все сообщения старше X месяцев - получить, отфильтровать, вернуть.

Очевидное ограничение - журнал сообщений должен умещаться в памяти.

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

person Ivan Blinkov    schedule 25.04.2012
comment
К сожалению, журнал сообщений имеет отличный шанс не уместиться в памяти ... Вот почему я, вероятно, собираюсь использовать Cassandra, база данных, ориентированная на столбцы, выглядит многообещающей, и если она работает для твитов Twitter, она будет работать и для меня ... (который может больше, может меньше ;-) - person TheSquad; 26.04.2012
comment
Вы также можете разделить журнал сообщений на страницы, где одна страница хранится как одно значение. У меня нет личного опыта в этом, но это описано в этом выступлении Voxer: vimeo.com/52827773 - person Joe Rideout; 03.04.2014