BerkeleyDB写出性能问题

时间:2011-03-24 17:52:24

标签: java performance berkeley-db key-value

我需要一个基于磁盘的键值存储,它可以维持大数据集的高写入和读取性能。很高,我知道。

我正在尝试使用Java的C BerkeleyDB(5.1.25)库,我看到了严重的性能问题。

我在短时间内获得了稳定的14K docs / s,但是当我达到几十万个文档时,性能会像摇滚一样下降,然后它会恢复一段时间,然后再次下降,等等。更常见的是,在大多数情况下,我无法获得超过60个docs / s,并且在1000万个docs之后有一些12K docs / s的孤立峰值。我的db类型选择是HASH,但我也试过BTREE,它是一样的。

我尝试使用10 db的池并在其中散列文档以消除性能下降;这使写入吞吐量增加到50K docs / s,但对性能下降没有帮助:所有10 db都同时减慢了爬行速度。

我假设文件正在重组,我试图找到一个影响何时进行重组的配置参数,因此每个池化的db会在不同的时间重新组织,但我找不到任何有效的东西。我尝试了不同的缓存大小,使用setHashNumElements配置选项保留空间,这样就不会花时间增长文件,但每次调整都会让它变得更糟。

我准备给berkeleydb并尝试更复杂的解决方案,比如cassandra,但我想确保在写下来之前我没有在berkeleydb做错事。

此处有人在berkeleydb获得持续写作表现的经验吗?

修改1

我已经尝试了几件事:

  1. 将写入速率降低到500 / s(低于我在15个小时写入3000万个文档后得到的平均值,这表明硬件能够写入550个文档/秒)。没有用:一旦写了一定数量的文档,性能就会下降。
  2. 将传入的项目写入队列。这有两个问题:A)它破坏了释放r​​am的目的。 B)队列最终会阻塞,因为BerkeleyDB冻结的时间越长越频繁。
  3. 换句话说,即使我限制传入数据保持低于硬件功能并使用ram来保存项目,而BerkeleyDB需要一些时间来适应增长,因为这个时间越来越长,性能接近0。

    这令我感到惊讶,因为我已经看到声称它可以处理数TB的数据,但我的测试显示不然。我仍然希望我做错了...

    编辑2

    在给予它更多的思考和Peter的输入之后,我现在明白随着文件变大,一批写入将会分散得更远,并且它们落入相同磁盘柱的可能性会下降,直到最终达到磁盘的搜索/第二限制。

    但是BerkeleyDB的定期文件重组比这更早地杀死了性能,并且以更糟糕的方式:它只是停止响应更长和更长的时间,同时它会改变周围的东西。使用速度更快的磁盘或在不同磁盘之间传播数据库文件无济于事。我需要找到解决这些吞吐量漏洞的方法。

5 个答案:

答案 0 :(得分:2)

我所看到的高磁盘写入速率是系统缓存将填满(在此点之前提供闪电性能)但是一旦它填满应用程序,即使整个系统也会大幅减速,甚至停止。

您的底层物理磁盘应至少每秒支持100次写入。除此之外,更清晰的缓存支持幻觉。 ;)但是,当缓存系统耗尽时,您会看到非常糟糕的行为。

我建议您考虑使用磁盘控制器缓存。其电池备份内存需要与您的数据大小相当。

另一种选择是使用SSD驱动器,如果更新是突发性的(它们可以每秒10K +写入,因为它们没有移动部件)和缓存,这应该比你需要的多,但是SSD的写入次数有限

答案 1 :(得分:1)

除非您手动调用压缩实用程序,否则BerkeleyDB不会执行文件重组。导致经济放缓的原因有几个:

  1. 以随机访问方式写入密钥,这会导致更高的磁盘I / O负载。
  2. 默认情况下写入是持久的,这会强制进行大量额外的磁盘刷新。
  3. 正在使用事务环境,在这种情况下,检查点在刷新磁盘更改时会导致速度变慢。
  4. 当你说“文档”时,你的意思是说你使用BDB来存储大于几千字节的记录吗? BDB溢出页面有更多开销,因此您应该考虑使用更大的页面大小。

答案 2 :(得分:1)

我们在工作中使用了BerkeleyDB(BDB)并且看起来有类似的性能趋势。 BerkeleyDB使用Btree来存储其键/值对。当条目数量不断增加时,树的深度会增加。 BerkeleyDB缓存可以将树加载到RAM中,因此树遍历不会导致文件IO(从磁盘读取)。

答案 3 :(得分:1)

这是一个老问题,问题可能已经消失,但我最近遇到了类似的问题(插入速度在数十万条记录之后急剧下降)并且它们通过向数据库提供更多缓存来解决(DB-> set_cachesize)。使用2GB的缓存,插入速度非常好,并且或多或少地保持高达1000万条记录(我没有进一步测试)。

答案 4 :(得分:0)

  

我需要一个基于磁盘的键值存储,可以维持大数据集的高写入和读取性能。

Chronicle Map是此任务的现代解决方案。它在读取和写入方面比BerkeleyDB much faster,并且在来自多个线程/进程的并发访问方面更具可伸缩性。