Skip to content

📗 Clase 3 — Caché en memoria con ElastiCache

Curso AWS (emulador Floci) · 2026-08-08 · Carpeta: 02-Ejercicios/clase-03-elasticache ⬅️ Volver al índice de clases

🎯 Qué aprendí

  • Por qué una caché no es una base de datos pequeña, y qué cambia esa diferencia.
  • Levantar un Redis gestionado y hablarle con su propio protocolo.
  • La caducidad como parte del diseño, no como limpieza posterior.
  • Las cinco estructuras de Redis, y por qué se usa para colas y rankings, no solo para caché.
  • Los patrones reales: cache-aside, contadores, sesiones, listas de espera.
  • Que en el emulador el endpoint no es el que dice la API — y por qué.

📖 PARTE TEÓRICA

⚡ 1. Una caché no es una base de datos pequeña

Es la confusión más común al empezar. Las diferencias son de fondo:

Base de datos (RDS)Caché (ElastiCache)
Dónde viveDiscoMemoria
Si se apagaLos datos siguen ahíSe pierde todo
Los datos sonLa verdadUna copia de la verdad
DuranHasta que los borresLo que dure su caducidad
Responde enMilisegundosMicrosegundos
Preguntas complejasSí, con SQLNo: se busca por clave

💡 La regla que lo resume: si perder un dato de la caché rompe algo, ese dato no debía estar solo ahí. La caché acelera; no custodia.

🔁 2. El patrón que justifica su existencia: cache-aside

   La aplicacion pregunta por el paciente 12345601


            ┌───────────────┐
            │  ¿esta en la  │
            │    cache?     │
            └───┬───────┬───┘
           SI   │       │   NO
                ▼       ▼
        devolver    consultar la BASE DE DATOS
        (microseg)          │

                    guardar en cache con caducidad


                        devolver

La primera consulta paga el precio completo. Las siguientes, mientras no caduque, salen de memoria. En una pantalla que consultan cien personas por minuto, la diferencia es enorme.

🧪 Pregunta de entrevista: ¿qué pasa si el dato cambia en la base y la caché aún tiene el viejo? Se sirve un dato obsoleto hasta que caduque. Por eso el TTL es una decisión de negocio: cuánta desactualización tolera esa pantalla.

⏳ 3. La caducidad es parte del diseño

En una base de datos, un dato vive hasta que lo borras. En una caché, lo normal es que muera solo:

bash
SET sesion:abc "token-123"
EXPIRE sesion:abc 300      # se borra sola en 5 minutos
TTL sesion:abc             # 300, 299, 298... y desaparece

Sin caducidad, la memoria se llena y el servidor empieza a expulsar claves o a rechazar escrituras. Una clave sin TTL debería ser la excepción, no la costumbre.

🧩 4. Cinco estructuras, no solo texto

Aquí está la razón de que Redis se use para mucho más que cachear:

EstructuraComandos típicosPara qué se usa de verdad
CadenaSET, GET, INCRCaché simple, contadores atómicos
ListaRPUSH, LPOP, LRANGEColas de trabajo, últimos N elementos
ConjuntoSADD, SISMEMBERPertenencia sin duplicados (¿ya votó?)
Conjunto ordenadoZADD, ZRANGERankings, colas por prioridad
HashHSET, HGETALLUn registro con campos, sin serializar a JSON

💡 INCR es atómico: dos procesos incrementando a la vez nunca pierden una cuenta. Eso en SQL requeriría una transacción; aquí es el comportamiento por defecto.

🔌 5. El endpoint: lo que dice la API no es donde te conectas

Este detalle desconcierta y conviene entenderlo:

bash
aws elasticache describe-replication-groups --replication-group-id demo-cache \
  --query 'ReplicationGroups[0].ConfigurationEndpoint'
# { "Address": "localhost", "Port": 6379 }

Dice localhost porque es la vista del emulador desde dentro de sí mismo. Floci no publica el contenedor de Valkey: corre un proxy en sus propios puertos (6379-6399) que valida la firma IAM y reenvía al motor.

   tu cliente ──▶ FLOCI (proxy RESP, valida SigV4) ──▶ contenedor valkey

                  el host es el de Floci, no el de la cache

⚠️ Lo aprovechable de la respuesta es el puerto, no la dirección. Si trabajas fuera de Docker, conectas a localhost:<puerto>; si estás en otro contenedor, al host de Floci.

