Caching in Rust: Redis, Memcached und integrierte Lösungen
Caching ist einer der Schlüsselmechanismen zur Optimierung der Leistung von Webanwendungen und hochbelasteten Systemen. Im Rust-Ökosystem stehen mehrere leistungsstarke Bibliotheken zur Organisation von Caching zur Verfügung: von verteilten Lösungen (Redis, Memcached) bis hin zu leichtgewichtigen In-Memory-Caches (moka, cached). In diesem Artikel werden wir jede einzelne davon im Detail analysieren, Codebeispiele geben und ihre Leistung vergleichen.
1. Redis über die Crate redis-rs
redis-rs ist der wichtigste und ausgereifteste Client für Redis in Rust. Er unterstützt alle grundlegenden Funktionen: Strings, Listen, Hashes, Pub/Sub, Transaktionen und Clustering.
Installation
[dependencies]redis = { version = "0.25", features = ["tokio-comp"] }tokio = { version = "1", features = ["full"] }Beispiel: Basis-Caching mit Redis
use redis::{AsyncCommands, Client};use std::time::Duration;
#[tokio::main]async fn main() -> redis::RedisResult<()> { let client = Client::open("redis://127.0.0.1:6379/")?; let mut con = client.get_multiplexed_async_connection().await?;
// Setzen eines Schlüssels mit TTL von 60 Sekunden con.set_ex("user:1:profile", "{\\"name\\":\\"Alice\\"}", 60).await?;
// Lesen des Wertes let data: Option<String> = con.get("user:1:profile").await?; println!("Erhalten: {:?}", data);
// Inkrementieren eines Zählers let count: i64 = con.incr("page_views", 1).await?; println!("Seitenaufrufe: {}", count);
Ok(())}Wichtige Merkmale:
- Asynchronität: redis-rs unterstützt sowohl synchrone als auch asynchrone (tokio/async-std) Modi.
- Pipeline: Bündelung von Befehlen zur Reduzierung der Latenz.
- Clustering: Unterstützung für Redis Cluster über
redis::cluster.
2. Memcached über die Crate memcached-rs
Memcached ist ein leichtgewichtiger verteilter Schlüssel-Wert-Speicher. Für Rust gibt es die Crate memcached-rs (oder memcache).
Anwendungsbeispiel
use memcache::Client;
fn main() -> memcache::MemcacheResult<()> { let client = Client::connect("memcache://127.0.0.1:11211")?;
// Schreiben mit TTL client.set("session:token_abc", "user_data", 30)?;
// Lesen let value: Option<String> = client.get("session:token_abc")?; println!("Aus Memcached: {:?}", value);
// Löschen client.delete("session:token_abc")?;
Ok(())}Wann Memcached statt Redis wählen:
- Wenn nur einfaches Caching (Schlüssel-Wert) benötigt wird.
- Wenn eine minimale Verzögerung wichtig ist (Memcached ist bei einfachen Operationen schneller als Redis).
- Wenn keine Redis-Datenstrukturen (Listen, Hashes, Sets) benötigt werden.
3. Integrierte In-Memory-Caches: moka und cached
Für das Caching innerhalb eines einzelnen Prozesses (ohne externen Server) eignen sich die Crates moka und cached hervorragend.
3.1 Moka — Hochleistungs-Cache
moka ist ein asynchroner, threadsicherer Cache mit Unterstützung für TTL, maximale Größe und Verdrängungsrichtlinien (LRU, LFU).
use moka::future::Cache;use std::time::Duration;
#[tokio::main]async fn main() { let cache: Cache<String, String> = Cache::builder() .max_capacity(10_000) // maximal 10.000 Einträge .time_to_live(Duration::from_secs(300)) // TTL 5 Minuten .build();
// Einfügen cache.insert("key1".to_string(), "value1".to_string()).await;
// Abrufen if let Some(value) = cache.get(&"key1".to_string()).await { p Auch in der Bibliothek
Maschinelles Lernen mit Swift: Bibliotheken für iOS/macOS
Drogon C++ Framework: Vollständiges Tutorial mit Beispielen
Aufgabenwarteschlangen in C# (.NET): System.Threading.Channels, Hangfire und RabbitMQ