如何在内存中持久化RocksDB数据库

最近几个月,我们集中精力为内存工作负载优化RocksDB。随着RAM大小的增长和严格的低延迟要求,许多应用程序决定将它们的整个数据保存在内存中。 使用RocksDB在内存中运行数据库很容易——只需将RocksDB目录挂载到tmpfs或ramfs[1]上。 即使进程崩溃,RocksDB也可以从内存文件系统中恢复所有数据。但是,如果机器重新启动会发生什么?

在本文中,我们将解释如何在机器重启之后恢复内存中的RocksDB数据库。

每次对RocksDB的更新都被写到两个地方——一个是内存中的数据结构memtable,另一个是写前日志。 写前日志可以用来完全恢复memtable中的数据。默认情况下,当我们将memtable刷新到表文件时,还会删除当前日志,因为我们不再需要它进行恢复(日志中的数据“持久化”到表文件中——我们说日志文件已经过时)。 但是,如果表文件存储在内存文件系统中,则可能需要使用过时的写前日志,以便在机器重新启动后恢复数据。你可以这样做。

Options::wal_dir是RocksDB存储写前日志文件的目录。 如果将此目录配置为在闪存或磁盘上,则在计算机重新启动时不会丢失当前日志文件。 Options::WAL_ttl_seconds是删除归档日志文件时的超时。 如果超时不为零,那么过时的日志文件将被移动到Options::wal_dir下的archive/目录。 这些存档日志文件只会在指定的超时之后删除。

让我们假设Options::wal_dir是持久性存储上的一个目录,Options::WAL_ttl_seconds被设置为一天。 为了完全恢复数据库,我们还需要以少于一天的频率备份数据库的当前快照(包含表和元数据文件)。 RocksDB提供了一个实用程序,可以方便地备份数据库快照。您可以在这里了解更多信息: https://github.com/facebook/rocksdb/wiki/How-to-backup-RocksDB%3F

您应该配置备份进程,以避免备份日志文件,因为它们已经存储在持久存储中。 为此,将BackupableDBOptions::backup_log_files设置为false。

在默认情况下,还原进程将清理整个DB和WAL目录。由于我们没有在备份中包含日志文件,所以需要确保恢复数据库不会删除WAL目录中的日志文件。 恢复时,将RestoreOptions::keep_log_file配置为true。该选项还将把任何存档的日志文件移回WAL目录,使RocksDB能够重播所有存档的日志文件并重建内存中的数据库状态。

重申一遍,你需要做的是:

1.将DB目录设置为tmpfs或ramfs挂载驱动器

2.设置Option::wal_log到持久存储上的目录

3.设置选项::WAL_ttl_seconds to T seconds

4.每隔T/2秒备份一次RocksDB,使用BackupableDBOptions::backup_log_files = false

5.当您丢失数据时,使用RestoreOptions::keep_log_file = true从备份中恢复

您可能还想考虑对表文件使用纯表格式 — https://github.com/facebook/rocksdb/wiki/PlainTable-Format