⚠️ 6. Lo que el emulador no hace

Las instantáneas no existen, igual que en RDS:

An error occurred (UnsupportedOperation) when calling the CreateSnapshot
operation: Operation CreateSnapshot is not supported.

Y create-cache-cluster rechaza Redis:

Engine must be 'memcached'. For Redis/Valkey use CreateReplicationGroup.

📝 Eso último no es un fallo: es lo correcto en AWS moderno. Los tutoriales antiguos siguen usando create-cache-cluster para Redis, y por eso mucha gente se atasca aquí.


💻 PARTE PRÁCTICA

bash
floci start
eval $(floci env)

Pedir la caché (fíjate: replication group, no cache cluster):

bash
aws elasticache create-replication-group \
  --replication-group-id clase03-cache \
  --replication-group-description "Cache del laboratorio" \
  --engine redis \
  --cache-node-type cache.t3.micro \
  --num-cache-clusters 1

Resolver el puerto y dejar un atajo:

bash
P=$(aws elasticache describe-replication-groups --replication-group-id clase03-cache \
    --query 'ReplicationGroups[0].ConfigurationEndpoint.Port' --output text)
r() { redis-cli -h localhost -p "$P" "$@"; }
zsh · clase03-cache
$ r PING
PONG
$ r SET paciente:12345601 "Paciente Ficticio"
OK
$ r GET paciente:12345601
Paciente Ficticio

💡 Convención de nombres. Redis no tiene tablas, así que la estructura vive en el nombre de la clave: paciente:12345601, sesion:abc, cola:citas. Los dos puntos no significan nada para el motor, pero organizan el espacio de claves y permiten buscarlas por patrón.


🏋️ EJERCICIOS CON SOLUCIÓN

🟢 Nivel 1 — Levantar la caché y hablarle (1-8)

Ejercicio 1 — Crear el grupo de réplica

Levanta una caché Redis con identificador ej01-cache.

💡 ¿Sabías que…? — por qué "replication group"

AWS retiró Redis de create-cache-cluster; ese comando quedó solo para Memcached. Un grupo de réplica puede tener un nodo (como aquí) o varios con réplicas de lectura.

bash
# ejemplo de referencia — otro grupo
aws elasticache create-replication-group --replication-group-id demo-otra \
  --replication-group-description "Otra cache" --engine redis \
  --cache-node-type cache.t3.micro --num-cache-clusters 1
Ver solución
bash
aws elasticache create-replication-group \
  --replication-group-id ej01-cache \
  --replication-group-description "Cache del ejercicio 1" \
  --engine redis --cache-node-type cache.t3.micro --num-cache-clusters 1

Ejercicio 2 — Comprobar que está disponible

Muestra el estado del grupo.

💡 ¿Sabías que…? — `creating` → `available`

Como en RDS, hay un estado intermedio. A diferencia de RDS, Redis arranca casi al instante: no hay que inicializar ficheros de datos.

bash
# ejemplo de referencia
aws elasticache describe-replication-groups --replication-group-id demo-otra \
  --query 'ReplicationGroups[0].Status' --output text
Ver solución
bash
aws elasticache describe-replication-groups --replication-group-id ej01-cache \
  --query 'ReplicationGroups[0].Status' --output text
# available

Ejercicio 3 — Averiguar el puerto

Obtén el puerto del endpoint de configuración.

💡 ¿Sabías que…? — la dirección que devuelve es engañosa

Devuelve localhost porque es la vista interna del emulador. El dato útil es el puerto; la dirección depende de desde dónde te conectes.

bash
# ejemplo de referencia — el objeto completo
aws elasticache describe-replication-groups --replication-group-id demo-otra \
  --query 'ReplicationGroups[0].ConfigurationEndpoint'
Ver solución
bash
P=$(aws elasticache describe-replication-groups --replication-group-id ej01-cache \
    --query 'ReplicationGroups[0].ConfigurationEndpoint.Port' --output text)
echo "$P"
# 6379

Ejercicio 4 — Comprobar que responde

Envía el comando que confirma que el servidor está vivo.

💡 ¿Sabías que…? — `PING` es el latido

Devuelve PONG. Es lo primero que se prueba y lo que usan los sistemas de monitorización para saber si el servicio sigue en pie.

