使用NoSQL数据库为JSON数据提供高效且可扩展的存储

时间:2011-08-18 15:02:56

标签: json mongodb hadoop couchdb cassandra

我们正在开发一个项目,该项目应收集日记和审计数据,并将其存储在数据存储区中,以便进行存档和查看。我们不太确定哪个数据存储区对我们有用。

  • 我们需要存储小的JSON文档,大约150个字节,例如"audit:{timestamp: '86346512',host':'foo',username:'bar',task:'foo',result:0}""journal:{timestamp:'86346512',host':'foo',terminalid:1,type='bar',rc=0}"
  • 我们预计每天大约有一百万个条目,大约150 MB的数据
  • 数据将被存储和读取,但从未被修改
  • 数据应以有效的方式存储,例如Apache Avro使用的二进制格式
  • 保留时间数据可能会被删除
  • 自定义查询,例如'get audit for user and time period''get journal for terminalid and time period'
  • 为故障安全复制数据库
  • 可扩展

目前我们正在评估NoSQL数据库,如Hadoop / Hbase,CouchDB,MongoDB和Cassandra。这些数据库对我们来说是正确的数据库吗?哪个最适合? 有更好的选择吗?

4 个答案:

答案 0 :(得分:11)

  • 每天100万次插入约10次插入/秒。大多数数据库都可以解决这个问题,远低于我们从Cassandra在合理硬件上获得的最大插入速率(50k插入/秒)

  • 您的要求“在保留时间数据可能被删除后”很适合Cassandra的列TTL - 当您插入数据时,您可以指定保留多长时间,然后后台合并进程将在数据到达时删除超时。

  • “数据应以有效的方式存储,例如Apache Avro使用的二进制格式” - Cassandra(与许多其他NOSQL存储一样)将值视为不透明的字节序列,因此您可以根据自己的喜好对值进行编码。您还可以考虑将值分解为一系列列,这样您就可以进行更复杂的查询。

  • 自定义查询,例如“获取用户和时间段的审核” - 在Cassandra中,您可以通过将行键设置为用户ID并将列键设置为事件的时间来对此进行建模(大多数可能是一个timeuuid)。然后,您将使用get_slice调用(或更好的CQL)来满足此查询

  • 或'获取terminalid和time period' - 如上所述,将行键设为terminalid,列键为时间戳。需要注意的一点是,在Cassandra中(与许多无连接存储一样),通常会多次插入数据(以不同的方式排列)以针对不同的查询进行优化。

  • Cassandra有一个非常复杂的复制模型,您可以在其中为每个操作指定不同的一致性级别。 Cassandra也是一个非常可扩展的系统,没有单点故障或瓶颈。这实际上是Cassandra和MongoDB或HBase之类的主要区别(不是我想要开火!)

说完所有这些后,您可以通过更传统的数据库和简单的主从复制轻松满足您的要求,这里的任何内容都不会太繁重

答案 1 :(得分:4)

Avro支持模式演变,非常适合此类问题。

如果您的系统不需要低延迟数据加载,请考虑将数据接收到可靠文件系统中的文件,而不是直接加载到实时数据库系统。保持可靠的文件系统(例如HDFS)运行比实时数据库系统更简单并且不太可能发生中断。此外,分离职责可确保您的查询流量不会影响数据收集系统。

如果您只需要运行少量查询,则可以将文件保留为原始格式并编写自定义地图以生成所需的报告。如果需要更高级别的接口,请考虑在本机数据文件上运行Hive。 Hive将允许您对原始数据文件运行任意友好的类SQL查询。或者,由于您每天只有150MB,您可以将其批量加载到MySQL只读压缩表中。

如果由于某种原因你需要交互式系统的复杂性,HBase或Cassandra或者可能是合适的,但要注意你将花费大量时间玩“DBA”,150MB /天是如此之少的数据你可能不需要复杂性。

答案 2 :(得分:2)

我们正在使用Hadoop / HBase,我看过Cassandra,他们通常使用行键作为最快检索数据的方法,当然(至少在HBase中)你仍然可以申请它过滤列数据,或者做客户端。例如,在HBase中,您可以说“给我所有从key1开始的行,但不包括key2”。

因此,如果您正确设计了密钥,则可以为1个用户,1个主机或1个主机上的1个用户或类似的东西获取所有内容。但是,它需要一个设计合理的密钥。如果您的大多数查询都需要使用时间戳运行,则可以将其作为密钥的一部分包含在内。例如。

您需要多久查询一次数据/写入数据?如果你希望运行你的报告,如果它需要10,15或更多分钟(可能),但你做了很多小写,那么HBase w / Hadoop做MapReduce(或使用Hive或Pig作为更高级别的查询)语言)可以很好地工作。

答案 3 :(得分:1)

如果您的JSON数据具有可变字段,那么像Cassandra这样的无模式模型可以很好地满足您的需求。我将数据扩展为列,而不是以二进制格式存储,这将使查询更容易。使用给定的数据速率,填充1 TB磁盘需要20年,所以我不担心压缩。

对于您提供的示例,您可以创建两个列系列,Audit和Journal。行键是TimeUUID(即时间戳+ MAC地址,将它们变成唯一键)。然后,您提供的审核行将包含四列host:'foo'username:'bar'task:'foo'result:0。其他行可能有不同的列。

对行键进行范围扫描将允许您在一段时间内有效查询(假设您使用ByteOrderedPartitioner)。然后,您可以使用二级索引来查询用户和终端。