Mise en cache en Rust : Redis, Memcached et solutions intégrées

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

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                    

Recommendations