Redis & Cache

👨‍🍳 Chef

Cache y datos en memoria

Redis guarda datos en RAM para acceso ultra-rápido.


Casos de uso

UsoPor qué Redis
CacheEvitar queries lentas
SessionsEstado de usuario
Rate limitingContar requests
QueuesJobs en background

Instalación

# macOS
brew install redis
brew services start redis

# Docker
docker run -d --name redis -p 6379:6379 redis:7

Comandos básicos

redis-cli

# Strings
SET user:1 "Ana"
GET user:1
SETEX token:abc 3600 "data"  # Expira en 1 hora

# Contadores
INCR page:views
INCRBY api:calls 10

# Hashes
HSET user:1 name "Ana" email "ana@email.com"
HGETALL user:1

Con Node.js

import { Redis } from 'ioredis'

const redis = new Redis()

// Cache
async function getUser(id: string) {
  const cached = await redis.get(`user:${id}`)
  if (cached) return JSON.parse(cached)

  const user = await db.users.findUnique({ where: { id } })
  await redis.setex(`user:${id}`, 3600, JSON.stringify(user))
  return user
}

🏦 Caso Fintech: Rate Limiting para APIs

Las APIs financieras son objetivo de ataques de fuerza bruta y abuso. Redis es perfecto para implementar rate limiting robusto:

import { Redis } from 'ioredis'

const redis = new Redis()

// Sliding window rate limiter
async function checkRateLimit(userId: string, action: string): Promise<boolean> {
  const key = `ratelimit:${action}:${userId}`
  const now = Date.now()
  const windowMs = 60000 // 1 minuto

  // Límites por acción (más estrictos para operaciones sensibles)
  const limits: Record<string, number> = {
    'transfer': 5,      // 5 transferencias/min
    'login': 10,        // 10 intentos/min
    'api_call': 100,    // 100 llamadas/min
    'otp_request': 3,   // 3 códigos OTP/min
  }

  const limit = limits[action] || 60

  // Sliding window con sorted sets
  await redis.zremrangebyscore(key, 0, now - windowMs)
  const count = await redis.zcard(key)

  if (count >= limit) {
    // Log intento bloqueado para análisis de seguridad
    await redis.lpush('security:blocked_requests', JSON.stringify({
      userId, action, timestamp: now, count
    }))
    return false // Bloqueado
  }

  await redis.zadd(key, now, `${now}`)
  await redis.expire(key, 60)
  return true // Permitido
}

// Middleware para Express/Fastify
async function rateLimitMiddleware(req, res, next) {
  const userId = req.user?.id || req.ip
  const allowed = await checkRateLimit(userId, 'api_call')

  if (!allowed) {
    // Headers estándar de rate limiting
    res.set('Retry-After', '60')
    res.set('X-RateLimit-Limit', '100')
    res.set('X-RateLimit-Remaining', '0')
    return res.status(429).json({ error: 'Too many requests' })
  }

  next()
}

Estrategias según operación

OperaciónLímiteVentanaAcción si excede
Login fallido515 minBloqueo temporal + alerta
Transferencia101 horaRequiere MFA adicional
Consulta saldo1001 minSolo rate limit
OTP request35 minBloqueo + notificación

💡 Rate limiting con Redis protege contra ataques de fuerza bruta y credential stuffing, cumpliendo con requisitos de seguridad de PCI DSS.


Practica

Cache con Redis