在BerkleyDB JE中使用游标时,我发现遍历数据集会产生大量的随机读取IO。发生这种情况是因为BDB按主键升序遍历数据集。
在我的应用程序中,我没有任何按顺序处理数据集的要求(从数学上讲,我的操作是可交换的),并且我对最大化吞吐量感兴趣。
有没有办法用游标按存储顺序而不是按主键顺序处理数据集。
我猜不是;BDBJE 是一个日志结构化的数据库 - 即,所有写入都附加到日志的末尾。这意味着记录始终附加到最后一个日志,并且可能取代先前日志中的记录。由于 BDBJE 在设计上无法写入旧日志,因此它无法将旧记录标记为被取代,因此您无法继续浏览存储处理记录,因为您不知道该记录是否是最新的,而无需处理日志中后面的记录。
BDBJE 将通过将实时记录转发到新日志中并删除旧文件来清理旧日志,因为它们的"实时"记录计数减少,这会进一步打乱排序。
我发现京都文件柜的 Java 绑定在原始插入性能方面比 BDB 更快,并且您可以选择存储格式,这可以让您优化游标顺序记录遍历性能。许可证是类似的(京都内阁是GPL3,BDB是Oracle BDB许可证(copyleft)),除非你在这两种情况下支付商业许可证。
更新:从版本 5.0.34 开始,BDBJE 包括 DiskOrderedCursor 类,该类解决了所需的用例 - 它遍历日志序列中的记录,在未碎片化的日志文件中应与磁盘顺序相同。
有新的"批量访问"接口可用,允许使用Db#get()
或Dbc#get()
方法之一与DB_MULTIPLE
标志一起使用将多个可能连续的记录读入缓冲区。
该文档适用于 4.2.52 版,我在 Oracle 网站上查找 com.sleepycat.db
包的文档时遇到了一些麻烦。在这里,我找到了 4.8.30 版的文档,但那里没有提到类 Db
和 Dbc
。
啊,类MultipleEntry
和MultipleDataEntry
看起来是有希望的等价物,与使用上面的DB_MULTIPLE
。这个想法是,当您使用适当大小的缓冲区MultipleDataEntry
获取数据时,您将一起返回一大堆记录,然后可以使用MultipleDataEntry#next()
将这些记录分开。
我的印象是界面的这一部分一直在变化。由于我的项目中没有足够新的库版本,因此我不能声称已经使用了这些批量获取接口。如果您能够调查它们的使用情况,请报告。