bash
# ejemplo de referencia
redis-cli -h localhost -p 6390 PING
Ver solución
bash
redis-cli -h localhost -p "$P" PING
# PONG

Ejercicio 5 — Saber qué motor y versión corre

Averigua la versión del servidor.

💡 ¿Sabías que…? — `INFO` cuenta todo del servidor

INFO devuelve secciones: server, clients, memory, keyspace… Se puede pedir solo una para no ahogarse en datos.

bash
# ejemplo de referencia — la memoria usada
redis-cli -h localhost -p 6390 INFO memory | head -3
Ver solución
bash
redis-cli -h localhost -p "$P" INFO server | head -3
# redis_version:7.2.4
# server_name:valkey

📌 Es Valkey, el fork libre de Redis que surgió al cambiar Redis su licencia en 2024. Habla el mismo protocolo y responde a los mismos comandos.

Ejercicio 6 — Guardar tu primer valor

Guarda el nombre de un paciente bajo la clave paciente:12345601.

💡 ¿Sabías que…? — las comillas importan

Sin comillas, un valor con espacios se interpreta como argumentos separados y el comando falla o guarda solo la primera palabra.

bash
# ejemplo de referencia
redis-cli SET usuario:7 "Nombre Con Espacios"
Ver solución
bash
redis-cli -h localhost -p "$P" SET paciente:12345601 "Paciente Ficticio"
# OK

Ejercicio 7 — Recuperarlo

Léelo de vuelta.

💡 ¿Sabías que…? — `GET` sobre una clave inexistente

Devuelve (nil), no un error. Distinguir «no existe» de «existe y está vacío» es parte de usar bien una caché.

bash
# ejemplo de referencia
redis-cli GET clave-que-no-existe    # (nil)
Ver solución
bash
redis-cli -h localhost -p "$P" GET paciente:12345601
# Paciente Ficticio

Ejercicio 8 — Contar cuántas claves hay

Averigua cuántas claves tiene la base actual.

💡 ¿Sabías que…? — `DBSIZE` es instantáneo

Redis mantiene el contador al día, así que DBSIZE no recorre nada. KEYS *, en cambio, recorre todo el espacio de claves y puede bloquear el servidor en producción.

bash
# ejemplo de referencia
redis-cli DBSIZE
Ver solución
bash
redis-cli -h localhost -p "$P" DBSIZE
# 1

🔵 Nivel 2 — Claves, tipos y caducidad (9-16)

Ejercicio 9 — Hacer que un dato caduque

Guarda una sesión y haz que se borre sola en 5 minutos.

💡 ¿Sabías que…? — la caducidad es lo que hace caché a una caché

Sin TTL, la memoria crece sin freno. Con TTL, el propio motor se encarga de la limpieza sin que nadie tenga que acordarse.

bash
# ejemplo de referencia
redis-cli SET token:x "abc"
redis-cli EXPIRE token:x 60
Ver solución
bash
redis-cli -h localhost -p "$P" SET sesion:abc "token-123"
redis-cli -h localhost -p "$P" EXPIRE sesion:abc 300
# 1

Ejercicio 10 — Consultar cuánto le queda

Averigua los segundos de vida restantes de esa sesión.

💡 ¿Sabías que…? — los tres valores de `TTL`

Un número: los segundos que quedan. -1: existe pero no caduca. -2: no existe. Esa distinción es muy útil al depurar.

bash
# ejemplo de referencia
redis-cli TTL clave-inexistente    # -2
Ver solución
bash
redis-cli -h localhost -p "$P" TTL sesion:abc
# 300

Ejercicio 11 — Guardar con caducidad en un solo paso

Repite lo anterior pero con un solo comando.

💡 ¿Sabías que…? — `SETEX` evita una ventana peligrosa

Entre SET y EXPIRE hay un instante en que la clave existe sin caducidad. Si el proceso muere ahí, esa clave se queda para siempre. SETEX lo hace atómico.

bash
# ejemplo de referencia
redis-cli SETEX token:y 120 "valor"
Ver solución
bash
redis-cli -h localhost -p "$P" SETEX sesion:def 300 "token-456"
# OK

Ejercicio 12 — Quitarle la caducidad a una clave

Haz que sesion:def deje de caducar y compruébalo.

💡 ¿Sabías que…? — `PERSIST` deja la clave para siempre

