选择MongoDb / CouchDb / RavenDb - 性能和可扩展性建议

时间:2011-03-10 10:29:16

标签: mongodb couchdb ravendb document-database nosql

对于某些读/写密集型应用程序,我们正在研究具有故障转移群集的文档数据库存储解决方案。

我们将平均每秒写入40K并发写入数据库(峰值可能达到70,000) - 并且可能会发生几乎相同数量的读取。

我们还需要一种机制让db通知新写入的记录(db级别的某种触发器)。

在正确选择文档数据库和相关容量规划方面,什么是一个好的选择?

更新

关于期望的更多细节。

  • 平均而言,我们期望在3-4个数据库/文档集合中每秒有40,000(40K)个插入数(新文档)。
  • 峰值可能高达120,000(120K)插入
  • 插件应该可以立即读取 - 几乎是实时的
  • 除此之外,我们预计每秒约有5000次更新或删除
  • 除此之外,我们还希望有500-600个并发查询访问数据。这些查询和执行计划在某种程度上是已知的,但可能需要更新,例如,一周左右更新一次。
  • 系统应支持存储端的故障转移群集

4 个答案:

答案 0 :(得分:8)

如果“20,000并发写入”意味着插入,那么我将使用CouchDB并使用“_changes”api作为触发器。但是有了20.000次写入,你还需要一个稳定的分片。然后你最好看看bigcouch

如果“20.000”并发写入包含“大多数”更新,我肯定会选择MongoDB,因为它的“就地更新”非常棒。但是你应该手动处理触发器,但使用另一个集合来更新一般文档可以是一个方便的解决方案。再次注意分片。

最后,我认为你无法选择只有并发性的数据库,你需要规划api(如何检索数据),然后查看手头的选项。

答案 1 :(得分:6)

我会推荐MongoDB。我的要求并不像你的要求那么高,但它相当接近。假设您将使用C#,我建议使用官方MongoDB C#驱动程序和 InsertBatch 方法,并启用 SafeMode 。它可以像文件系统一样快速地写入数据。一些警告:

  1. MongoDB执行支持触发器(至少我上次检查时)。
  2. MongoDB最初在同步到磁盘之前将数据缓存到RAM。如果您需要具有持久性的实时需求,则可能需要将fsync设置得更低。这将对性能产生重大影响。
  3. C#驱动程序有点不稳定。我不知道它是否仅仅是我,但每当我尝试使用它运行任何长时间运行时,我都会遇到奇怪的错误。 C ++驱动程序比C#驱动程序(或任何其他驱动程序)更好,实际上更快。
  4. 话虽这么说,我也建议调查RavenDB。它支持你正在寻找的一切,但对于我的生活,我无法在Mongo附近的任何地方进行表演。

    接近MongoDB的唯一其他数据库是Riak。只要你有足够的内存来存储密钥空间,它的默认Bitcask后端就会非常快,但我记得它不支持触发器。

答案 2 :(得分:4)

Membase(以及即将发布的Couchbase服务器)将轻松满足您的需求,并提供动态可扩展性(即时添加或删除节点),具有故障转移功能的复制。顶部的memcached缓存层将轻松处理200k ops / sec,您可以使用多个节点线性扩展,以支持将数据持久保存到磁盘。

我们最近有一些基准测试显示极低的延迟(大致相当于高吞吐量):http://10gigabitethernet.typepad.com/network_stack/2011/09/couchbase-goes-faster-with-openonload.html

不知道拥有支持其的工程和QA资源的受支持企业级产品对您来说有多重要,但这也是可用的。

编辑:忘了提到已经有一个内置的触发器接口,我们进一步扩展它以跟踪数据何时到达磁盘(持久)或被复制。

佩里

答案 3 :(得分:2)

  • 我们正在研究一个带有故障转移群集的文档数据库存储解决方案,用于某些读/写密集型应用程序

Riak使用Google的LevelDB后端[这里是来自Google的awesome benchmark],如果有足够的缓存和固态磁盘,速度非常快。根据文档的结构及其大小(您提到2KB),您当然需要对其进行基准测试。 [请记住,如果您能够对数据进行分片(业务方面),则不必在单个节点上保持40K / s的吞吐量]

LevelDB的另一个优点是数据压缩=>存储。如果存储不是问题,您可以禁用压缩,在这种情况下,LevelDB将真正飞行。

带有次要指标的Riak允许您根据自己的喜好记录数据结构=>您只索引那些您关心搜索的字段。

成功且无痛Fail Over是Riak的第二个名字。它真的很棒。

  • 我们还需要一种机制让数据库通知新写入的记录(数据库级别的某种触发器)

你可以依靠Riak中的pre-commitpost-commit hooks来实现这种行为,但同样,在任何触发器中,它都附带价格=>性能/可维护性。

  • 插件应该可以立即读取 - 几乎是实时的

Riak写入磁盘(没有异步MongoDB意外)=> reliably readable马上。如果您需要更好的一致性,可以配置Riak的插入仲裁:例如在将插入视为成功之前应该返回多少节点

一般情况下,如果fault tolerance / concurrency / fail over / scalability对您很重要,我会使用Erlang编写的数据存储,因为Erlang成功多年来解决了这些问题。