使用LMDB的内存数据库

4
我有一个项目,使用BerkelyDB作为高达数亿小记录的键值存储。所有的值都被插入到数据库中,然后使用单个线程进行顺序和随机访问迭代。
使用BerkeleyDB,我可以创建“永不打算在磁盘上保留”的内存数据库。如果数据库足够小以适应BerkeleyDB缓存,则永远不会写入磁盘。如果它比缓存大,则会创建一个临时文件来保存溢出。这个选项可以显著加速,因为它防止我的应用程序在关闭数据库时将几GB的死数据写入磁盘。
我发现即使在SSD上,BerkeleyDB的写入性能也太差了,所以我想转换到LMDB。但是,根据文档,似乎没有创建非持久数据库的选项。
如果我完全不关心持久性或并发访问,想要 LMDB 的最佳性能配置/组合是什么?即使它像一个“内存数据库”一样,具有临时备份磁盘存储的功能?
2个回答

2
只需使用MDB_NOSYNC,不要自己调用mdb_env_sync()。您还可以添加MDB_WRITEMAP选项。操作系统最终仍会将脏页刷新到磁盘上;您可以通过更改/proc/sys/vm/dirty_ratio等参数来控制该行为。

我认为这仍会导致在数据库关闭时将所有内容写入磁盘?对于完全在内存中的数据库,这会显著减慢整个操作。 - Jeremy Salwen
胡说八道。关闭文件并不会刷新文件。如果在操作系统刷新之前关闭和删除文件,则什么也不会被写入。 - hyc
仅出于完整性考虑,您在 Linux 中大多数(如果不是全部)情况下都是正确的。 但这并非一定适用于其他操作系统,甚至不适用于所有文件系统。 在 Mac OS X 中,在某些情况下有证据表明close()会阻塞。来源:http://blog.libtorrent.org/2012/10/asynchronous-disk-io/ 像这些技巧中的所有技巧一样,您需要进行试验以查看它是否适合您。 - Mike Andrews
你的参考引用了在关闭HFS+上的稀疏文件时,close()会阻塞的情况,因为内核会填充所有空白空间。这只意味着逻辑上进行填充,而在磁盘分配映射中,并没有提及更改是否同步写入。POSIX close()不保证刷新,这就是为什么存在fsync()的原因。仅仅因为MacOSX的close() 阻塞,并不意味着它正在同步 - hyc
从文档中看来,草率地这样做可能会破坏数据库。是否有某种配置可以将ACID的Durability移除而不会破坏数据库? - The Quantum Physicist

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接