Devuelve 1 si le quitó el TTL, 0 si no lo tenía. Después, TTL devuelve -1.

bash
# ejemplo de referencia
redis-cli PERSIST token:y
Ver solución
bash
redis-cli -h localhost -p "$P" PERSIST sesion:def
# 1
redis-cli -h localhost -p "$P" TTL sesion:def
# -1

Ejercicio 13 — Saber si una clave existe

Comprueba si paciente:12345601 está en la caché.

💡 ¿Sabías que…? — `EXISTS` no trae el valor

Devuelve solo 0 o 1. Si la clave guarda algo grande, comprobar existencia es mucho más barato que traérselo entero.

bash
# ejemplo de referencia
redis-cli EXISTS usuario:7
Ver solución
bash
redis-cli -h localhost -p "$P" EXISTS paciente:12345601
# 1

Ejercicio 14 — Averiguar el tipo de una clave

Sin leer su contenido, averigua qué estructura guarda una clave.

💡 ¿Sabías que…? — usar el comando equivocado da error

Si haces GET sobre una lista, Redis responde WRONGTYPE. TYPE evita esa sorpresa cuando no sabes qué hay dentro.

bash
# ejemplo de referencia
redis-cli TYPE alguna:clave    # string | list | set | zset | hash
Ver solución
bash
redis-cli -h localhost -p "$P" TYPE paciente:12345601
# string

Ejercicio 15 — Buscar claves por patrón

Lista todas las claves que empiecen por sesion:.

💡 ¿Sabías que…? — `KEYS` es peligroso en producción

Recorre el espacio completo y bloquea el servidor mientras lo hace. En una caché con millones de claves, es una caída. La alternativa es SCAN, que va por trozos.

bash
# ejemplo de referencia
redis-cli KEYS 'usuario:*'
Ver solución
bash
redis-cli -h localhost -p "$P" KEYS 'sesion:*'
# sesion:abc
# sesion:def

Ejercicio 16 — Recorrer sin bloquear

Usa la alternativa segura a KEYS para recorrer las claves por trozos.

💡 ¿Sabías que…? — `SCAN` devuelve un cursor

Devuelve dos cosas: el cursor para la siguiente llamada (0 significa que terminó) y un puñado de claves. No bloquea, pero puede repetir alguna.

bash
# ejemplo de referencia
redis-cli SCAN 0 COUNT 10
Ver solución
bash
redis-cli -h localhost -p "$P" SCAN 0 COUNT 3
# 1              ← cursor: hay mas
# sesion:abc
# ...

🟡 Nivel 3 — Las cinco estructuras (17-26)

Ejercicio 17 — Un contador atómico

Crea un contador de visitas e increméntalo dos veces.

💡 ¿Sabías que…? — atómico significa sin carreras

Dos procesos haciendo INCR a la vez nunca pierden una cuenta. En SQL, UPDATE … SET n = n + 1 necesita bloqueo o transacción para garantizar lo mismo.

bash
# ejemplo de referencia
redis-cli SET descargas 0
redis-cli INCR descargas
Ver solución
bash
redis-cli -h localhost -p "$P" SET visitas 0
redis-cli -h localhost -p "$P" INCR visitas
redis-cli -h localhost -p "$P" INCR visitas
# 2

Ejercicio 18 — Restar de golpe

Baja un contador de 100 a 70 en una sola operación.

💡 ¿Sabías que…? — la familia completa

INCR, DECR, INCRBY, DECRBY y INCRBYFLOAT. Todos atómicos. Sirven para stock, créditos o cupos disponibles.

bash
# ejemplo de referencia
redis-cli INCRBY puntos 50
Ver solución
bash
redis-cli -h localhost -p "$P" SET cupos 100
redis-cli -h localhost -p "$P" DECRBY cupos 30
# 70

Ejercicio 19 — Añadir texto al final

Concatena " mundo" a una clave que contenga "hola", y mide el resultado.

💡 ¿Sabías que…? — `APPEND` devuelve la longitud

No devuelve el texto, devuelve cuántos caracteres quedaron. Útil para ir acumulando un registro sin leerlo entero cada vez.

bash
# ejemplo de referencia
redis-cli APPEND log "linea nueva\n"
Ver solución
bash
redis-cli -h localhost -p "$P" SET saludo "hola"
redis-cli -h localhost -p "$P" APPEND saludo " mundo"
redis-cli -h localhost -p "$P" GET saludo     # hola mundo
redis-cli -h localhost -p "$P" STRLEN saludo  # 10

