Almacenamiento de sesiones y patrones de tablas de clasificación
Utilice ElastiCache para descargar el estado de las sesiones HTTP de los servidores de aplicaciones e implemente tablas de clasificación en tiempo real con conjuntos ordenados de Redis
Almacenamiento de sesiones y patrones de tablas de clasificación es una lección gratuita de AWS Solutions Architect en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de AWS Solutions Architect, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de AWS Solutions Architect incluye 4 lecciones en total.
El problema de las sesiones del lado del servidor
Las aplicaciones web tradicionales almacenan los datos de sesión en la memoria del servidor. Esto funciona con un solo servidor, pero deja de funcionar al escalar horizontalmente: si la siguiente solicitud de un usuario se enruta a otra instancia de EC2, esa instancia no conoce la sesión del usuario y este cierra su sesión. Las sesiones persistentes (afinidad de sesión en el balanceador de carga) resuelven el problema parcialmente, pero reducen la eficacia del balanceo de carga. La solución escalable consiste en trasladar el estado de sesión a un almacén compartido de baja latencia accesible para todas las instancias, que es precisamente lo que proporciona ElastiCache Redis.
Redis para el almacenamiento de sesiones
Almacenar las sesiones en Redis ofrece: lecturas de sesión en menos de un milisegundo desde todos los servidores de aplicaciones, TTL integrado para la caducidad automática de las sesiones, actualizaciones atómicas de sesión para evitar condiciones de carrera y la posibilidad de invalidar inmediatamente una sesión eliminando la clave. La aplicación almacena el ID de sesión en una cookie; en cada solicitud, busca el ID de sesión en Redis para recuperar los datos de la sesión. Todos los servidores de aplicaciones comparten el mismo Redis, por lo que cualquier servidor puede gestionar la solicitud de cualquier usuario.
# Session storage with Redis (Python Flask example)
import redis, json, uuid
from datetime import timedelta
redis_client = redis.Redis(host='prod-redis-primary', port=6379)
SESSION_TTL = int(timedelta(hours=8).total_seconds())
def create_session(user_id):
session_id = str(uuid.uuid4())
session_data = {'user_id': user_id, 'logged_in': True}
redis_client.setex(f'session:{session_id}', SESSION_TTL, json.dumps(session_data))
return session_id
def get_session(session_id):
data = redis_client.get(f'session:{session_id}')
return json.loads(data) if data else NoneTTL de sesión y caducidad deslizante
Un TTL fijo significa que la sesión caduca N segundos después de su creación, independientemente de la actividad. Un TTL deslizante (que amplía la caducidad con cada acceso) es más práctico para el usuario: la sesión caduca N segundos después del último acceso. En Redis, implemente un TTL deslizante llamando a EXPIRE (o EXPIREAT) sobre la clave de sesión después de cada lectura correcta de la sesión para reiniciar la cuenta atrás de caducidad. Así se asegura de que los usuarios activos no cierren su sesión inesperadamente, mientras que las sesiones inactivas caducan automáticamente y liberan memoria.
# Sliding TTL session implementation
def get_session_with_sliding_ttl(session_id, redis_client, ttl_seconds=1800):
session_key = f'session:{session_id}'
# Pipeline: GET + EXPIRE in one round trip
pipe = redis_client.pipeline()
pipe.get(session_key)
pipe.expire(session_key, ttl_seconds) # Reset TTL on access
results = pipe.execute()
data = results[0]
if data:
return json.loads(data)
return None # Session expired or not foundCarrito de compra en Redis
Un carrito de compra de comercio electrónico encaja perfectamente con Redis. Cada carrito se almacena como un Hash de Redis, donde el campo es el SKU del producto y el valor es la cantidad. Las operaciones de hash, como HINCRBY y HDEL, permiten realizar actualizaciones atómicas sin recuperar y volver a escribir todo el carrito. Combinado con un TTL (para hacer caducar los carritos abandonados después de 24 horas), Redis proporciona un almacén de carritos rápido y persistente sin la sobrecarga de utilizar una base de datos relacional para cada evento de adición al carrito.
# Shopping cart operations using Redis Hash
cart_key = f'cart:{user_id}'
# Add item (or increase quantity)
# HINCRBY cart:user42 SKU-001 2
redis_client.hincrby(cart_key, 'SKU-001', 2)
# Remove item
# HDEL cart:user42 SKU-001
redis_client.hdel(cart_key, 'SKU-001')
# Get all items in cart
# HGETALL cart:user42
cart = redis_client.hgetall(cart_key) # {b'SKU-001': b'2', b'SKU-002': b'1'}
# Set TTL for cart abandonment (24 hours)
redis_client.expire(cart_key, 86400)Arquitectura de la tabla de posiciones
Una tabla de posiciones en tiempo real es un caso de uso clásico de Redis habilitado por los conjuntos ordenados (ZSET). Cada entrada de jugador tiene una puntuación; el conjunto ordenado mantiene siempre los miembros en orden ascendente de puntuación. Las consultas de la tabla de posiciones (los N mejores jugadores, la posición de un jugador y los jugadores dentro de un rango de puntuaciones) tienen una complejidad de O(log n) u O(log n + m), por lo que son extremadamente rápidas incluso con millones de jugadores. Los conjuntos ordenados de Redis son la base de muchas funciones de clasificación en juegos, aplicaciones de fitness y redes sociales, sin necesidad de consultas complejas a la base de datos ni de recalcular la posición cada vez que se muestra una página.
# Real-time leaderboard with Redis Sorted Set
# Add or update a player's score
# ZADD game:weekly:leaderboard 15750 'player:alice'
redis_client.zadd('game:weekly:leaderboard', {'player:alice': 15750})
# Increment score (atomic)
# ZINCRBY game:weekly:leaderboard 500 'player:alice'
redis_client.zincrby('game:weekly:leaderboard', 500, 'player:alice')
# Get top 10 players (highest scores first)
# ZREVRANGE game:weekly:leaderboard 0 9 WITHSCORES
top_10 = redis_client.zrevrange('game:weekly:leaderboard', 0, 9, withscores=True)Posición del jugador y jugadores cercanos
Dos funciones habituales de las tablas de posiciones, además de «mostrar los 10 primeros», son mostrar la posición de un jugador y mostrar los jugadores cercanos a un jugador determinado. Ambas son triviales con los conjuntos ordenados de Redis. ZREVRANK devuelve la posición indexada desde 0 de un jugador en orden descendente de puntuación. Para mostrar 5 jugadores por encima y por debajo de un jugador, obtenga su posición y, a continuación, use ZREVRANGE desde la posición-5 hasta la posición+5. Esto proporciona una vista personalizada de la tabla de posiciones con solo dos comandos de Redis, sin necesidad de funciones de ventana SQL complejas.
# Get Alice's rank (0-indexed, so add 1 for display)
# ZREVRANK game:weekly:leaderboard 'player:alice'
rank = redis_client.zrevrank('game:weekly:leaderboard', 'player:alice')
print(f'Alice is rank #{rank + 1}')
# Get 5 players above and below Alice
start = max(0, rank - 5)
end = rank + 5
nearby = redis_client.zrevrange(
'game:weekly:leaderboard', start, end, withscores=True
)
print('Players near Alice:', nearby)Limitación de frecuencia con Redis
La limitación de frecuencia (restringir cuántas solicitudes puede realizar un cliente en un intervalo de tiempo) es otro caso de uso de gran valor para Redis. El algoritmo de ventana deslizante utiliza un conjunto ordenado en el que cada miembro es la marca de tiempo de una solicitud. En cada solicitud: elimina los miembros anteriores al intervalo, cuenta los miembros restantes, rechaza la solicitud si el recuento supera el límite y añade la nueva marca de tiempo. Esto implementa una limitación de frecuencia precisa mediante una ventana deslizante con resolución de milisegundos, mucho más exacta que los contadores de ventana fija y sin la sobrecarga de una base de datos.
# Sliding window rate limiter (100 requests per 60 seconds)
import time
def is_rate_limited(user_id, redis_client, limit=100, window_seconds=60):
key = f'ratelimit:{user_id}'
now = time.time()
window_start = now - window_seconds
pipe = redis_client.pipeline()
pipe.zremrangebyscore(key, '-inf', window_start) # Remove old
pipe.zcard(key) # Count current
pipe.zadd(key, {str(now): now}) # Add this request
pipe.expire(key, window_seconds)
results = pipe.execute()
request_count = results[1]
return request_count >= limit # True = rate limitedBloqueos distribuidos con Redis
Los bloqueos distribuidos coordinan el acceso exclusivo a un recurso compartido entre varios servidores de aplicaciones. El comando SET key value NX EX ttl de Redis proporciona una adquisición atómica del bloqueo: establece la clave solo si no existe (NX = Not eXists) y configura un TTL para evitar interbloqueos si el proceso que posee el bloqueo se bloquea. Cuando finaliza la operación, el propietario elimina la clave. El algoritmo Redlock (que utiliza varios nodos de Redis para obtener un quórum) proporciona un bloqueo distribuido más sólido, aunque añade complejidad. Para la mayoría de los casos de uso, basta con un bloqueo en un único nodo de Redis.
# Distributed lock with Redis SET NX EX
import uuid
def acquire_lock(redis_client, resource, ttl_seconds=30):
lock_id = str(uuid.uuid4()) # Unique ID to identify this lock holder
key = f'lock:{resource}'
acquired = redis_client.set(key, lock_id, nx=True, ex=ttl_seconds)
return lock_id if acquired else None
def release_lock(redis_client, resource, lock_id):
key = f'lock:{resource}'
# Only delete if we still own the lock (Lua script for atomicity)
lua = 'if redis.call("get",KEYS[1])==ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end'
redis_client.eval(lua, 1, key, lock_id)Almacenamiento de sesiones: ElastiCache frente a DynamoDB
Tanto ElastiCache Redis como DynamoDB pueden almacenar datos de sesión, pero presentan distintas ventajas y desventajas. ElastiCache Redis: latencia de microsegundos, almacenamiento en memoria (volátil si no se habilita la persistencia), modelo de datos más sencillo y requisito de VPC. DynamoDB: latencia de milisegundos de un solo dígito (DAX puede igualar a Redis), servicio completamente administrado sin clúster que mantener, durabilidad predeterminada, acceso global mediante Global Tables y arquitectura sin servidor con capacidad bajo demanda. Para el examen SAA-C03: si la pregunta hace hincapié en la latencia de microsegundos o en las operaciones complejas en memoria, elija Redis. Si hace hincapié en la durabilidad, la arquitectura sin servidor o la escala global, considere DynamoDB.
Indexación geoespacial con Redis
Redis tiene un tipo de datos geoespaciales integrado (comandos GEO) que almacena coordenadas de latitud y longitud y permite realizar consultas de proximidad. Mediante GEOADD, GEODIST y GEORADIUS (ahora GEOSEARCH en Redis 6.2), puede encontrar todas las ubicaciones dentro de un radio determinado desde un punto en un tiempo O(n + log n). Casos de uso: encontrar conductores cercanos (servicios de transporte compartido), encontrar restaurantes en un radio de 5 km y ordenar los resultados de búsqueda por distancia. Esto evita utilizar una base de datos geoespacial independiente y mantiene las consultas de ubicación a velocidades propias de la memoria.
# Store driver locations
# GEOADD drivers 13.361389 38.115556 'driver:001'
# GEOADD drivers 15.087269 37.502669 'driver:002'
# Find all drivers within 10 km of a point
# GEOSEARCH drivers FROMLONLAT 13.5 38.1 BYRADIUS 10 km ASC COUNT 5 WITHCOORD
# Result: sorted list of driver IDs within 10 km with coordinatesHyperLogLog para contar visitantes únicos
Un HyperLogLog es una estructura de datos probabilística que estima el número de elementos únicos de un conjunto utilizando una cantidad fija de memoria (12 KB en Redis), independientemente del número de elementos únicos que se añadan. Proporciona un error estándar aproximado del 0,81 %. Use PFADD para añadir elementos y PFCOUNT para obtener la estimación. Es ideal para contar usuarios activos diarios únicos, visualizaciones de página únicas o direcciones IP únicas cuando no se necesitan recuentos exactos y la eficiencia de memoria es importante. Almacenar millones de identificadores de usuario únicos como un Set de Redis consumiría GB; HyperLogLog utiliza 12 KB.
# Count unique daily visitors using HyperLogLog
date = '2024-01-15'
hll_key = f'unique_visitors:{date}'
# Track a visitor (PFADD is idempotent for the same user)
# PFADD unique_visitors:2024-01-15 'user:12345'
redis_client.pfadd(hll_key, 'user:12345')
redis_client.pfadd(hll_key, 'user:67890')
redis_client.pfadd(hll_key, 'user:12345') # Duplicate — not counted again
# Get estimated unique visitor count
# PFCOUNT unique_visitors:2024-01-15
count = redis_client.pfcount(hll_key)
print(f'Unique visitors today (estimate): {count}')Comprobación rápida
Compruebe sus conocimientos sobre los conceptos de AWS Solutions Architect (SAA-C03) de esta lección.
Resumen de la lección
En esta lección ha aprendido lo siguiente: el almacenamiento de sesiones en Redis permite el escalado horizontal sin estado al proporcionar a todas las instancias acceso al estado de sesión compartido con una latencia inferior a un milisegundo; los conjuntos ordenados de Redis permiten crear tablas de posiciones en tiempo real con consultas de posición O(log n); y los tipos de datos especializados de Redis (HyperLogLog para recuentos únicos, GEO para proximidad y bloqueos distribuidos) resuelven eficazmente problemas habituales de arquitectura. Con esto finaliza el curso de almacenamiento en caché con ElastiCache; a continuación exploraremos la alta disponibilidad y las arquitecturas tolerantes a fallos.
Aprende AWS Solutions Architect con un tutor de IA — gratis
Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.
- Cursos
- 30
- Lecciones
- 120
Preguntas frecuentes
¿La lección «Almacenamiento de sesiones y patrones de tablas de clasificación» es gratis?
Sí — el texto completo de «Almacenamiento de sesiones y patrones de tablas de clasificación» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de AWS Solutions Architect, actualiza a CoddyKit PRO. El curso de AWS Solutions Architect incluye 4 lecciones en total.
¿Qué aprenderé en «Almacenamiento de sesiones y patrones de tablas de clasificación»?
Utilice ElastiCache para descargar el estado de las sesiones HTTP de los servidores de aplicaciones e implemente tablas de clasificación en tiempo real con conjuntos ordenados de Redis Practicas AWS Solutions Architect con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar AWS Solutions Architect?
No se requiere experiencia previa. AWS Solutions Architect en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Almacenamiento de sesiones y patrones de tablas de clasificación»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de AWS Solutions Architect?
Sí. Cada lección de AWS Solutions Architect incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Redis frente a Memcached: elección del motor adecuado
- Grupos de replicación y modo de clúster de ElastiCache Redis
- Estrategias de almacenamiento en caché: carga diferida y escritura simultánea
- Almacenamiento de sesiones y patrones de tablas de clasificación