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

时间:2012-10-23 03:59:33

标签: java database key-value key-value-store ssd

我确信:

  • 我在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没有将读/写混合在一起,正如这个问题所示:Low-latency Key-Value Store for SSD

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

感谢。

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

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

1 个答案:

答案 0 :(得分:4)

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

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

fsync()可以在许多操作系统和磁盘硬件上进行非常重量级操作,即使在SSD上也是如此。 (例外情况是由电池或电容器支持的企业级SSD - 他们可以将缓存刷新操作基本上视为无操作,以避免您可能遇到的延迟。)

解决方案是在一个大型交易中进行所有商店。我不知道Berkeley DB,但对于sqlite,性能可以大大提高。

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

<强>更新 如果您完全确定需要耐久性,可以尝试Optimizing Put Performance in Berkeley DB的答案;如果你这样做,你应该查看Berkeley DB的TDS(事务数据存储)功能。