Ejercicio 20 — Leer y escribir varias claves a la vez

Guarda dos claves y recupéralas en una sola llamada.

💡 ¿Sabías que…? — menos idas y vueltas, más rendimiento

Cada comando es un viaje por la red. MSET/MGET hacen en uno lo que harían en varios: con latencia de red, la diferencia se nota mucho.

bash
# ejemplo de referencia
redis-cli MSET x 1 y 2 z 3
redis-cli MGET x z
Ver solución
bash
redis-cli -h localhost -p "$P" MSET conf:a 1 conf:b 2
redis-cli -h localhost -p "$P" MGET conf:a conf:b
# 1
# 2

Ejercicio 21 — Una lista como cola

Crea una cola de citas con tres elementos y muéstralos en orden.

💡 ¿Sabías que…? — por qué extremos distintos

RPUSH añade al final y LPOP saca del principio: eso es una cola (el primero que entra, el primero que sale). Con LPUSH + LPOP tendrías una pila.

bash
# ejemplo de referencia
redis-cli RPUSH tareas t1 t2
redis-cli LRANGE tareas 0 -1
Ver solución
bash
redis-cli -h localhost -p "$P" RPUSH cola:citas c1 c2 c3
redis-cli -h localhost -p "$P" LRANGE cola:citas 0 -1
# c1
# c2
# c3

💡 El -1 de LRANGE significa «hasta el último». 0 -1 es la lista entera.

Ejercicio 22 — Atender la cola

Saca el primer elemento y comprueba cuántos quedan.

💡 ¿Sabías que…? — sacar es leer y borrar a la vez

LPOP devuelve el elemento y lo elimina. Por eso dos trabajadores pueden consumir la misma cola sin procesar lo mismo dos veces.

bash
# ejemplo de referencia
redis-cli LPOP tareas
redis-cli LLEN tareas
Ver solución
bash
redis-cli -h localhost -p "$P" LPOP cola:citas   # c1
redis-cli -h localhost -p "$P" LLEN cola:citas   # 2

Ejercicio 23 — Un conjunto sin duplicados

Añade tres elementos a un conjunto, repitiendo uno, y cuenta cuántos quedaron.

💡 ¿Sabías que…? — el conjunto descarta repetidos solo

SADD devuelve cuántos elementos nuevos añadió. Añadir algo que ya estaba devuelve 0 y no duplica nada.

bash
# ejemplo de referencia
redis-cli SADD etiquetas nueva nueva otra
redis-cli SCARD etiquetas    # 2
Ver solución
bash
redis-cli -h localhost -p "$P" SADD votantes ana luis ana
redis-cli -h localhost -p "$P" SCARD votantes
# 2

Ejercicio 24 — Preguntar por pertenencia

Comprueba si alguien está en el conjunto.

💡 ¿Sabías que…? — es una comprobación de coste constante

Da igual que el conjunto tenga 10 o 10 millones: SISMEMBER tarda lo mismo. Por eso se usa para «¿ya votó?», «¿ya lo vio?», «¿está bloqueado?».

bash
# ejemplo de referencia
redis-cli SISMEMBER etiquetas nueva
Ver solución
bash
redis-cli -h localhost -p "$P" SISMEMBER votantes ana
# 1

Ejercicio 25 — Un ranking

Crea un conjunto ordenado con dos elementos puntuados y muéstralos de mayor a menor.

💡 ¿Sabías que…? — el orden lo mantiene el motor

Cada elemento lleva una puntuación y Redis mantiene el orden en todo momento. No hay que reordenar nada al consultar: el ranking siempre está listo.

bash
# ejemplo de referencia
redis-cli ZADD marcador 100 ana 250 luis
redis-cli ZRANGE marcador 0 -1 REV WITHSCORES
Ver solución
bash
redis-cli -h localhost -p "$P" ZADD ranking 10 uno 20 dos
redis-cli -h localhost -p "$P" ZRANGE ranking 0 -1 REV
# dos
# uno

Ejercicio 26 — Un registro con campos (hash)

Guarda una cita con dos campos y recupérala entera.

💡 ¿Sabías que…? — un hash evita serializar JSON

