selectMongoDb / CouchDb / RavenDb – 性能和可伸缩性的build议
我们正在寻找一种具有故障转移群集function的文档数据库存储解决scheme,用于某些读/写密集型应用程序。
我们将平均每秒钟写入数据库的并发写入(平均每秒高达70,000次),并可能有几乎相似的读取次数。
我们还需要一个db的机制来通知新写入的logging(在db级别的某种触发器)。
在正确select文档数据库和相关的容量规划方面,什么是一个好的select?
更新
关于期望的更多细节。
- 平均而言,我们预计在3-4个数据库/文档集合中,每秒插入(新文档)数量为40,000(40K)。
- 峰值可能高达12万(120K)插入
- Inserts应该是可以立即读取的 – 几乎是实时的
- 与此同时,我们预计每秒大约5000次更新或删除
- 与此同时,我们也期望500-600个并发查询访问数据。 这些查询和执行计划在某种程度上是已知的,尽pipe这可能需要在一周左右更新一次。
- 系统应支持存储端的故障转移群集
如果“20,000并发写入”意味着插入,那么我会去CouchDB和使用“_changes”API触发器。 但有了20.000写入,你将需要一个稳定的分片。 那么你最好看看bigcouch
如果“20.000”并发写入包含“大部分”更新,我肯定会去MongoDB,因为它的“更新到位”是非常棒的。 但是,那么你应该手动处理触发器,但使用另一个集合来更新一个通用文档可以是一个方便的解决scheme。 再次要小心分片。
最后,我认为你不能select一个只有并发的数据库,你需要计划api(你将如何检索数据),然后看看手中的选项。
我会推荐MongoDB。 我的要求并不像你的要求那样高,但相当接近。 假设你将使用C#,我推荐使用正式的MongoDB C#驱动程序和启用了SafeMode的InsertBatch方法。 它会像文件系统一样快速地写入数据。 几点注意事项:
- MongoDB不支持触发器(至less在最后一次检查)。
- 在同步到磁盘之前,MongoDB最初将数据caching到RAM。 如果您需要耐用性的实时需求,则可能需要将fsync设置得更低。 这将会有显着的性能影响。
- C#驱动程序有点不可思议。 我不知道这是否只是我,但每当我尝试运行任何长时间运行的操作时,我会得到奇怪的错误。 C ++驱动程序比C#驱动程序(或任何其他驱动程序)要好得多,实际上要快得多。
话虽如此,我也build议考虑到RavenDB。 它支持你正在寻找的所有东西,但在我的生活中,我无法在靠近Mongo的任何地方执行它。
接近MongoDB的唯一其他数据库是Riak 。 它的默认Bitcask后端是快速的,只要你有足够的内存来存储密钥空间,但我记得它不支持触发器。
Membase(以及即将发布的Couchbase服务器)将轻松处理您的需求,并提供dynamic的可扩展性(即时添加或移除节点),故障转移复制。 顶端的memcachedcaching层将轻松处理200k ops / sec,并且可以通过多个节点线性扩展以支持将数据保存到磁盘。
我们有一些最新的基准testing显示极低的延迟(大致相当于高吞吐量): http : //10gigabitethernet.typepad.com/network_stack/2011/09/couchbase-goes-faster-with-openonload.html
不知道有多less重要的是你有一个支持企业级产品的工程和QA资源,但也可以。
编辑:忘了提及,已经有一个内置的触发器接口,我们正在进一步扩展,以追踪数据何时到达磁盘(持续)或复制。
佩里
- 我们正在寻找一种具有故障转移群集function的文档数据库存储解决scheme,用于某些读/写密集型应用程序
与谷歌的LevelDB后端Riak [这是来自谷歌的一个很棒的基准 ],因为足够的caching和固态硬盘非常快。 根据文档的结构和大小(你提到的2KB),当然你需要进行基准testing。 [请记住,如果您能够分割数据(商业智能),则不必在单个节点上保持40K / s的吞吐量]
LevelDB的另一个优点是数据压缩=>存储。 如果存储不是问题,则可以禁用压缩,在这种情况下,LevelDB将会直接进行压缩。
具有次要标记的Riak允许您按照自己的喜好logging数据结构=>仅索引那些您关心的search字段。
Riak的第二个名字是成功而无痛的Fail Over
。 这真的在这里闪耀。
- 我们还需要一个db的机制来通知新写入的logging(在db级别的某种触发器)
你可以依靠Riak中的pre-commit
和post-commit hooks
来实现这种行为,但是同样,任何触发器都会带有price =>性能/可维护性。
- Inserts应该是可以立即读取的 – 几乎是实时的
Riak写入磁盘(没有asynchronous的MongoDB意外)=> reliably readable
。 如果您需要更好的一致性,您可以configurationRiak的法定人数插入:例如,在插入被视为成功之前应该返回多less节点
一般来说,如果fault tolerance
/ concurrency
/ fail over
/ scalability
对您来说很重要,那么我将使用用Erlang编写的数据存储,因为Erlang已经成功地解决了这些问题很多年了。