17 个版本 (8 个重大更改)
新版本 0.9.0 | 2024年8月21日 |
---|---|
0.8.1 | 2024年7月8日 |
0.7.3 | 2024年6月5日 |
0.4.0 | 2024年3月12日 |
0.1.0 | 2023年11月29日 |
#359 在 缓存
19,045 每月下载量
用于 6 个 crates (5 个直接使用)
81KB
1.5K SLoC
foyer
foyer 旨在成为 Rust 中一个高效且用户友好的混合缓存库。
foyer 从 Facebook/CacheLib 等项目中汲取灵感,这是一个备受推崇的 C++ 编写的混合缓存库,以及 ben-manes/caffeine,一个流行的 Java 缓存库。
然而,foyer 不仅仅是一个 Rust 中的重写 工作量;它引入了各种新优化的功能。
功能
- 混合缓存:无缝集成内存和基于磁盘的缓存,以实现最佳性能和灵活性。
- 即插即用算法:为用户提供易于替换的缓存算法,确保适应各种用例。
- 无惧并发:构建用于处理高并发的强大线程安全机制,确保在重负载下可靠性能。
- 零拷贝内存缓存抽象:利用 Rust 强大的类型系统,foyer 中的内存缓存通过零拷贝抽象实现更好的性能。
- 用户友好界面:提供简单直观的 API,使缓存集成轻松易用,适用于所有层次的开发者。
- 开箱即用可观察性:只需一行即可集成流行的观察系统,如 Prometheus、Grafana、Opentelemetry 和 Jaeger。
使用 foyer 的项目
请随时打开 PR 并在此处添加您的项目
- RisingWave:SQL 流处理、分析和管理。
- Chroma:嵌入 LLM 应用程序的数据库。
用法
要在您的项目中使用 foyer,请将此行添加到 dependencies
部分的 Cargo.toml
。
foyer = "0.11"
如果您的项目正在使用 nightly rust 工具链,则必须启用 nightly
功能。
foyer = { version = "0.11", features = ["nightly"] }
开箱即用内存缓存
use foyer::{Cache, CacheBuilder};
fn main() {
let cache: Cache<String, String> = CacheBuilder::new(16).build();
let entry = cache.insert("hello".to_string(), "world".to_string());
let e = cache.get("hello").unwrap();
assert_eq!(entry.value(), e.value());
}
易于使用的混合缓存
use foyer::{DirectFsDeviceOptionsBuilder, HybridCache, HybridCacheBuilder};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let dir = tempfile::tempdir()?;
let hybrid: HybridCache<u64, String> = HybridCacheBuilder::new()
.memory(64 * 1024 * 1024)
.storage()
.with_device_config(
DirectFsDeviceOptionsBuilder::new(dir.path())
.with_capacity(256 * 1024 * 1024)
.build(),
)
.build()
.await?;
hybrid.insert(42, "The answer to life, the universe, and everything.".to_string());
assert_eq!(
hybrid.get(&42).await?.unwrap().value(),
"The answer to life, the universe, and everything."
);
Ok(())
}
完全配置的混合缓存
use std::sync::Arc;
use anyhow::Result;
use chrono::Datelike;
use foyer::{
DirectFsDeviceOptionsBuilder, FifoPicker, HybridCache, HybridCacheBuilder, LruConfig, RateLimitPicker, RecoverMode,
RuntimeConfig, TokioRuntimeConfig, TombstoneLogConfigBuilder,
};
use tempfile::tempdir;
#[tokio::main]
async fn main() -> Result<()> {
let dir = tempdir()?;
let hybrid: HybridCache<u64, String> = HybridCacheBuilder::new()
.memory(1024)
.with_shards(4)
.with_eviction_config(LruConfig {
high_priority_pool_ratio: 0.1,
})
.with_object_pool_capacity(1024)
.with_hash_builder(ahash::RandomState::default())
.with_weighter(|_key, value: &String| value.len())
.storage()
.with_device_config(
DirectFsDeviceOptionsBuilder::new(dir.path())
.with_capacity(64 * 1024 * 1024)
.with_file_size(4 * 1024 * 1024)
.build(),
)
.with_flush(true)
.with_indexer_shards(64)
.with_recover_mode(RecoverMode::Quiet)
.with_recover_concurrency(8)
.with_flushers(2)
.with_reclaimers(2)
.with_buffer_threshold(256 * 1024 * 1024)
.with_clean_region_threshold(4)
.with_eviction_pickers(vec![Box::<FifoPicker>::default()])
.with_admission_picker(Arc::new(RateLimitPicker::new(100 * 1024 * 1024)))
.with_reinsertion_picker(Arc::new(RateLimitPicker::new(10 * 1024 * 1024)))
.with_compression(foyer::Compression::Lz4)
.with_tombstone_log_config(
TombstoneLogConfigBuilder::new(dir.path().join("tombstone-log-file"))
.with_flush(true)
.build(),
)
.with_runtime_config(RuntimeConfig::Separated {
read_runtime_config: TokioRuntimeConfig {
worker_threads: 4,
max_blocking_threads: 8,
},
write_runtime_config: TokioRuntimeConfig {
worker_threads: 4,
max_blocking_threads: 8,
},
})
.build()
.await?;
hybrid.insert(42, "The answer to life, the universe, and everything.".to_string());
assert_eq!(
hybrid.get(&42).await?.unwrap().value(),
"The answer to life, the universe, and everything."
);
let e = hybrid
.fetch(20230512, || async {
let value = mock().await?;
Ok(value)
})
.await?;
assert_eq!(e.key(), &20230512);
assert_eq!(e.value(), "Hello, foyer.");
hybrid.close().await.unwrap();
Ok(())
}
async fn mock() -> Result<String> {
let now = chrono::Utc::now();
if format!("{}{}{}", now.year(), now.month(), now.day()) == "20230512" {
return Err(anyhow::anyhow!("Hi, time traveler!"));
}
Ok("Hello, foyer.".to_string())
}
其他示例
更多示例和详细信息可以在此处找到:这里。
支持的 Rust 版本
foyer 是基于最近的稳定版构建的。最低支持的版本是 1.77。当前 foyer 版本不一定能在低于最低支持版本的 Rust 版本上构建。
开发状态 & 路线图
目前,foyer 还处于高度开发状态。
开发状态和路线图可以在 foyer - 开发路线图 中找到。
贡献
欢迎为 foyer 贡献!🥰
在提交 PR 之前,不要忘记在本地运行 make fast
(表示快速检查 & 测试)。🚀
如果您想在本地运行更广泛的检查,请运行 make full
。🙌
星号历史
依赖项
~9–19MB
~255K SLoC