Caché en Rust: Redis, Memcached y soluciones integradas
El caché es uno de los mecanismos clave para optimizar el rendimiento de aplicaciones web y sistemas de alta carga. En el ecosistema de Rust hay varias bibliotecas potentes disponibles para organizar el caché: desde soluciones distribuidas (Redis, Memcached) hasta cachés ligeros en memoria (moka, cached). En este artículo analizaremos cada una de ellas en detalle, proporcionaremos ejemplos de código y compararemos su rendimiento.
1. Redis a través del crate redis-rs
redis-rs es el cliente principal y más maduro para Redis en Rust. Soporta todas las funcionalidades principales: strings, listas, hashes, pub/sub, transacciones y clustering.
Instalación
[dependencies]redis = { version = "0.25", features = ["tokio-comp"] }tokio = { version = "1", features = ["full"] }Ejemplo: caché básico con Redis
use redis::{AsyncCommands, Client};use std::time::Duration;
#[tokio::main]async fn main() -> redis::RedisResult<()> { let client = Client::open("redis://127.0.0.1:6379/")?; let mut con = client.get_multiplexed_async_connection().await?;
// Establecemos una clave con TTL de 60 segundos con.set_ex("user:1:profile", "{\\"name\\":\\"Alice\\"}", 60).await?;
// Leemos el valor let data: Option<String> = con.get("user:1:profile").await?; println!("Obtenido: {:?}", data);
// Incremento de contador let count: i64 = con.incr("page_views", 1).await?; println!("Vistas de página: {}", count);
Ok(())}Características importantes:
- Asincronía: redis-rs soporta tanto modo síncrono como asíncrono (tokio/async-std).
- Pipeline: agrupación de comandos para reducir la latencia.
- Clustering: soporte para Redis Cluster a través de
redis::cluster.
2. Memcached a través del crate memcached-rs
Memcached es un almacén distribuido ligero de tipo clave-valor. Para Rust existe el crate memcached-rs (o memcache).
Ejemplo de uso
use memcache::Client;
fn main() -> memcache::MemcacheResult<()> { let client = Client::connect("memcache://127.0.0.1:11211")?;
// Escritura con TTL client.set("session:token_abc", "user_data", 30)?;
// Lectura let value: Option<String> = client.get("session:token_abc")?; println!("Desde Memcached: {:?}", value);
// Eliminación client.delete("session:token_abc")?;
Ok(())}Cuándo elegir Memcached en lugar de Redis:
- Si solo se necesita un caché simple (clave-valor).
- Si la latencia mínima es importante (Memcached es más rápido que Redis para operaciones simples).
- Si no se necesitan las estructuras de datos de Redis (listas, hashes, sets).
3. Cachés integrados en memoria: moka y cached
Para el caché dentro de un solo proceso (sin servidor externo), los crates moka y cached son ideales.
3.1 Moka — caché de alto rendimiento
moka es un caché asíncrono, seguro para subprocesos, con soporte para TTL, tamaño máximo y política de desalojo (LRU, LFU).
use moka::future::Cache;use std::time::Duration;
#[tokio::main]async fn main() { let cache: Cache<String, String> = Cache::builder() .max_capacity(10_000) // máximo 10 000 entradas .time_to_live(Duration::from_secs(300)) // TTL 5 minutos .build();
// Inserción cache.insert("key1".to_string(), "value1".to_string()).await;
// Obtención if let Some(value) = cache.get(&"key1".to_string()).await { p También en la biblioteca
PM2: Monitoreo y gestión de aplicaciones JavaScript
Trabajo con CSV en Go (Golang): guía completa de encoding/csv
Caché en Rust: Redis, Memcached y soluciones integradas
Integración de métricas de Prometheus en C++: biblioteca prometheus-cpp
Aprendizaje automático en Java: revisión de las principales bibliotecas para desarrollo