Rust中的缓存:Redis、Memcached及内置解决方案

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Rust中的缓存:Redis及其他高效解决方案



在现代高负载的Rust开发中,缓存扮演着关键角色。它可以降低数据库负载、加速API响应并优化昂贵计算的处理。本文将介绍Rust生态系统中的主要缓存库:从强大的Redis到轻量级的内存解决方案。



1. 通过crate redis-rs使用Redis



redis-rs 是Rust中用于操作Redis的主要且最成熟的库。它支持异步操作(通过tokio或async-std)、集群、发布/订阅以及所有流行的Redis数据类型。



安装

[dependencies]redis = { version = "0.25", features = ["tokio-comp"] }tokio = { version = "1", features = ["full"] }


基础示例:字符串缓存

use redis::AsyncCommands;

#[tokio::main]async fn main() -> redis::RedisResult<()> { let client = redis::Client::open("redis://127.0.0.1:6379/")?; let mut con = client.get_multiplexed_async_connection().await?;

// 设置TTL为60秒的缓存 let _: () = con.set_ex("user:123", "{\\"name\\":\\"Alice\\"}", 60).await?;

// 获取值 let cached: String = con.get("user:123").await?; println!("缓存数据: {}", cached);

// 检查键是否存在 let exists: bool = con.exists("user:123").await?; println!("键存在: {}", exists);

Ok(())}


复杂结构的序列化

要缓存数据结构,请将serde与redis结合使用:

use serde::{Serialize, Deserialize};use redis::AsyncCommands;

#[derive(Debug, Serialize, Deserialize)]struct User { id: u32, name: String, email: String,}

async fn cache_user(con: &mut redis::aio::MultiplexedConnection, user: &User) { let json = serde_json::to_string(user).unwrap(); let _: () = con.set_ex(format!("user:{}", user.id), json, 300).await.unwrap();}

async fn get_cached_user(con: &mut redis::aio::MultiplexedConnection, id: u32) -> Option<User> { let json: Option<String> = con.get(format!("user:{}", id)).await.unwrap(); json.and_then(|data| serde_json::from_str(&data).ok())}


2. 内存缓存:crate moka



Moka 是一个高性能的内存缓存库,灵感来自Caffeine (Java)。它非常适合不需要外部服务器、追求极致速度的场景。



moka的特点:

  • 基于时间(TTL、TTI)和大小的自动淘汰
  • 异步同步(后台刷新)
  • 多线程安全(Arc + RwLock)
  • 支持权重策略(weighted cache)


示例:带TTL和大小限制的缓存

use moka::sync::Cache;use std::time::Duration;

fn main() { // 创建一个最多1000个元素、TTL为10分钟的缓存 let cache: Cache<String, String> = Cache::builder() .max_capacity(1000) .time_to_live(Duration::from_secs(600)) .build();

// 插入和获取 cache.insert("key1".to_string(), "value1".to_string()); if let Some(v) = cache.get("key1") { println!("值: {}", v); }}


异步版本 (moka::future::Cache)

use moka::future::Cache;

#[tokio::main]async fn main() { let cache: Cache<u64, String> = Cache::new(10_000);

// 异步插入 cache.insert(42, "Hello async".to_string()).await;

// 异步获取 if let Some(val) = cache.get(&42).await { println!("{}", val); }}


3. 声明式缓存:crate <

推荐