Kyoto Cabinet / Berkeley DB:哈希表的大小限制

时间:2012-10-24 17:48:56

标签: java database nosql hashmap berkeley-db

我很难在我的SSD上存储数以亿计的16/32字节的键/值对和哈希数组。

使用Kyoto Cabinet :当它工作正常时,它以70000记录/秒的速度插入。一旦下降,它就会下降到10-500记录/秒。使用默认设置,在大约一百万条记录之后发生丢弃。查看文档,这是数组中默认的桶数,因此它是有意义的。我将这个数字增加到了2500万,事实上,它可以正常工作,直到大约2500万条记录。问题是,只要我将桶数推到3000万或以上,插入速率就会从一开始就降低到10-500条记录/秒。 Kyoto Cabinet不是为了在创建数据库后增加存储桶数量而设计的,因此我无法插入超过2500万条记录。

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

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

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

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

THX。

1 个答案:

答案 0 :(得分:3)

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

经过努力,我仍然没有解决京都议会和伯克利数据库的问题。然而,我想出了一个使用京都内阁的有趣解决方法。

我注意到我不能在一个KC文件上写超过25M的记录,但是读取没有这样的限制 - 无论数据库的大小如何,它总是很快。我找到的解决方案是为每25M新记录创建一个新的KC文件(一个新的数据库)。这样,读取就发生在许多KC文件上并且仍然很快,并且写入仅在最后创建的文件上发生并且也很快。唯一剩下的问题是允许更新/删除以前文件中的记录。为此,我复制了SSTables方法,即:

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

注意:

  • 与SSTables一样,如果执行了大量更新/删除,我们可能希望执行压缩。但是与SSTables相反,压缩不需要重写文件。过时的记录只是从KC文件中删除,如果KC文件非常小,可以将其删除 - 重新插入文件N中的记录或重新打开以进行新的插入 - 提供下一个文件是紧凑的。
  • 删除不会删除记录,但会写一个特殊值,将记录标识为已删除。在压缩过程中,删除的记录将被删除。
  • 检查是否存在记录通常需要查看数据库。由于布隆过滤器,大多数否定答案都可以在没有任何磁盘访问的情况下给出。