Con una cadena guardarías todo el JSON y tendrías que leerlo y reescribirlo entero para cambiar un campo. Con un hash, HSET toca solo ese campo.

bash
# ejemplo de referencia
redis-cli HSET usuario:7 nombre Ana rol admin
redis-cli HGET usuario:7 rol
Ver solución
bash
redis-cli -h localhost -p "$P" HSET cita:900 paciente 12345601 especialidad Cardiologia
redis-cli -h localhost -p "$P" HGETALL cita:900
# paciente
# 12345601
# especialidad
# Cardiologia

🟠 Nivel 4 — Patrones reales (27-34)

Ejercicio 27 — Implementar cache-aside a mano

Simula el patrón: comprueba si existe la clave; si no, "consulta la base" y guarda el resultado con caducidad.

💡 ¿Sabías que…? — el patrón en tres pasos

Mirar la caché → si falta, ir al origen → guardar con TTL. Es el 90% del uso real de una caché, y se escribe en cinco líneas.

bash
# ejemplo de referencia
if [ "$(redis-cli EXISTS dato)" = "0" ]; then
  redis-cli SETEX dato 60 "valor traido del origen"
fi
Ver solución
bash
CLAVE=paciente:23456702
if [ "$(redis-cli -h localhost -p "$P" EXISTS $CLAVE)" = "0" ]; then
  echo "fallo de cache: consultando el origen…"
  redis-cli -h localhost -p "$P" SETEX $CLAVE 300 "Otro Ficticio"
else
  echo "acierto de cache"
fi
redis-cli -h localhost -p "$P" GET $CLAVE

Ejercicio 28 — Medir aciertos y fallos

Lleva dos contadores: uno de aciertos y otro de fallos de caché.

💡 ¿Sabías que…? — la tasa de aciertos es LA métrica

Una caché con 20% de aciertos no sirve de nada: añade complejidad sin acelerar. Por debajo del 80% conviene revisar qué se cachea y con qué TTL.

bash
# ejemplo de referencia
redis-cli INCR stats:aciertos
Ver solución
bash
redis-cli -h localhost -p "$P" INCR stats:aciertos
redis-cli -h localhost -p "$P" INCR stats:fallos
redis-cli -h localhost -p "$P" MGET stats:aciertos stats:fallos

Ejercicio 29 — Invalidar una entrada

Borra de la caché un paciente porque sus datos cambiaron en la base.

💡 ¿Sabías que…? — invalidar es una de las dos cosas difíciles

Hay una frase célebre en informática: las dos cosas difíciles son invalidar cachés y poner nombres. Borrar la clave al cambiar el origen es la estrategia más simple y la más segura.

bash
# ejemplo de referencia
redis-cli DEL usuario:7
Ver solución
bash
redis-cli -h localhost -p "$P" DEL paciente:12345601
# 1

Ejercicio 30 — Una cola de trabajo con dos consumidores

Encola tres tareas y sácalas alternando, como harían dos trabajadores.

💡 ¿Sabías que…? — la cola reparte sola

Como LPOP borra al leer, dos procesos nunca cogen la misma tarea. No hace falta coordinación entre ellos.

bash
# ejemplo de referencia
redis-cli RPUSH trabajos a b c
redis-cli LPOP trabajos    # trabajador 1
redis-cli LPOP trabajos    # trabajador 2
Ver solución
bash
redis-cli -h localhost -p "$P" DEL cola:trabajo
redis-cli -h localhost -p "$P" RPUSH cola:trabajo t1 t2 t3
echo "trabajador A: $(redis-cli -h localhost -p "$P" LPOP cola:trabajo)"
echo "trabajador B: $(redis-cli -h localhost -p "$P" LPOP cola:trabajo)"
echo "quedan: $(redis-cli -h localhost -p "$P" LLEN cola:trabajo)"

Ejercicio 31 — Un ranking que se actualiza

Suma 5 puntos a un elemento del ranking sin recalcular nada.

💡 ¿Sabías que…? — `ZINCRBY` reordena solo

Al cambiar la puntuación, el elemento se recoloca automáticamente. Un marcador en vivo se implementa así, sin ordenar nada por tu cuenta.

bash
# ejemplo de referencia
redis-cli ZINCRBY marcador 10 ana
Ver solución
bash
redis-cli -h localhost -p "$P" ZSCORE ranking dos      # 20
redis-cli -h localhost -p "$P" ZINCRBY ranking 5 dos   # 25

