【发布时间】:2011-07-22 08:30:57
【问题描述】:
我需要一个基于磁盘的键值对存储,它可以为大型数据集维持高写入和读取性能。我知道,要求很高。
我正在尝试来自 java 的 C BerkeleyDB (5.1.25) 库,但遇到了严重的性能问题。
我在短时间内获得了稳定的 14K 文档/秒,但是一旦我达到几十万个文档,性能就会像石头一样下降,然后恢复一段时间,然后再次下降,等等。这种情况越来越多,而且更频繁地,在大多数情况下,在 1000 万个文档之后,我无法获得超过 60 个文档/秒的几个孤立峰值 12K 文档/秒。我选择的数据库类型是 HASH,但我也尝试过 BTREE,它是一样的。
我尝试使用 10 个 db 的池并在其中散列文档以消除性能下降;这将写入吞吐量提高到 50K docs/s,但对性能下降没有帮助:所有 10 db 同时减速到爬行。
我认为文件正在被重组,我试图找到一个影响重组发生时间的配置参数,因此每个池化数据库都会在不同的时间重组,但我找不到任何有用的东西.我尝试了不同的缓存大小,使用 setHashNumElements 配置选项保留空间,这样它就不会花时间增长文件,但每次调整都让它变得更糟。
我即将放弃 berkeleydb 并尝试更复杂的解决方案,例如 cassandra,但我想确保在 berkeleydb 注销之前我没有做错什么。
这里有人有使用 berkeleydb 实现持续写入性能的经验吗?
编辑 1:
我已经尝试了几件事:
- 将写入速度降低到 500/s(低于我在 15 小时内写入 3000 万个文档后得到的平均值,这表明硬件能够写入 550 个文档/秒)。不起作用:一旦编写了一定数量的文档,性能就会下降。
- 将传入项目写入队列。这有两个问题:A)它破坏了释放内存的目的。 B) 队列最终会阻塞,因为 BerkeleyDB 冻结的时间越来越长且越来越频繁。
换句话说,即使我限制传入数据以保持低于硬件能力并使用 ram 来保存项目,而 BerkeleyDB 需要一些时间来适应增长,随着时间越来越长,性能接近 0。
这让我感到惊讶,因为我已经看到声称它可以处理 TB 的数据,但我的测试表明并非如此。我仍然希望我做错了什么......
编辑 2:
经过深思熟虑并根据 Peter 的意见,我现在了解到,随着文件变大,一批写入将分散得更远,并且它们落入同一个磁盘柱面的可能性会下降,直到最终达到磁盘的搜索次数/秒限制。
但是,BerkeleyDB 的定期文件重组比这更早地扼杀了性能,而且以更糟糕的方式:它只是停止响应的时间越来越长,同时它随机播放数据。使用更快的磁盘或将数据库文件分布在不同的磁盘之间并没有帮助。我需要找到解决这些吞吐量漏洞的方法。
【问题讨论】:
标签: java performance berkeley-db key-value