Módulo 2 · Bases de datos

Lección 12 — NoSQL

Redis, MongoDB y motores de búsqueda: qué sacrificas con cada uno y cuándo compensa.

Publicada
En esta lección
  1. Ejercicio 1 — Caché de disponibilidad
  2. Ejercicio 2 — Rate limit atómico
  3. Ejercicio 3 — Lock distribuido de tarjeta regalo
  4. Ejercicio 4 — JSONB con GIN
  5. Ejercicio 5 — Stampede simulado
  6. Entrega

Redis instalado desde la 00 (redis-server); pip install redis en tu venv. No mires solutions.md hasta entregar.

Ejercicio 1 — Caché de disponibilidad

  1. Envuelve tu consulta de disponibilidad (09) con setex/get de Redis (TTL 10s, clave avail:{event_id}). Mide con \timing/queries: primera llamada vs segunda.
  2. Reserva un asiento y comprueba que la caché sirve datos viejos durante ≤10s. ¿Es aceptable para tu negocio? ¿Qué TTL elegirías y por qué?
  3. Añade invalidación: tras una reserva confirmada, DELETE de la clave. ¿Qué problema resuelve? ¿Cuál introduce (stampede)?

Ejercicio 2 — Rate limit atómico

  1. Implementa el límite "20 requests por IP por minuto" con INCR + EX 60 sobre un middleware o vista de prueba.
  2. Demuéstralo: 25 requests desde la misma IP → la 21 recibe 429.
  3. Discute: ¿por qué GET contador, si < 20: SET contador+1 (sin atomicidad) deja pasar 35 requests bajo concurrencia?

Ejercicio 3 — Lock distribuido de tarjeta regalo

  1. Con r.lock("gift:TEST", timeout=5, blocking_timeout=2), dos threads intentan canjear la misma tarjeta (sleep de 0.2s dentro). ¿Qué observa el perdedor?
  2. Quita el timeout=5 del lock y mata el proceso dentro del with (Ctrl+C en el thread lo complica; simula con lock.release = crash). ¿Qué pasa con la tarjeta? ¿Por qué el TTL es lo que evita el bloqueo eterno?
  3. Conecta con la 10: dentro del lock, ¿qué más necesitas para que el canje sea atómico frente a la BD?

Ejercicio 4 — JSONB con GIN

  1. Añade metadata JSONB DEFAULT '{}' a tu modelo Event (migración de la 11, ¡segura!) y el índice GIN.
  2. Inserta 3 eventos con metadata distintos ({"venue_type": "stadium"}, etc.) y consulta con @>. Verifica en EXPLAIN que usa el índice GIN.
  3. Reflexiona: de esos campos, ¿cuál merecería columna real y cuál sigue en JSONB?

Ejercicio 5 — Stampede simulado

  1. Vacía la caché y lanza 50 threads que piden disponibilidad a la vez. Cuenta len(connection.queries): ¿cuántas golpearon la BD?
  2. Arreglo simple: TTL con jitter (10 + random(0,5)). Repite y compara. (El lock de regeneración lo formalizamos con Celery en la 29.)

Entrega

Pega números y código recortado. Con esto cierras el módulo de datos entero; después Lección 13 — REST bien hecho (Módulo de APIs).