Caching in Rust: Redis, Memcached und integrierte Lösungen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

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 <

Empfehlungen