Einführung in das Caching in Rust
Caching ist eines der wichtigsten Werkzeuge zur Leistungssteigerung von Anwendungen in Rust. Unabhängig davon, ob Sie einen hochbelasteten Webserver, eine Datenbank oder eine Desktop-Anwendung erstellen, ermöglicht ein durchdachtes Caching, die Antwortzeit zu verkürzen, die Belastung externer Ressourcen zu reduzieren und die Speichernutzung zu optimieren. In diesem Artikel betrachten wir drei grundlegende Ansätze zum Caching im Rust-Ökosystem: die Verwendung externer Systeme (Redis und Memcached) sowie integrierte Lösungen wie lru-rs und moka. Sie erfahren, wann welches Werkzeug die richtige Wahl ist, und erhalten fertige Codebeispiele.
Externe Caching-Systeme: Redis und Memcached
Caching mit Redis in Rust
Redis ist ein beliebter In-Memory-Datenspeicher, der verschiedene Datenstrukturen (Strings, Listen, Mengen, Hash-Tabellen) unterstützt. Für die Arbeit mit Redis in Rust wird die Crate redis (oder redis-rs) verwendet.
Wir fügen die Abhängigkeit in Cargo.toml hinzu:
[dependencies]redis = { version = "0.25", features = ["tokio-comp"] }tokio = { version = "1", features = ["full"] }serde = { version = "1", features = ["derive"] }serde_json = "1"Beispiel für die Verbindung und das grundlegende Caching mit Redis:
use redis::AsyncCommands;use serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize)]struct User { id: u32, name: String, email: String,}
#[tokio::main]async fn main() -> redis::RedisResult<()> { let client = redis::Client::open("redis://127.0.0.1:6379/")?; let mut conn = client.get_multiplexed_async_connection().await?;
// Objekt im Cache speichern (in JSON serialisieren) let user = User { id: 1, name: "Alexej".into(), email: "alex@example.com".into(), }; let json = serde_json::to_string(&user).unwrap(); conn.set_ex("user:1", json, 3600).await?; // TTL = 1 Stunde
// Aus dem Cache lesen let cached: String = conn.get("user:1").await?; let user_cached: User = serde_json::from_str(&cached).unwrap(); println!("Benutzer erhalten: {:?}", user_cached);
Ok(())}Vorteile von Redis: Unterstützung komplexer Datenstrukturen, TTL, pub/sub, Replikation, Clustering. Nachteile: Erfordert einen separaten Server, Netzwerkverzögerungen.
Caching mit Memcached in Rust
Memcached ist ein leichterer und einfacherer In-Memory-Speicher, der auf die Speicherung von Schlüssel-Wert-Paaren ausgerichtet ist. Für Rust wird die Crate memcache verwendet.
Wir fügen in Cargo.toml hinzu:
[dependencies]memcache = "0.19"tokio = { version = "1", features = ["full"] }Beispiel für die Arbeit mit Memcached:
use memcache::Client;
#[tokio::main]async fn main() -> memcache::MemcacheResult<()> { let client = Client::connect("memcache://127.0.0.1:11211")?;
// Schreiben mit TTL (in Sekunden) client.set("greeting", "Hallo, Welt!", 300)?;
// Lesen let value: Option<String> = client.get("greeting")?; if let Some(msg) = value { println!("Aus dem Cache: {}", msg); }
// Zähler erhöhen client.set("counter", "10", 0)?; client.increment("counter", 5)?; let counter: Option<u64> = client.get("counter")?; println!("Zähler: {:?}", counter);
Ok(())}Vorteile von Memcached: Einfachheit, hohe Geschwindigkeit, minimaler Speicherverbrauch. Nachteile: Keine komplexen Datenstrukturen, nur Speicherung von Strings/Bytes.
Integrierte Lösungen für Caching in Rust
Bibliothek lru-rs (LRU-Cache)
Die Crate lru implementiert den klassischen Verdrängungsalgorithmus Least Recently Used (LRU). Ideal für das Caching im Arbeitsspeicher