引言在当今的数据驱动时代,高效的数据存储和管理至关重要。嵌入式键值存储因其轻量级、高性能和易于集成的特点,在众多应用场景中得到了广泛应用。Redb作为一个新兴的嵌入式键值存储库,以其简单、可移植、高性能和支持ACID等特性,吸引了众多开发者的关注。本文将深入解读Redb的核心特性、
在当今的数据驱动时代,高效的数据存储和管理至关重要。嵌入式键值存储因其轻量级、高性能和易于集成的特点,在众多应用场景中得到了广泛应用。
Redb 作为一个新兴的嵌入式键值存储库,以其简单、可移植、高性能和支持 ACID 等特性,吸引了众多开发者的关注。
本文将深入解读 Redb 的核心特性、性能表现、设计原理以及使用方法,帮助你更好地了解和使用这个强大的工具。
Redb 是一个用纯 Rust 编写的嵌入式键值存储库,它受到了 lmdb 的启发,采用了复制写(copy-on-write)的 B 树来存储数据。这种设计使得 Redb 具有很高的性能和可靠性,同时保持了代码的简洁性和可维护性。
BTreeMap
的零拷贝、线程安全 API,减少了数据复制的开销,提高了并发性能。Redb 的性能表现是其一大亮点,它与其他顶级嵌入式键值存储(如 lmdb 和 rocksdb)相近。下面是 Redb 与其他存储库的性能对比: | 操作类型 | redb | lmdb | rocksdb | sled | sanakirja |
---|---|---|---|---|---|---|
批量加载(bulk load) | 2689ms | 1247ms | 5330ms | 5892ms | 1187ms | |
单条写入(individual writes) | 226ms | 419ms | 703ms | 816ms | 398ms | |
批量写入(batch writes) | 2522ms | 2070ms | 1047ms | 1867ms | 2776ms | |
获取长度(len()) | 0ms | 0ms | 304ms | 444ms | 64ms | |
随机读取(random reads) | 860ms | 624ms | 2432ms | 1596ms | 875ms | |
随机读取(random reads) | 866ms | 624ms | 2464ms | 1588ms | 842ms | |
随机范围读取(random range reads) | 2347ms | 1179ms | 4436ms | 4907ms | 1367ms | |
随机范围读取(random range reads) | 2322ms | 1207ms | 4465ms | 4732ms | 1373ms | |
随机读取(4 线程)(random reads (4 threads)) | 337ms | 158ms | 732ms | 488ms | 349ms | |
随机读取(8 线程)(random reads (8 threads)) | 185ms | 81ms | 433ms | 259ms | 277ms | |
随机读取(16 线程)(random reads (16 threads)) | 116ms | 49ms | 238ms | 165ms | 1708ms | |
随机读取(32 线程)(random reads (32 threads)) | 100ms | 44ms | 203ms | 142ms | 4714ms | |
删除操作(removals) | 1889ms | 803ms | 2038ms | 2371ms | 1170ms | |
未压缩大小(uncompacted size) | 1.00 GiB | 582.22 MiB | 206.38 MiB | 457.01 MiB | 4.00 GiB | |
压缩后大小(compacted size) | 311.23 MiB | 284.46 MiB | 106.26 MiB | N/A | N/A |
从上述数据可以看出,Redb 在单条写入和获取长度操作上表现出色,而在其他操作上也与其他存储库各有优劣。这表明 Redb 在不同的应用场景下都能提供较好的性能表现。
Redb 的数据库文件逻辑上由一些元数据和多个 B 树组成,包括待释放页树(pending free tree)、表树(table tree)和数据表树(data tree)。除了数据库元数据外,所有其他数据结构都是复制写的,这意味着在修改数据时,会创建新的数据副本,而不是直接修改原始数据,从而保证了数据的一致性和可恢复性。
Redb 支持两种事务提交策略:单阶段加校验和提交(1PC+C)和两阶段持久化提交(2PC)。
fsync
操作完成提交。首先,将所有数据和校验和写入磁盘,同时写入一个单调递增的事务 ID,然后翻转主页面标志并调用 fsync
。如果发生崩溃,需要验证主页面的事务 ID 是否更大,以及所有校验和是否有效。如果验证失败,数据库将用备用页面替换部分更新的主页面。这种策略减少了提交延迟,但在处理恶意数据时存在一定的安全风险。fsync
操作完成提交,能够减轻处理恶意数据时的理论攻击风险。首先,将数据写入 B 树的新副本,然后进行第一次 fsync
;最后,翻转控制 B 树主副本的字节并进行第二次 fsync
。Redb 采用了基于纪元的页面回收机制,确保页面在不再被引用后才被释放。在事务和保存点的处理过程中,需要特别注意避免释放仍被引用的页面,以保证数据的一致性和完整性。
下面是一个简单的使用示例,展示了如何创建数据库、插入数据和读取数据:
use redb::{Database, Error, ReadableTable, TableDefinition};
const TABLE: TableDefinition<&str, u64> = TableDefinition::new("my_data");
fn main() -> Result<(), Error> {
let db = Database::create("my_db.redb")?;
let write_txn = db.begin_write()?;
{
let mut table = write_txn.open_table(TABLE)?;
table.insert("my_key", &123)?;
}
write_txn.commit()?;
let read_txn = db.begin_read()?;
let table = read_txn.open_table(TABLE)?;
assert_eq!(table.get("my_key")?.unwrap().value(), 123);
Ok(())
}
要运行 Redb 的所有测试和基准测试,需要安装一些额外的依赖:
cargo install cargo-deny --locked
cargo install cargo-fuzz --locked
apt install libclang-dev
Redb 作为一个新兴的嵌入式键值存储库,具有简单、可移植、高性能和支持 ACID 等特性,在性能上与其他顶级存储库相近。其采用的复制写 B 树和 MVCC 并发控制机制,保证了数据的一致性和并发性能。
同时,支持多种事务提交策略和保存点回滚操作,提高了系统的可靠性和灵活性。如果你正在寻找一个高性能、可靠的嵌入式键值存储解决方案,Redb 是一个值得考虑的选择。
Redb 目前正在区块链行业中得到广泛应用。其文件格式保持稳定,在区块链领域的应用展示了它在现实世界高需求场景中的可靠性和性能。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!