在内存数据库中使用 LMDB

Posted

技术标签:

【中文标题】在内存数据库中使用 LMDB【英文标题】:In memory databases with LMDB 【发布时间】:2016-03-23 05:55:17 【问题描述】:

我有一个项目,它使用 BerkelyDB 作为键值存储来存储多达数亿条小记录。

它的使用方式是将所有值插入到数据库中,然后使用顺序访问和随机访问对它们进行迭代,所有这些都来自单个线程。

使用 BerkeleyDB,我可以创建“从未打算保存在磁盘上”的 in-memory databases。如果数据库足够小以适合 BerkeleyDB 缓存,则它永远不会被写入磁盘。如果它大于缓存,则将创建一个临时文件来保存溢出。此选项可以显着加快速度,因为它可以防止我的应用程序在关闭数据库时将千兆字节的死数据写入磁盘。

我发现 BerkeleyDB 的写入性能太差了,即使在 SSD 上也是如此,所以我想切换到LMDB。但是,基于documentation,,似乎没有创建非持久数据库的选项。

如果我根本不关心持久性或并发访问,我应该使用什么配置/选项组合来获得 LMDB 的最佳性能?即让它像一个带有临时备份磁盘存储的“内存数据库”?

【问题讨论】:

【参考方案1】:

只使用 MDB_NOSYNC 并且永远不要自己打电话给mdb_env_sync()。此外,您还可以使用 MDB_WRITEMAP。操作系统最终仍会将脏页刷新到磁盘;您可以使用 /proc/sys/vm/dirty_ratio 等来控制该行为。

【讨论】:

我认为这仍然会导致数据库关闭时所有内容都写入磁盘?对于完全在内存中的数据库,这会显着减慢整个操作。 废话。关闭文件不会刷新文件。如果您在操作系统刷新之前关闭并删除文件,则不会写入任何内容。 为了完整起见,您在 Linux 上的大多数(如果不是全部)情况下都是正确的。但这并不一定适用于其他操作系统,甚至所有文件系统。至少有一些证据表明close() 在 Mac OS X 上的某些情况下会阻塞。来源:blog.libtorrent.org/2012/10/asynchronous-disk-io 与所有这些技巧一样,您需要进行试验,看看它是否真的适合您。 您的参考文献引用了 close() 将在关闭 HFS+ 上的稀疏文件时阻塞,因为内核会填充所有空白空间。这仅意味着它在逻辑上填充,在其磁盘分配映射中,没有提及更改是否是同步写入的。 POSIX close() 不保证刷新,这就是 fsync() 存在的原因。仅仅因为 MacOSX close() blocks 并不意味着它正在 syncing 从文档看来,不小心这样做可能会损坏数据库。是否有某种配置不会破坏数据库并仅从 ACID 中删除 Durability?【参考方案2】:

来自这个帖子:https://lonesysadmin.net/2013/12/22/better-linux-disk-caching-performance-vm-dirty_ratio/

vm.dirty_ratio 是在所有内容都必须提交到磁盘之前可以用脏页填充的系统内存的绝对最大量。当系统到达这一点时,所有新的 I/O 阻塞,直到脏页被写入磁盘。

如果脏比太小,那么你会看到频繁的同步磁盘写入。

【讨论】:

以上是关于在内存数据库中使用 LMDB的主要内容,如果未能解决你的问题,请参考以下文章

caffe实战笔记

LMDB数据库加速Pytorch文件读取速度

caffe-Windows以mnist为例lmdb格式数据

Python LMDB的使用

caffe数据层

Caffe系列2——制作LMDB数据详细过程(手把手教你制作LMDB)