Ejercicio 32 — Varias operaciones como un bloque

Ejecuta dos incrementos dentro de una transacción.

💡 ¿Sabías que…? — `MULTI` encola y `EXEC` ejecuta

Entre ambos, cada comando responde QUEUED: aún no se ha ejecutado. EXEC los aplica todos seguidos, sin que otro cliente se cuele en medio.

bash
# ejemplo de referencia — hace falta UNA sola conexion
printf 'MULTI\nINCR a\nINCR b\nEXEC\n' | redis-cli
Ver solución
bash
printf 'SET tx 0\nMULTI\nINCR tx\nINCR tx\nEXEC\nGET tx\n' | redis-cli -h localhost -p "$P"
# OK
# QUEUED
# QUEUED
# 1
# 2
# 2

⚠️ Tiene que ser una sola conexión. Si lanzas MULTI en un comando y EXEC en otro, obtienes ERR EXEC without MULTI: son sesiones distintas.

Ejercicio 33 — Modificar un solo campo de un registro

Cambia únicamente la especialidad de la cita, sin tocar el resto.

💡 ¿Sabías que…? — la ventaja del hash frente al JSON

Con JSON en una cadena tendrías que leer, modificar y reescribir todo. Con un hash, HSET sobre un campo no toca los demás — y sin condiciones de carrera.

bash
# ejemplo de referencia
redis-cli HSET usuario:7 rol lector
Ver solución
bash
redis-cli -h localhost -p "$P" HSET cita:900 especialidad Neurologia
redis-cli -h localhost -p "$P" HGETALL cita:900
# paciente sigue siendo 12345601

Ejercicio 34 — Listar solo los campos

Muestra qué campos tiene el hash, sin traer los valores.

💡 ¿Sabías que…? — `HKEYS`, `HVALS`, `HLEN`

Permiten inspeccionar un registro sin transferirlo entero. Con hashes grandes, ahorra red.

bash
# ejemplo de referencia
redis-cli HLEN usuario:7
Ver solución
bash
redis-cli -h localhost -p "$P" HKEYS cita:900
# paciente
# especialidad

🔴 Nivel 5 — Operación y límites (35-40)

Ejercicio 35 — Ver el estado del espacio de claves

Muestra cuántas claves hay y cuántas tienen caducidad.

💡 ¿Sabías que…? — `INFO keyspace` en una línea

Devuelve algo como db0:keys=8,expires=1,avg_ttl=260831. La proporción entre keys y expires dice cuántas claves están creciendo sin control.

bash
# ejemplo de referencia
redis-cli INFO keyspace
Ver solución
bash
redis-cli -h localhost -p "$P" INFO keyspace | tail -1
# db0:keys=8,expires=1,avg_ttl=260831

💡 Si expires es mucho menor que keys, la mayoría de tus datos no caducan nunca: mala señal en una caché.

Ejercicio 36 — Vaciar la caché

Borra todas las claves de la base actual.

💡 ¿Sabías que…? — `FLUSHDB` frente a `FLUSHALL`

FLUSHDB vacía la base actual; FLUSHALL, todas. En producción, ambos son comandos que conviene tener deshabilitados.

bash
# ejemplo de referencia
redis-cli DBSIZE     # antes
redis-cli FLUSHDB
Ver solución
bash
redis-cli -h localhost -p "$P" FLUSHDB
redis-cli -h localhost -p "$P" DBSIZE
# 0

Ejercicio 37 — Comprobar que los datos son volátiles

Reinicia el emulador y comprueba qué queda en la caché.

💡 ¿Sabías que…? — memoria significa memoria

Redis puede persistir a disco con RDB o AOF, pero en una caché normalmente no se configura: si hiciera falta que los datos sobrevivan, no serían datos de caché.

bash
# ejemplo de referencia
floci stop && floci start
Ver solución
bash
redis-cli -h localhost -p "$P" SET prueba "antes del reinicio"
floci restart
# hay que volver a crear el grupo: la cache no sobrevive
redis-cli -h localhost -p "$P" GET prueba

Es la lección central de la clase: lo que está solo en la caché, no está.

Ejercicio 38 — Intenta hacer una copia de seguridad

Crea una instantánea de la caché. Observa la respuesta.

