Introduction à la mise en cache en Rust
La mise en cache est l'un des outils clés pour améliorer les performances des applications en Rust. Que vous créiez un serveur web à forte charge, une base de données ou une application de bureau, une mise en cache judicieuse permet de réduire le temps de réponse, de diminuer la charge sur les ressources externes et d'optimiser l'utilisation de la mémoire. Dans cet article, nous aborderons trois approches principales de la mise en cache dans l'écosystème Rust : l'utilisation de systèmes externes (Redis et Memcached) et les solutions intégrées comme lru-rs et moka. Vous apprendrez quel outil choisir selon le cas et obtiendrez des exemples de code prêts à l'emploi.
Systèmes de cache externes : Redis et Memcached
Mise en cache avec Redis en Rust
Redis est un magasin de données in-memory populaire prenant en charge diverses structures de données (chaînes, listes, ensembles, tables de hachage). Pour travailler avec Redis en Rust, on utilise la crate redis (ou redis-rs).
Ajoutons la dépendance dans Cargo.toml :
[dependencies]redis = { version = "0.25", features = ["tokio-comp"] }tokio = { version = "1", features = ["full"] }serde = { version = "1", features = ["derive"] }serde_json = "1"Exemple de connexion et de mise en cache de base avec 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?;
// Sauvegarder l'objet dans le cache (sérialisation en JSON) let user = User { id: 1, name: "Alexeï".into(), email: "alex@example.com".into(), }; let json = serde_json::to_string(&user).unwrap(); conn.set_ex("user:1", json, 3600).await?; // TTL = 1 heure
// Lire depuis le cache let cached: String = conn.get("user:1").await?; let user_cached: User = serde_json::from_str(&cached).unwrap(); println!("Utilisateur récupéré : {:?}", user_cached);
Ok(())}Avantages de Redis : prise en charge de structures de données complexes, TTL, pub/sub, réplication, clustering. Inconvénients : nécessite un serveur dédié, latences réseau.
Mise en cache avec Memcached en Rust
Memcached est un magasin in-memory plus léger et plus simple, axé sur le stockage de paires clé-valeur. Pour Rust, on utilise la crate memcache.
Ajoutons dans Cargo.toml :
[dependencies]memcache = "0.19"tokio = { version = "1", features = ["full"] }Exemple de travail avec Memcached :
use memcache::Client;
#[tokio::main]async fn main() -> memcache::MemcacheResult<()> { let client = Client::connect("memcache://127.0.0.1:11211")?;
// Écriture avec TTL (en secondes) client.set("greeting", "Bonjour le monde !", 300)?;
// Lecture let value: Option<String> = client.get("greeting")?; if let Some(msg) = value { println!("Depuis le cache : {}", msg); }
// Incrémentation d'un compteur client.set("counter", "10", 0)?; client.increment("counter", 5)?; let counter: Option<u64> = client.get("counter")?; println!("Compteur : {:?}", counter);
Ok(())}Avantages de Memcached : simplicité, haute vitesse, consommation mémoire minimale. Inconvénients : pas de structures de données complexes, stockage uniquement de chaînes/octets.
Solutions intégrées pour la mise en cache en Rust
Bibliothèque lru-rs (cache LRU)
La crate lru implémente l'algorithme classique d'éviction Least Recently Used (LRU). Idéale pour la mise en cache en mémoire