SSD上的键/值存储速度极慢

Kai*_*vin 6 java database solid-state-drive key-value key-value-store

我确信:

  • 我正在使用Linux上的Java/Eclipse,并尝试在磁盘上分别存储大量16/32字节的键/值对.密钥是完全随机的,使用SecureRandom生成.
  • 速度恒定在~50000插入/秒,直到达到约100万个条目.
  • 达到此限制后,java进程每隔1-2秒从0%CPU振荡到100%,从150MB内存振荡到400MB,从10插入/秒振荡到100.
  • 我试过Berkeley DB和Kyoto Cabinet以及Btrees和Hashtables.结果相同.

可能有什么贡献:

  • 它是在SSD上写的.
  • 对于每个插入,平均有1.5次读取 - 不断读取和写入.

我怀疑在达到某个缓存/缓冲区限制之前,50000的速率很快.然后,大缓慢可能是由于SSD没有处理混合在一起的读/写,正如这个问题所建议的:SSD的低延迟键值存储.

问题是:
这种极端减速可能来自哪里?它不是所有SSD的故障.很多人乐于使用SSD进行高速数据库处理,我相信它们会混合读写.

谢谢.

编辑:我已确保删除任何内存限制,并且java进程始终有空间分配更多内存.
编辑:删除读数和仅执行插入不会更改问题.

上次编辑:对于记录,对于哈希表,它似乎与初始数字桶有关.在京都内阁,这个数字不能改变,默认为~100万,所以最好在创建时获得数字(存储的最大记录数的1到4倍).对于BDB,它被设计为逐渐增加桶的数量,但由于它是资源消耗,因此更好地预先确定数量.

lxg*_*xgr 4

您的问题可能与您正在使用的数据库的强大持久性保证有关。

基本上,对于任何符合 ACID 的数据库,每次数据库提交至少需要调用一次 fsync() 。必须这样做是为了保证持久性(否则,在系统故障的情况下更新可能会丢失),同时也是为了保证磁盘上数据库的内部一致性。在 fsync() 调用完成之前,数据库 API 不会从插入操作返回。

在许多操作系统和磁盘硬件上,甚至在 SSD 上, fsync() 可能是一个非常重量级的操作。(电池或电容器支持的企业级 SSD 是一个例外 - 它们可以将缓存刷新操作基本上视为无操作,以避免您可能遇到的延迟。)

一种解决方案是在一笔大交易中完成所有商店。我不了解Berkeley DB,但是对于sqlite,这样可以大大提高性能。

要弄清楚这是否是您的问题,您可以尝试使用 strace 观察数据库写入过程并查找频繁的 fsync() 调用(每秒多次调用将是一个非常强烈的提示)。

更新: 如果您绝对确定不需要持久性,您可以尝试Optimizing Put Performance in Berkeley DB中的答案;如果你这样做,你应该研究一下 Berkeley DB 的 TDS(事务数据存储)功能。