9 个版本

0.3.3 2024 年 3 月 17 日
0.3.2 2023 年 2 月 6 日
0.3.1 2023 年 1 月 21 日
0.2.2 2023 年 1 月 15 日
0.1.1 2023 年 1 月 7 日

#285数据库接口

每月 39 次下载

MIT 许可证

105KB
2.5K SLoC

DiskLRU

DiskLRU 是一个用 Rust 实现的实验性 LRU 存储。

它作为一个简单的键值存储,由 sled 提供支持,sled 是一个轻量级的纯 Rust 高性能事务嵌入式数据库。

它通过给定一个数字自动过期条目,遵循 LRU(最近最少使用)策略,这是一个相当常见的缓存替换策略。

它有一定的成本,但有时比仅在 FIFO 模式(先进先出)中过期旧键更合适,因为您可能有一个很久以前就引入存储中的键值对,但它仍然相关。使用 DiskLRU,如果您的代码经常读取值,它将确保键保持活跃,不会消失。

DiskLRU icon

  • HashLRU 在设计上非常相似,充当内存缓存,而 DiskLRU 是一个持久存储。
  • MenhirKV 解决了 DiskLRU 所解决的同一个问题,即“存储东西,保留最常用的值,丢弃其余的”。它以一种不那么严格和精确的方式做到这一点,但效率更高。

状态

目前这是一个玩具项目,显然不适用于生产使用。

它至少有两个显著的缺陷

  • 与其他替代方案相比,它非常(非常)慢,正是这一点促使我开始开发 MenhirKV,它对过期的处理方法更加实用。
  • 它存在严重的稳定性问题,例如,在我的基于 arm64 的笔记本电脑上开启磁盘写入(例如:不使用临时存储)会导致基准测试直接挂起,表现出死锁的症状。

Build Status Crates.io Gitlab License

使用

use disklru::Store;

let mut store = Store::open_temporary(4).unwrap();
store.insert(&1, &10).unwrap();
store.insert(&2, &20).unwrap();
store.insert(&3, &30).unwrap();
store.insert(&4, &40).unwrap();
store.insert(&5, &50).unwrap();
// key1 has been dropped, size is limited to 4
assert_eq!(Some(2), store.lru().unwrap());
assert_eq!(Some(20), store.get(&2).unwrap());
// getting key2 has made key3 the least recently used item
assert_eq!(Some(3), store.lru().unwrap());
assert_eq!(Some(40), store.get(&4).unwrap());
// getting key4 makes it the most recently used item
assert_eq!("[3: 30, 5: 50, 2: 20, 4: 40]", format!("{}", store));
store.flush().unwrap(); // commit

基准测试

来自一个随机的 CI 作业

running 12 tests
test tests::bench_read_usize_disklru_compress    ... bench:     169,738 ns/iter (+/- 21,901)
test tests::bench_read_usize_disklru_persistent  ... bench:     111,211 ns/iter (+/- 12,312)
test tests::bench_read_usize_disklru_temporary   ... bench:     105,257 ns/iter (+/- 25,468)
test tests::bench_read_usize_hashlru             ... bench:         157 ns/iter (+/- 16)
test tests::bench_read_usize_hashmap             ... bench:          40 ns/iter (+/- 10)
test tests::bench_read_usize_lru                 ... bench:          34 ns/iter (+/- 15)
test tests::bench_write_usize_disklru_compress   ... bench:     151,871 ns/iter (+/- 15,723)
test tests::bench_write_usize_disklru_persistent ... bench:     100,999 ns/iter (+/- 5,399)
test tests::bench_write_usize_disklru_temporary  ... bench:      95,390 ns/iter (+/- 15,908)
test tests::bench_write_usize_hashlru            ... bench:         239 ns/iter (+/- 32)
test tests::bench_write_usize_hashmap            ... bench:         117 ns/iter (+/- 26)
test tests::bench_write_usize_lru                ... bench:          84 ns/iter (+/- 25)

test result: ok. 0 passed; 0 failed; 0 ignored; 12 measured; 0 filtered out; finished in 98.17s

这不是广泛的、彻底的基准测试的结果,而是一段开发历史中某个时间点的随机快照。

TL;DR -> 性能不佳。

诚然,比较的是非持久性LRU缓存,因此预期会有“一些性能损失”,但差距在这里非常巨大。我启动的另一个项目,使用Bloom过滤器来过期旧条目,大约比这个快10倍。

运行基准测试

cd bench
rustup default nightly
cargo bench

链接

许可证

DiskLRU采用MIT许可证。

依赖项

~6MB
~107K SLoC