Caching in Rust: Redis und andere effiziente Lösungen
In der modernen hochbelasteten Entwicklung mit Rust spielt Caching eine Schlüsselrolle. Es ermöglicht, die Datenbanklast zu reduzieren, API-Antworten zu beschleunigen und die Arbeit mit teuren Berechnungen zu optimieren. In diesem Artikel betrachten wir die wichtigsten Bibliotheken für Caching im Rust-Ökosystem: vom leistungsstarken Redis bis hin zu leichten In-Memory-Lösungen.
1. Redis über die Crate redis-rs
redis-rs ist die wichtigste und ausgereifteste Bibliothek für die Arbeit mit Redis in Rust. Sie unterstützt asynchrone Operationen (über tokio oder async-std), Clustering, Pub/Sub und alle gängigen Redis-Datentypen.
Installation
[dependencies]redis = { version = "0.25", features = ["tokio-comp"] }tokio = { version = "1", features = ["full"] }Basisbeispiel: Caching von Strings
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?;
// Cache mit TTL von 60 Sekunden setzen let _: () = con.set_ex("user:123", "{\\"name\\":\\"Alice\\"}", 60).await?;
// Wert abrufen let cached: String = con.get("user:123").await?; println!("Gecachte Daten: {}", cached);
// Vorhandensein des Schlüssels prüfen let exists: bool = con.exists("user:123").await?; println!("Schlüssel existiert: {}", exists);
Ok(())}Serialisierung komplexer Strukturen
Verwenden Sie für das Caching von Datenstrukturen serde in Kombination mit 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. In-Memory-Caching: Crate moka
Moka ist eine leistungsstarke Bibliothek für In-Memory-Caching, inspiriert von Caffeine (Java). Sie ist ideal für Szenarien, in denen kein externer Server benötigt wird, sondern maximale Geschwindigkeit gefragt ist.
Funktionen von moka:
- Automatische Verdrängung nach Zeit (TTL, TTI) und nach Größe
- Asynchrone Synchronisierung (Hintergrundaktualisierung)
- Sicherheit für den Multithread-Einsatz (Arc + RwLock)
- Unterstützung von Gewichtungsrichtlinien (gewichteter Cache)
Beispiel: Cache mit TTL und Größenbeschränkung
use moka::sync::Cache;use std::time::Duration;
fn main() { // Cache für 1000 Elemente mit TTL von 10 Minuten erstellen let cache: Cache<String, String> = Cache::builder() .max_capacity(1000) .time_to_live(Duration::from_secs(600)) .build();
// Einfügen und Abrufen cache.insert("key1".to_string(), "value1".to_string()); if let Some(v) = cache.get("key1") { println!("Wert: {}", v); }}Asynchrone Variante (moka::future::Cache)
use moka::future::Cache;
#[tokio::main]async fn main() { let cache: Cache<u64, String> = Cache::new(10_000);
// Asynchrones Einfügen cache.insert(42, "Hello async".to_string()).await;
// Asynchrones Abrufen if let Some(val) = cache.get(&42).await { println!("{}", val); }}3. Deklaratives Caching: Crate <
Auch in der Bibliothek
Geolokalisierung und Karten in PHP: Überblick über Bibliotheken und Werkzeuge
E-Mail-Versand in C++: libcurl und SMTP-Clients
Reaktive Programmierung in TypeScript: Bibliothek RxJS