2 个版本
0.2.1 | 2024年4月27日 |
---|---|
0.2.0 | 2024年4月27日 |
0.1.5 |
|
#117 in 并发
130 次每月下载
300KB
8K SLoC
Async SkipDB
介绍
一个嵌入式、内存中、零拷贝、MVCC、几乎无锁且可序列化快照隔离的数据库引擎。
async-skipdb
的 SSI(可序列化快照隔离)事务模型参考了 foundationdb
的论文 和 badger
。
同步版本请参见 skipdb
。
该 crate 包含两种内存中的键值数据库
-
SerializableDb
支持并发执行完全可序列化快照隔离事务和乐观并发控制事务。
通过
SerializableDb::serializable_write
创建的事务可以正确处理所有类型的写偏斜。通过
SerializableDb::optimistic_write
创建的事务可以处理所有类型的直接依赖写偏斜,但不能处理所有类型的间接依赖写偏斜,例如 https://wiki.postgresql.ac.cn/wiki/SSI#Intersecting_Data。 -
OptimisticDb
仅支持乐观并发控制的并发执行,这意味着写事务无法检测所有类型的写偏斜。
可以正确处理所有类型的直接依赖写偏斜,但不能处理所有类型的间接依赖写偏斜,例如 https://wiki.postgresql.ac.cn/wiki/SSI#Intersecting_Data。
特性
- 原子性、一致性、隔离性、MVCC、并发安全且几乎无锁。
- 没有额外的分配和复制,数据库中存储的键和值都没有
Arc
包装器,这意味着用户提供K
和V
,数据库直接存储K
和V
。 - 零拷贝和原地压缩,意味着在压缩时没有拷贝,没有额外的分配。
- 事务并发执行,提供可序列化快照隔离,避免写倾斜。
- 读事务和写事务都是
Send + Sync + 'static
,这意味着您不再需要处理烦人的生命周期问题。 - 无锁且并发安全的读事务:读事务完全并发安全,可以在多个线程中共享,读事务中没有锁。
BTreeMap
类的用户友好 API 和所有迭代器实现Iterator
特性,这意味着用户在遍历数据库时可以使用 Rust 强大的组合器。- 运行时无关,支持
tokio
、async-std
、smol
、wasm-bindgen-futures
和任何其他异步运行时。 - 100% 安全,使用
[forbid(unsafe_code)]
。
安装
-
tokio
[dependencies] async-skipdb = { version = "0.2", features = ["tokio"] }
-
async-std
[dependencies] async-skipdb = { version = "0.2", features = ["async-std"] }
-
smol
[dependencies] async-skipdb = { version = "0.2", features = ["smol"] }
-
wasm-bindgen-futures
[dependencies] async-skipdb = { version = "0.2", features = ["wasm"] }
示例
use async_skipdb::serializable::TokioSerializableDb;
#[derive(Debug)]
struct Person {
name: String,
hobby: String,
age: u8,
}
#[tokio::main]
async fn main() {
let db: TokioSerializableDb<u64, Person> = TokioSerializableDb::new().await;
{
let alice = Person { name: "Alice".to_string(), hobby: "swim".to_string(), age: 20 };
let bob = Person { name: "Bob".to_string(), hobby: "run".to_string(), age: 30 };
let mut txn = db.serializable_write().await;
txn.insert(1, alice).unwrap();
txn.insert(2, bob).unwrap();
{
let alice = txn.get(&1).unwrap().unwrap();
assert_eq!(alice.value().name, "Alice");
assert_eq!(alice.value().age, 20);
assert_eq!(alice.value().hobby, "swim");
}
txn.commit().await.unwrap();
}
{
let txn = db.read().await;
let alice = txn.get(&1).unwrap();
assert_eq!(alice.value().name, "Alice");
assert_eq!(alice.value().age, 20);
assert_eq!(alice.value().hobby, "swim");
let bob = txn.get(&2).unwrap();
assert_eq!(bob.value().name, "Bob");
assert_eq!(bob.value().age, 30);
assert_eq!(bob.value().hobby, "run");
}
}
许可协议
async-skipdb
同时遵守 MIT 许可协议和 Apache 许可协议(版本 2.0)。
有关详细信息,请参阅 LICENSE-APACHE、LICENSE-MIT。
版权所有 (c) 2024 Al Liu。
依赖项
~3–15MB
~194K SLoC