java - 京都内阁/伯克利 DB : Hash table size limitations

标签 java database nosql hashmap berkeley-db

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

With 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/什么会导致 BDB 的插入率在插入 1-2 百万次后下降?

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

谢谢。

最佳答案

下面是我如何在 KC 遇到写入限制的情况下设法存储数十亿条记录。

我费了好大劲,还是没有解决Kyoto Cabinet和Berkeley DB的问题。不过,我想出了一个使用 Kyoto Cabinet 的有趣解决方法。

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

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

注释:

  • 就像 SSTables 一样,如果执行大量更新/删除,我们可能需要执行压缩。然而与 SSTables 相反,这里的压缩不需要重写文件。过时的记录只是从 KC 文件中删除,如果 KC 文件变得非常小,它可以被删除——重新插入文件 N 中的记录——或者重新打开以进行新的插入——前提是下一个文件是紧凑的。
  • 删除不会删除记录,而是写入一个特殊值来标识记录已删除。在压缩过程中,删除的记录会被真正删除。
  • 检查记录是否存在通常需要查看数据库。多亏了布隆过滤器,大多数否定答案都可以在没有任何磁盘访问权限的情况下给出。

关于java - 京都内阁/伯克利 DB : Hash table size limitations,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13054852/

相关文章:

amazon-web-services - Cassandra 2021 目前建议的最大存储空间是多少?

java - 我可以在 iPhone 上练习 Java 编程吗?

java - 什么是 Eclipse SR1 包?

java - 覆盖另一个项目中的 Java 类

sql - 如果引用了 customer 表,我如何将数据插入到 cars 表中?

c# - 我们如何从 getschemaTable 中获取列大小和数据类型?

database - 没有非规范化的 NOSQL 设计?

java - 无法通过Java连接到Hbase

java - 在系统之间迁移大数据

MongoDB - 物化 View /OLAP 样式聚合和性能