Caché en TypeScript: Redis, Memcached y soluciones en memoria
El almacenamiento en caché es uno de los mecanismos clave para optimizar el rendimiento de las aplicaciones web. En el ecosistema de TypeScript y Node.js, existen varios enfoques probados para organizar el caché: desde soluciones simples en memoria hasta sistemas distribuidos basados en Redis y Memcached. En este artículo, analizaremos en detalle las bibliotecas populares, su instalación, configuración y ejemplos de uso.
¿Por qué es necesario el caché?
El almacenamiento en caché permite reducir el tiempo de respuesta del servidor, disminuir la carga en bases de datos y API externas, y mejorar la experiencia del usuario. Los principales casos de uso son:
- Guardar resultados de cálculos costosos
- Almacenar en caché respuestas de API externas
- Almacenar sesiones de usuarios
- Almacenar en caché fragmentos de páginas HTML
1. ioredis — cliente avanzado para Redis
ioredis es la biblioteca más popular para trabajar con Redis en Node.js y TypeScript. Soporta clustering, Pub/Sub, transacciones y reconexión automática.
Instalación:
npm install ioredisnpm install @types/ioredis --save-devUso básico con TypeScript:
import Redis from 'ioredis';
// Conexión a Redis localconst redis = new Redis({ host: 'localhost', port: 6379, retryStrategy: (times) => Math.min(times * 50, 2000)});
// Función para almacenar datos en cachéasync function getCachedData(key: string): Promise<string | null> { const cached = await redis.get(key); if (cached) { console.log('Datos desde caché'); return cached; } // Simulación de obtención de datos desde BD const data = `Data for ${key} at ${new Date().toISOString()}`; await redis.setex(key, 3600, data); // TTL 1 hora return data;}
// Ejemplo de uso(async () => { const result = await getCachedData('user:123'); console.log(result);})();Almacenamiento en caché de objetos:
interface User { id: number; name: string; email: string;}
async function cacheUser(user: User): Promise<void> { await redis.setex(`user:${user.id}`, 3600, JSON.stringify(user));}
async function getUserFromCache(id: number): Promise<User | null> { const cached = await redis.get(`user:${id}`); return cached ? JSON.parse(cached) : null;}2. node-cache — caché simple en memoria
node-cache es una biblioteca ligera para almacenar datos en la memoria RAM del proceso Node.js. Ideal para proyectos pequeños o prototipos donde no se requiere caché distribuido.
Instalación:
npm install node-cachenpm install @types/node-cache --save-devEjemplo de uso:
import NodeCache from 'node-cache';
const myCache = new NodeCache({ stdTTL: 600, // tiempo de vida por defecto (seg) checkperiod: 120 // período de verificación de claves caducadas});
// Guardar y obtener datosmyCache.set('key1', { value: 42 });const value = myCache.get('key1');console.log(value); // { value: 42 }
// Verificar existencia de claveif (myCache.has('key1')) { console.log('La clave existe');}
// Eliminar por clavemyCache.del('key1');
// Obtener estadísticasconst stats = myCache.getStats();console.log(`Claves en caché: ${stats.keys}`);3. lru-cache — caché con política LRU
lru-cache es una implementación de caché con el algoritmo de expulsión Least Recently Used. Limita la cantidad de registros almacenados, eliminando automáticamente los más antiguos. Ideal para caché con tamaño fijo.
Instalación:
npm install lru-cache