💡 ¿Sabías que…? — para qué sirven en AWS

Una instantánea de ElastiCache permite recrear la caché ya "caliente", sin el bajón de rendimiento inicial mientras se llena. Se usa al migrar o al escalar.

bash
# ejemplo de referencia — como seria en AWS
aws elasticache create-snapshot --replication-group-id demo-otra --snapshot-name copia-1
Ver solución
bash
aws elasticache create-snapshot --replication-group-id ej01-cache --snapshot-name ej38-snap
# An error occurred (UnsupportedOperation) when calling the CreateSnapshot
# operation: Operation CreateSnapshot is not supported.

No están soportadas, igual que en RDS. Verificado el 2026-08-08.

Ejercicio 39 — El comando que ya no vale para Redis

Intenta crear la caché con create-cache-cluster y lee el error.

💡 ¿Sabías que…? — el error explica la historia

AWS separó los caminos: create-cache-cluster quedó para Memcached, y Redis/Valkey pasaron a create-replication-group. Muchos tutoriales antiguos no lo reflejan.

bash
# ejemplo de referencia — esto SI vale, para Memcached
aws elasticache create-cache-cluster --cache-cluster-id demo-mc \
  --engine memcached --cache-node-type cache.t3.micro --num-cache-nodes 1
Ver solución
bash
aws elasticache create-cache-cluster --cache-cluster-id ej39 --engine redis \
  --cache-node-type cache.t3.micro --num-cache-nodes 1
# Engine must be 'memcached'. For Redis/Valkey use CreateReplicationGroup.

No es un fallo del emulador: reproduce fielmente el comportamiento de AWS.

Ejercicio 40 — Dejarlo limpio

Elimina el grupo de réplica y comprueba que el contenedor desapareció.

💡 ¿Sabías que…? — `--no-retain-primary-cluster`

Sin ese indicador, AWS conserva el nodo principal y solo borra las réplicas. Para eliminarlo todo hay que decirlo explícitamente.

bash
# ejemplo de referencia
aws elasticache delete-replication-group --replication-group-id demo-otra \
  --no-retain-primary-cluster
Ver solución
bash
aws elasticache delete-replication-group --replication-group-id ej01-cache \
  --no-retain-primary-cluster
sleep 5
docker ps --format '{{.Names}}' | grep valkey || echo "sin caches vivas"

❓ Preguntas y respuestas (autoevaluación)

1. ¿Por qué una caché no es una base de datos pequeña?

Vive en memoria, sus datos son una copia y están pensados para caducar. Si perderlos rompe algo, no debían estar solo ahí.

2. ¿En qué consiste el patrón cache-aside?

Mirar la caché; si falta el dato, ir al origen y guardarlo con caducidad antes de devolverlo.

3. ¿Por qué el TTL es una decisión de negocio?

Determina cuánto tiempo se puede servir un dato desactualizado, y eso depende de la pantalla, no de la técnica.

4. ¿Qué ventaja tiene SETEX sobre SET + EXPIRE?

Es atómico. Entre los dos comandos hay un instante en que la clave existiría sin caducidad para siempre.

5. ¿Qué devuelve TTL y qué significa cada valor?

Los segundos restantes; -1 si existe sin caducidad; -2 si no existe.

6. ¿Por qué KEYS * es peligroso en producción?

Recorre todo el espacio de claves y bloquea el servidor. La alternativa segura es SCAN.

7. ¿Por qué INCR es mejor que leer, sumar y escribir?

Es atómico: dos procesos simultáneos nunca pierden una cuenta.

8. ¿Cuándo usarías un hash en vez de guardar JSON en una cadena?

Cuando necesites modificar campos sueltos sin leer ni reescribir el registro entero.

9. ¿Por qué MULTI y EXEC deben ir en la misma conexión?

La transacción es estado de sesión. En conexiones distintas, EXEC no encuentra su MULTI.

10. ¿Qué dos operaciones de ElastiCache no se pueden practicar aquí?

Las instantáneas (no soportadas) y crear Redis con create-cache-cluster — esto último por fidelidad a AWS, no por limitación.


📎 Apuntes relacionados

➡️ Siguiente

Clase 4 — API REST serverless: encadenar API Gateway, Lambda y DynamoDB hasta obtener una URL que responde con datos.

Apuntes de AWS con Floci