2 个版本
0.1.1 | 2024年1月21日 |
---|---|
0.1.0 | 2024年1月1日 |
#25 in #memory-mapped
125KB
3.5K SLoC
Bitcasky
Bitcasky 是 Bitcask 键值存储的 Rust 实现。它是一个符合 ACID 规范的只追加键值存储,提供高写入吞吐量。它针对高写入负载进行了优化,常用于日志存储和时间序列数据等应用。
功能
- 只追加存储以提供持久性和一致性
- 内存映射文件以实现高效的 I/O
- 具有 O(1) 读写性能的键值存储
- 存储可过期值
用法
基本用法
要使用 Bitcasky,只需将其添加到您的 Cargo.toml
文件中
[dependencies]
bitcasky = "0.1.2"
然后,在您的 Rust 代码中,导入 bitcasky
包并开始使用键值存储
use bitcasky::Bitcasky;
fn main() {
let mut db = Bitcasky::open("/path/to/db", BitcaskyOptions::default()).unwrap()
db.put("key", "value").unwrap();
assert!(db.has("key").unwrap());
let value = db.get("key").unwrap().unwrap();
println!("{:?}", value);
}
存储可过期值
db.put_with_ttl("key", "value", Duration::from_secs(60)).unwrap();
// 60 seconds later
assert!(db.get("key").unwrap().is_none());
删除某些值或整个数据库
db.put("key1", "value1").unwrap();
db.put("key2", "value2").unwrap();
// delete some value
db.delete("key1").unwrap();
assert!(db.get("key1").unwrap().is_none());
// drop database
db.drop().unwrap();
assert!(db.get("key2").unwrap().is_none());
迭代数据库
迭代所有键。
// iterate and print all keys in database
bc.foreach_key(|k| println!("{}", String::from_utf8_lossy(k))).unwrap();
// fold all keys by concatenate them
let ret = bc.fold_key(
|k, accumulator: Option<String>| match accumulator {
// concatenate new key to folded key string
Some(folded_k) => Ok(Some(folded_k + &String::from_utf8_lossy(k))),
// if we have not fold anything, use this new key as folded key
None => Ok(Some(String::from_utf8_lossy(k).into())),
},
// init accumulator
None,
)
.unwrap();
assert!(ret.is_some());
println!("{}", ret.unwrap());
迭代所有键和值。
// iterate and print all keys and values in database
bc.foreach(|k, v| {
println!(
"key: {}, value: {}",
String::from_utf8_lossy(k),
String::from_utf8_lossy(v)
)
})
.unwrap();
// fold all keys and values by concatenate them
let ret = bc
.fold(
|k, v, accumulator: Option<String>| match accumulator {
// concatenate new key and value to folded values
Some(folded_vals) => Ok(Some(format!(
"{} key: {}, val: {};",
folded_vals,
String::from_utf8_lossy(k),
String::from_utf8_lossy(v)
))),
// if we have not fold anything, use this new key and value as folded values
None => Ok(Some(format!(
"key: {}, val: {};",
String::from_utf8_lossy(k),
String::from_utf8_lossy(v)
))),
},
// init accumulator
None,
)
.unwrap();
assert!(ret.is_some());
println!("{}", ret.unwrap());
同步策略
通过选择同步策略,您可以通过指定何时将数据同步到磁盘来配置写入的持久性。
以下同步策略可用
- None — 由操作系统管理同步写入
- OSync — 使用 O_SYNC 标志,强制每次写入都进行同步
- 时间间隔 — 在指定的时间间隔内同步(默认:60 秒)
例如,创建一个每 35 秒同步一次的 Bitcasky 数据库,如下所示
let db = Bitcasky::open(
"/path/to/db",
BitcaskyOptions::default().sync_strategy(SyncStrategy::Interval(Duration::from_secs(35)))
).unwrap();
合并过程
Bitcasky 需要定期调用合并以减少磁盘使用。合并过程遍历数据文件,通过消除过期的或已删除的键值对来回收空间,只将当前键值对写入目录中的新文件集。
通过在 Bitcaksy 实例上调用 merge
来启动合并过程,如下所示
db.merge().unwrap();
许可证
本项目采用 MIT 许可证。
依赖项
~4–13MB
~158K SLoC