Caché en Rust: Redis, Memcached y soluciones integradas

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Caché en Rust: Redis y otras soluciones eficientes



En el desarrollo moderno de alto rendimiento con Rust, el caché juega un papel clave. Permite reducir la carga en las bases de datos, acelerar las respuestas de API y optimizar el trabajo con cálculos costosos. En este artículo, revisaremos las principales bibliotecas para caché en el ecosistema de Rust: desde el potente Redis hasta soluciones ligeras en memoria.



1. Redis a través del crate redis-rs



redis-rs es la biblioteca principal y más madura para trabajar con Redis en Rust. Soporta operaciones asíncronas (a través de tokio o async-std), clustering, pub/sub y todos los tipos de datos populares de Redis.



Instalación

[dependencies]redis = { version = "0.25", features = ["tokio-comp"] }tokio = { version = "1", features = ["full"] }


Ejemplo básico: caché de cadenas

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?;

// Establecemos caché con TTL de 60 segundos let _: () = con.set_ex("user:123", "{\\"name\\":\\"Alice\\"}", 60).await?;

// Obtenemos el valor let cached: String = con.get("user:123").await?; println!("Datos en caché: {}", cached);

// Verificamos la existencia de la clave let exists: bool = con.exists("user:123").await?; println!("Clave existe: {}", exists);

Ok(())}


Serialización de estructuras complejas

Para almacenar en caché estructuras de datos, use serde junto con 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. Caché en memoria: crate moka



Moka es una biblioteca de alto rendimiento para caché en memoria, inspirada en Caffeine (Java). Es ideal para escenarios donde no se requiere un servidor externo y se necesita la máxima velocidad.



Características de moka:

  • Evicción automática por tiempo (TTL, TTI) y por tamaño
  • Sincronización asíncrona (background refresh)
  • Seguridad para uso multihilo (Arc + RwLock)
  • Soporte para políticas de peso (weighted cache)


Ejemplo: caché con TTL y límite de tamaño

use moka::sync::Cache;use std::time::Duration;

fn main() { // Creamos un caché de 1000 elementos con TTL de 10 minutos let cache: Cache<String, String> = Cache::builder() .max_capacity(1000) .time_to_live(Duration::from_secs(600)) .build();

// Inserción y obtención cache.insert("key1".to_string(), "value1".to_string()); if let Some(v) = cache.get("key1") { println!("Valor: {}", v); }}


Variante asíncrona (moka::future::Cache)

use moka::future::Cache;

#[tokio::main]async fn main() { let cache: Cache<u64, String> = Cache::new(10_000);

// Inserción asíncrona cache.insert(42, "Hello async".to_string()).await;

// Obtención asíncrona if let Some(val) = cache.get(&42).await { println!("{}", val); }}


3. Caché declarativo: crate <

Recommendations