Cache em Rust: Redis e outras ferramentas para acelerar aplicações
Cache é um dos principais mecanismos de otimização de desempenho. Em Rust, com seu foco em velocidade e segurança, escolher a ferramenta certa para cache pode proporcionar um ganho significativo. Neste artigo, veremos bibliotecas populares: redis-rs (com pool de conexões), moka (cache in-memory) e cached (decoradores de funções).
1. Redis: cache externo com redis-rs e deadpool
Redis é o cache externo mais comum. Para trabalhar com ele em Rust, usa-se a crate redis-rs. Para cargas de produção, recomenda-se conectar um pool de conexões via deadpool-redis.
Instalação
[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"Exemplo: operação básica com Redis
use redis::AsyncCommands;use deadpool_redis::{Config, Runtime};
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { // Criando o pool de conexões let cfg = Config::from_url("redis://127.0.0.1:6379"); let pool = cfg.create_pool(Some(Runtime::Tokio1))?;
// Obtendo uma conexão do pool let mut conn = pool.get().await?;
// Definindo valor com TTL de 60 segundos conn.set_ex("user:42", "{\\"name\\":\\"Alice\\",\\"role\\":\\"admin\\"}", 60).await?;
// Lendo let value: String = conn.get("user:42").await?; println!("Obtido: {}", value);
// Removendo conn.del("user:42").await?;
Ok(())}Serialização de estruturas
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 in-memory rápido
Moka é um cache in-memory de alto desempenho, inspirado no Caffeine (Java). Suporta TTL, limite de tamanho e atualização assíncrona.
Instalação
[dependencies]moka = { version = "0.12", features = ["future"] }tokio = { version = "1", features = ["full"] }Exemplo: cache com limite de 1000 elementos e TTL de 10 minutos
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();
// Inserção cache.insert("key1".to_string(), "value1".to_string()).await;
// Leitura if let Some(v) = cache.get(&"key1".to_string()).await { println!("Encontrado: {}", v); }
// Remoção cache.invalidate(&"key1".to_string()).await;}Atualização automática após expiração do TTL
let cache: Cache<String, String> = Cache::builder() .time_to_live(Duration::from_secs(60)) .time_to_idle(Duration::from_secs(30)) // reset TTL na leitura .build();3. Cached: decoradores para funções
A crate cached permite armazenar em cache os resultados de funções usando atributos. Suporta vários backends, incluindo Redis e in-memory.
Instalação
[dependencies]cach Também na biblioteca
PM2 para JavaScript (Node.js): guia completo com exemplos práticos
ORM para JavaScript (Node.js): comparação entre Sequelize, TypeORM, Prisma
Biblioteca WebSocket para C# (.NET): SignalR e alternativas
Cache em TypeScript: Redis, node-cache e outras ferramentas