哪个集群NoSQL DB用于消息存储目的?

时间:2012-04-23 18:22:29

标签: erlang nosql cassandra hbase riak

另一个关于NoSQL选择的问题。 但是,我还没有找到有人要求这种目的,消息存储...

我有一个Erlang聊天服务器,我已经使用MySQL存储好友列表,以及“JOIN needed”信息。

我想存储消息(用户因为离线而没有收到消息......)并检索它们。

我已经预先选择了NoSQL,我不能使用像MongoDB这样的东西,因为它是面向RAM的范例,并且无法像其他人一样集群。 我的名单上有3个选项,我猜:

  • HBASE
  • 了Riak
  • 卡桑德拉

我知道他们的模型不同,一个使用键/值,另一个使用SuperColumns和co。

到目前为止,我对Riak有偏好,因为它是Erlang的稳定客户端库。

我知道我可以使用Cassandra和Thrift,但是对于Erlang来说似乎不太稳定(我没有得到很好的回报)

我现在对HBase一无所知,只知道它存在并且基于像Cassandra和Riak这样的Dynamo。

所以这就是我需要做的事情:

  • 为每位注册用户存储1到X条消息。
  • 获取每位用户存储的邮件数量。
  • 一次检索用户的所有邮件。
  • 立即删除用户的所有邮件。
  • 删除所有超过X个月的邮件

现在,我对那些NoSQL DB真的很陌生,我一直都是MySQL爱好者,这就是为什么我问你这个问题,作为一个新手,会有一个比我更有经验的人可以帮我选择哪个一个更好,并且会让我做我想做的一切而不会有太多的麻烦...

谢谢!

3 个答案:

答案 0 :(得分:7)

我不能代表Cassandra或Hbase,但让我谈谈Riak部分。

是的,Riak适用于您的场景(我看到有几家公司和社交网络将其用于类似目的)。

要实现这一点,您需要简单的Riak Key / Value操作,以及某种索引引擎。您的选择(按优先顺序排列):

  1. CRDT设置。如果你的1-N集合大小合理(比方说,每个用户的消息少于50条或者其他),你可以将子集合的密钥存储在CRDT Set Data Type中。

  2. Riak搜索。如果您的集合大小很大,特别是如果您需要在任意字段上搜索对象,则可以使用Riak Search。它在后台旋转Apache Solr,并根据您定义的模式索引对象。它具有非常棒的搜索,聚合和统计,地理空间功能等。

  3. 二级索引。您可以在eLevelDB storage back end之上运行Riak,并启用Secondary Index(2i)功能。

  4. 运行一些性能测试,选择最快的方法。

    就架构而言,我建议使用两个存储桶(用于您描述的设置):用户存储桶和消息存储桶。

    索引消息存储桶。 (通过将搜索索引与其关联,或通过2i存储user_key)。这使您可以执行所有必需的操作(并且消息日志不必适合内存):

    • 为每个注册用户存储1到X条消息 - 创建用户对象并获取用户密钥后,每个用户存储任意数量的消息很容易,它们将直接写入消息桶,每条消息都存储相应的user_key作为辅助索引。
    • 获取每位用户存储的邮件数量 - 没问题。获取属于用户的消息密钥列表(通过搜索查询,通过检索保存密钥的Set对象,或通过user_key上的2i查询)。这使您可以在客户端获得计数。
    • 一次检索用户的所有邮件 - 请参阅上一项。获取属于该用户的所有消息的密钥列表(通过Search,Sets或2i),然后通过多次获取每个密钥的值来获取这些密钥的实际消息(所有官方Riak客户端都有{{1能力,客户端)。
    • 立即删除用户的所有邮件 - 非常相似。获取用户的消息密钥列表,在客户端发出删除消息密钥。
    • 删除所有超过X个月的邮件 - 您可以在日期添加索引。然后,检索所有超过X个月的消息密钥(通过Search或2i),并为它们发出客户端删除。

答案 1 :(得分:0)

我根本不能和Riak说话,但我会质疑你选择丢弃Mongo。只要你关闭了日记功能并且没有完全饿死RAM就可以了。

我对HBase了解很多,听起来很容易满足你的需求。根据您拥有的用户数量,可能会有些过度。它简单地支持诸如为每个用户存储许多消息之类的事情,并具有自动写入过期的功能。根据您构建架构的方式,它可能是原子的,也可能不是原子的,但这对您的用例无关紧要。

缺点是正确设置它需要很多开销。在站立HBase之前,您需要了解Hadoop,运行HDFS,确保您的名称节点可靠等。

答案 2 :(得分:0)

我建议使用像Riak或Couchbase这样的分布式密钥/值存储,并将每个用户序列化的整个消息日志(二进制erlang术语或JSON / BSON)保留为一个值。

因此,对于您的用例,它将如下所示:

  • 每个注册用户从1条消息存储到X条消息 - 当用户联机时,产生一个有状态的 gen_server ,它从存储中获取并在启动时反序列化整个消息日志,收到新的消息,将它们附加到日志的副本,在它终止的会话结束时,序列化更改的日志并将其发送到存储。
  • 获取每个用户存储的邮件数 - 获取注销,反序列化,计数;或者可以将计数存储在一个单独的k / v对中。
  • 立即从用户检索所有邮件 - 只需从存储中提取即可。
  • 立即删除用户的所有邮件 - 只需从存储中删除值。
  • 删除所有超过X个月的邮件 - 获取,过滤,放回。

明显的限制 - 消息日志必须适合内存。

如果您决定单独存储每条消息,那么如果您希望它们按时间顺序排序,则需要从分布式数据库中对它们进行排序,因此处理大于内存的数据集几乎没有帮助。如果需要 - 你最终会得到一些更棘手的方案。