2012-10-24 25 views
7

我很难在我的SSD上存储数十亿个带有散列阵列的16/32bytes的键/值对。京都内阁/伯克利DB:散列表大小限制

与京都内阁:当它工作正常,它插入在70000记录/秒。一旦下降,它将下降到10-500记录/秒。使用默认设置后,下降发生在大约一百万条记录之后。查看文档,这是数组中的存储区的默认数量,因此它是有道理的。我把这个数字增加到了25百万,实际上,它可以正常工作,直到大约2500万条记录。问题是,只要我把桶的数量推到3千万或以上,插入速率从一开始就下降到10-500记录/秒。京都内阁的目的不是为了增加数据库创建后的存储桶数量,所以我不能插入超过25万条记录。

1/一旦桶号超过25M,为什么KC的插入率会非常低?

与伯克利DB:我得到的最佳速度略低于KC,接近50000记录/秒,但仍然可以。使用默认设置,就像KC一样,速度在大约一百万条记录后突然下降。我知道BDB旨在逐步扩展桶的数量。无论如何,它试图增加初始数量,使用HashNumElements和FillFactor,但是这些尝试中的任何一个都使情况变得最糟糕。所以我仍然无法在DBD中插入1-2百万条记录。我尝试激活非同步事务,尝试不同的检查点,增加缓存。没有什么改善了下拉。

2/什么可能导致BDB插入率在1-2百万次插入后下降?

注:我用java工作,当转速下降时,CPU占用率,而在正确的速度工作时,在100%降低到0-30%。
注意:停止进程并恢复插入不会改变任何内容。所以我不认为这与内存限制或垃圾收集有关。

Thx。

+0

你的BDB环境是什么样的?你在使用交易,复制等吗?另外,你可以发布一些示例代码? –

+0

目前的状态是:[pastebin.com/bWJpbipZ](http://pastebin.com/bWJpbipZ)。我使用'database.put(transaction,k,v)'插入',使用'database.get(transaction,k,v,LockMode.DEFAULT)'读取,每隔500000个插入使用'environment.checkpoint(null)'插入。 –

回答

3

以下是我如何设法存储数十亿条记录,尽管KC遇到了写入限制。

我付出了很多努力,对于京都议会和柏克莱DB都没有解决过这个问题。不过,我使用京都内阁提出了一个有趣的解决方法。

我注意到我在一个KC文件上写不到25M以上的记录,但读取没有这样的限制 - 无论数据库的大小如何,它总是很快。我找到的解决方案是为每25M新记录创建一个新的KC文件(新数据库)。这种方式在许多KC文件上进行读取,并且速度仍然很快,写入只发生在最后创建的文件上,并且速度也很快。剩下的问题是允许更新/删除以前文件上的记录。对于这一点,我复制SSTables接近,那就是:

  • 所有的0到N-1文件是只读的,文件N读+写。
  • 任何插入/更新/删除都写入文件N.
  • 读取文件N到0,并返回第一次看到/最后一次写入的插入/更新/删除。
  • Bloom Filter附加到每个文件以避免访问没有所需记录的文件。
  • 只要文件N达到25M记录,它就变为只读并创建文件N + 1。

注:

  • 就像使用SSTables,如果大量的更新/进行删除,我们可能要进行压缩。然而,与SSTables相反,这里的压缩并不需要重写文件。过期的记录只是从KC文件中删除,如果KC文件变得非常小,则可以删除它 - 可以删除文件N-中的记录插入或重新打开新的插入记录 - 提供下一个文件紧凑。
  • 删除操作不会删除该记录,而是会写入一个特殊值来标识该记录已删除。在压缩过程中,删除的记录将被删除。
  • 检查记录是否存在通常需要查看数据库。感谢bloom过滤器,大多数负面答案都可以在没有任何磁盘访问的情况下给出。