LevelDB 选项与使用示例

详解 LevelDB 的常用选项(Options/ReadOptions/WriteOptions)与核心 API 使用示例:Put/Get/Delete/WriteBatch 批量写、Iterator 迭代器与排序遍历、Compaction 与实现机制,附 db_bench 基准说明与真实运行输出。基于 LevelDB 1.23 实测。

RocksDB与LevelDBLevelDB嵌入式数据库KV存储配置详解NoSQL2026/10/02

LevelDB 选项与使用示例

目标:掌握 LevelDB 作为嵌入 KV 库的选项配置与 C++ 核心 API 用法。LevelDB 是 ordered key-value store(有序键值),核心由 leveldb::DB::Open 打开库,用 Put/Get/Delete/WriteBatch 读写,用 Iterator 有序遍历。本文示例编译运行于 LevelDB 1.23(链接 libleveldb.a + -lsnappy)。

一、核心概念

  • 排序:键按字典序(byte-wise)排序保存。
  • LSM 结构:写先入内存 memtable(再固化 immutable memtable → SST),通过 Compaction(多级合并)维持读效率。
  • 无服务进程:LevelDB 是库,由宿主进程以单进程或多进程(需锁)方式使用。

二、选项(Options)

leveldb::Options 在 DB::Open 时配置库级行为:

字段说明常见值
create_if_missing库不存在时自动创建true
error_if_exists库已存在时报错(排障用)false
write_buffer_size内存写缓冲(memtable)大小默认 4MB(4<<20)
max_open_files可打开的文件句柄上限默认 1000
block_cache读缓存(NewLRUCache)默认空
block_sizeSST 数据块大小默认 4KB
compression压缩方式kSnappyCompression/kNoCompression
filter_policyBloom 过滤器,加速查不存在 keyNewBloomFilterPolicy(10)
comparator键比较器(自定义排序)默认字节序比较

典型配置:

leveldb::Options opts;
opts.create_if_missing = true;
opts.write_buffer_size = 8 << 20;               // 8 MB
opts.block_cache = leveldb::NewLRUCache(64 << 20);   // 64 MB 读缓存
opts.filter_policy = leveldb::NewBloomFilterPolicy(10);
opts.compression = leveldb::kSnappyCompression;
leveldb::DB::Open(opts, "/data/ldb", &db);

三、ReadOptions / WriteOptions

ReadOptions(读):

字段说明
verify_checksums读时校验数据校验和(默认 false)
fill_cache读入的数据是否填充块缓存(默认 true)

WriteOptions(写):

字段说明
sync写入是否等落盘再返回(默认 false,更快)
// 每次写同步落盘(更安全但更慢)
leveldb::WriteOptions wo;
wo.sync = true;
db->Put(wo, "k", "v");

四、核心 API 使用示例

完整可编译 demo(g++ -std=c++11 demo.cc -lleveldb -lsnappy -lpthread):

4.1 Put / Get / Delete

#include <cassert>
#include <iostream>
#include "leveldb/db.h"

leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
leveldb::Status s = leveldb::DB::Open(options, "/tmp/ldb", &db);

s = db->Put(leveldb::WriteOptions(), "key1", "value1");   // 写
assert(s.ok());

std::string v;
s = db->Get(leveldb::ReadOptions(), "key1", &v);          // 读
if (s.ok()) std::cout << "Get key1=" << v << std::endl;

std::string miss;
s = db->Get(leveldb::ReadOptions(), "nokey", &miss);      // 读不存在的 key
std::cout << "Get nokey=" << s.ToString() << std::endl;   // NotFound

s = db->Delete(leveldb::WriteOptions(), "key1");          // 删
assert(s.ok());

实测输出:

Get: key1 = value1
Get: nokey -> NotFound:
Delete key1 ok

4.2 WriteBatch 批量写(原子)

WriteBatch 把多条写合并为一次原子提交,减少 RTT 并保证原子性:

#include "leveldb/write_batch.h"

leveldb::WriteBatch batch;
batch.Put("a", "1");
batch.Put("b", "2");
// batch.Delete("a");          // 支持混合删除
db->Write(leveldb::WriteOptions(), &batch);

实测输出:Batch written。

4.3 Iterator 有序遍历

leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
for (it->SeekToFirst(); it->Valid(); it->Next())
  std::cout << "  " << it->key().ToString() << " -> "
            << it->value().ToString() << std::endl;
delete it;

实测输出(插入 a、b、key1 后遍历,按字典序):

Iterate all keys:
  a -> 1
  b -> 2
  key1 -> value1

常用迭代操作:

方法作用
SeekToFirst() / SeekToLast()跳到第一个 / 最后一个
Seek(target)跳到 >= target 的第一个键
Valid() / Next() / Prev()判断有效 / 前进 / 后退
key() / value()读当前键 / 值

五、db_bench 基准(可选)

启用 LEVELDB_BUILD_BENCHMARKS=ON 时编译出 db_bench,可测读写吞吐:

cd build && cmake --build . --target db_bench
./db_bench

输出包含 fillseq、readrandom 等阶段与每秒操作数(ops/sec)。

六、常见问题(FAQ)

1. 多进程能同时打开同一个库吗?

LevelDB 用文件锁实现单写者;多进程并发写同一目录会因锁失败。多进程场景需先做持久化 DB 锁管理,或改用 RocksDB 的并发模式(见《RocksDB 配置与选项详解》)。

2. 写很慢?

WriteOptions.sync 默认为 false 已非同步;仍需更快的批量写用 WriteBatch 合并。

3. 数据库目录里有哪些文件?

CURRENT、MANIFEST-*、*.log(WAL/memtable 日志)、*.ldb(SST 数据)、LOCK、*.dbtmp 等。别单独复制 logs 已迁移,用官方同步备份机制。

4. 如何确认读到的最新值?

LevelDB 默认返回最新可见值(含未 Compact 的内存与 SST 叠加)。

七、小结

LevelDB 的选项集中在 Options(写缓冲/缓存/压缩/过滤器)与 ReadOptions/WriteOptions(同步/校验)。核心 API 即 Open + Put/Get/Delete + WriteBatch + Iterator,配合 Bloom 过滤与缓存即可用于本地有序 KV 存储。想要更丰富的配置、Blob 与并发写入,可参考姐妹库 RocksDB 的《RocksDB 配置与选项详解》。

LevelDB 选项与使用示例 - Quzuo