Rust 用 moka 构建内存缓存,TTL 与 LRU 回收并发安全
test12026-10-092 次阅读
为什么选 moka
Rust 里自己用 HashMap 加锁做缓存既慢又容易出并发 bug。moka 是一个高性能、线程安全的异步/同步缓存库,内置 TTL(存活时间)、TTI(空闲时间)和基于容量的 LRU 回收,读写几乎无锁,适合在高并发服务里当本地缓存层。
同步缓存基础
sync::Cache 用在非 async 上下文,设置 max_capacity 与 TTL 后,写入和读取都是原子的,多个线程可安全共享。
use moka::sync::Cache;
use std::time::Duration;
fn main() {
let cache: Cache<String, String> = Cache::builder()
.max_capacity(10_000)
.time_to_live(Duration::from_secs(300))
.time_to_idle(Duration::from_secs(60))
.build();
cache.insert("user:1".to_string(), "alice".to_string());
if let Some(name) = cache.get(&"user:1".to_string()) {
println!("hit: {}", name);
}
println!("size = {}", cache.run_pending_tasks());
}
异步缓存与"取数回填"
future::Cache 用在 async 运行时里,配合 try_get_with 可以在未命中时异步计算并自动回填,且并发请求只会触发一次计算。
use moka::future::Cache;
use std::time::Duration;
async fn get_user(cache: &Cache<u64, String>, id: u64) -> String {
cache
.try_get_with(id, async {
// 这里查数据库,并发未命中只执行一次
Ok(fetch_from_db(id).await)
})
.await
.unwrap_or_else(|e| e.to_string())
}
async fn fetch_from_db(id: u64) -> String {
format!("user-{}", id)
}
工程要点
- max_capacity 是软上限,超过后会按 LRU 异步回收,不会阻塞读写。
- TTL 控制绝对存活,TTI 控制空闲回收,二者可单独或同时设置。
- sync 版本适合简单场景且零 async 成本;需要 await 取数回填时选 future 版本。
- 想拿到精确计数可调用 run_pending_tasks,否则回收在后台惰性发生。
T
test1
文章作者
为什么选 moka Rust 里自己用 HashMap 加锁做缓存既慢又容易出并发 bug。moka 是一个高性能、线...
- 分类
- 技术
- 发布时间
- 2026-10-09
- 字数
- 约 1351 字
- 阅读
- 2 次
