Mise en cache en Rust : Redis et autres outils pour accélérer les applications
La mise en cache est l'un des mécanismes clés d'optimisation des performances. En Rust, avec son accent sur la vitesse et la sécurité, le choix du bon outil de mise en cache peut apporter un gain significatif. Dans cet article, nous examinerons les bibliothèques populaires : redis-rs (avec pool de connexions), moka (cache en mémoire) et cached (décorateurs de fonctions).
1. Redis : cache externe avec redis-rs et deadpool
Redis est le cache externe le plus courant. Pour l'utiliser en Rust, on utilise la crate redis-rs. Pour les charges de production, il est recommandé d'utiliser un pool de connexions via deadpool-redis.
Installation
[dependencies]redis = { version = "0.25", features = ["tokio-comp"] }deadpool-redis = "0.14"tokio = { version = "1", features = ["full"] }serde = { version = "1", features = ["derive"] }serde_json = "1"Exemple : opérations de base avec Redis
use redis::AsyncCommands;use deadpool_redis::{Config, Runtime};
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { // Création d'un pool de connexions let cfg = Config::from_url("redis://127.0.0.1:6379"); let pool = cfg.create_pool(Some(Runtime::Tokio1))?;
// Obtention d'une connexion depuis le pool let mut conn = pool.get().await?;
// Définition d'une valeur avec TTL de 60 secondes conn.set_ex("user:42", "{\\"name\\":\\"Alice\\",\\"role\\":\\"admin\\"}", 60).await?;
// Lecture let value: String = conn.get("user:42").await?; println!("Obtenu : {}", value);
// Suppression conn.del("user:42").await?;
Ok(())}Sérialisation des structures
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]struct User { id: u64, name: String, email: String,}
async fn cache_user(conn: &mut redis::aio::Connection, user: &User) -> redis::RedisResult<()> { let key = format!("user:{}", user.id); let json = serde_json::to_string(user).unwrap(); conn.set_ex(key, json, 300).await}
async fn get_cached_user(conn: &mut redis::aio::Connection, id: u64) -> Option<User> { let key = format!("user:{}", id); let result: Option<String> = conn.get(key).await.ok()?; result.and_then(|json| serde_json::from_str(&json).ok())}2. Moka : cache en mémoire rapide
Moka est un cache en mémoire haute performance, inspiré de Caffeine (Java). Il prend en charge le TTL, la limitation de taille et la mise à jour asynchrone.
Installation
[dependencies]moka = { version = "0.12", features = ["future"] }tokio = { version = "1", features = ["full"] }Exemple : cache avec limite de 1000 éléments et TTL de 10 minutes
use moka::future::Cache;use std::time::Duration;
#[tokio::main]async fn main() { let cache: Cache<String, String> = Cache::builder() .max_capacity(1000) .time_to_live(Duration::from_secs(600)) .build();
// Insertion cache.insert("key1".to_string(), "value1".to_string()).await;
// Lecture if let Some(v) = cache.get(&"key1".to_string()).await { println!("Trouvé : {}", v); }
// Suppression cache.invalidate(&"key1".to_string()).await;}Mise à jour automatique après expiration du TTL
let cache: Cache<String, String> = Cache::builder() .time_to_live(Duration::from_secs(60)) .time_to_idle(Duration::from_secs(30)) // réinitialisation du TTL à la lecture .build();3. Cached : décorateurs pour fonctions
La crate cached permet de mettre en cache les résultats de fonctions à l'aide d'attributs. Elle prend en charge différents backends, y compris Redis et la mémoire.
Installation
[dependencies]cach Aussi dans la bibliothèque
Autorisation et authentification en PHP : Guide complet avec exemples
Travailler avec CSV en JavaScript (Node.js) : bibliothèques, parsing et génération de données
Surveillance des applications C# (.NET) avec OpenTelemetry et Prometheus
Envoi de SMS en Kotlin : Bibliothèque API smslib4k
Sinon pour JavaScript (Node.js) : guide complet avec exemples