0Pricing
Cloud & IT Cert Prep · Lezione

Archiviazione delle sessioni e pattern per le classifiche

Utilizzare ElastiCache per esternalizzare lo stato delle sessioni HTTP dai server applicativi e implementare classifiche in tempo reale con i set ordinati di Redis

Archiviazione delle sessioni e pattern per le classifiche è una lezione Cloud & IT Cert Prep gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Cloud & IT Cert Prep, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Cloud & IT Cert Prep include 4 lezioni in totale.

Il problema delle sessioni lato server

Le applicazioni web tradizionali archiviano i dati di sessione nella memoria del server. Questa soluzione funziona con un singolo server, ma non quando si esegue una scalabilità orizzontale: se la richiesta successiva di un utente viene instradata verso un'istanza EC2 diversa, tale istanza non conosce la sessione dell'utente, che viene quindi disconnesso. Le sessioni persistenti (affinità di sessione nel load balancer) risolvono il problema solo in parte, ma riducono l'efficacia del bilanciamento del carico. La soluzione scalabile consiste nello spostare lo stato della sessione in un archivio condiviso a bassa latenza, accessibile da tutte le istanze: è esattamente ciò che offre ElastiCache Redis.

Redis per l'archiviazione delle sessioni

Archiviare le sessioni in Redis offre: letture delle sessioni in meno di un millisecondo su tutti i server applicativi, TTL integrato per la scadenza automatica delle sessioni, aggiornamenti atomici delle sessioni per evitare condizioni di gara e la possibilità di invalidare immediatamente una sessione eliminando la chiave. L'applicazione memorizza l'ID della sessione in un cookie; a ogni richiesta cerca l'ID della sessione in Redis per recuperare i dati della sessione. Tutti i server applicativi condividono lo stesso Redis, quindi qualsiasi server può gestire la richiesta di qualsiasi utente.

# 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 None

TTL della sessione e scadenza scorrevole

Un TTL fisso indica che la sessione scade N secondi dopo la creazione, indipendentemente dall'attività. Un TTL scorrevole (che estende la scadenza a ogni accesso) è più pratico per gli utenti: la sessione scade N secondi dopo l'ultimo accesso. In Redis, si implementa un TTL scorrevole chiamando EXPIRE (o EXPIREAT) sulla chiave della sessione a ogni lettura riuscita della sessione, così da reimpostare il conto alla rovescia della scadenza. In questo modo gli utenti attivi non vengono disconnessi inaspettatamente, mentre le sessioni inattive scadono automaticamente, liberando 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 found

Carrello degli acquisti in Redis

Un carrello per gli acquisti di un'applicazione di e-commerce è particolarmente adatto a Redis. Ogni carrello viene archiviato come un Redis Hash, in cui il campo è lo SKU del prodotto e il valore è la quantità. Le operazioni sugli hash, come HINCRBY e HDEL, consentono aggiornamenti atomici senza recuperare e riscrivere l'intero carrello. In combinazione con un TTL (per far scadere i carrelli abbandonati dopo 24 ore), Redis offre un archivio dei carrelli rapido e persistente, senza il sovraccarico di utilizzare un database relazionale per ogni evento di aggiunta al carrello.

# 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)

Architettura delle classifiche

Una classifica in tempo reale è un caso d'uso classico di Redis, reso possibile dagli Sorted Set (ZSET). Ogni voce del giocatore ha un punteggio; lo sorted set mantiene sempre i membri in ordine crescente di punteggio. Le query sulle classifiche (i primi N giocatori, la posizione di un giocatore, i giocatori in un intervallo di punteggio) hanno complessità O(log n) o O(log n + m): sono estremamente veloci anche con milioni di giocatori. Gli sorted set di Redis sono alla base di molte funzionalità di classificazione nel gaming, nel fitness e nei social network, senza dover ricorrere a query complesse sul database o ricalcolare la posizione a ogni visualizzazione della pagina.

# 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)

Posizione del giocatore e giocatori vicini

Due funzionalità comuni delle classifiche, oltre a "mostra i primi 10", sono mostrare la posizione di un giocatore e mostrare i giocatori vicini a un determinato giocatore. Entrambe sono semplici da implementare con gli sorted set di Redis. ZREVRANK restituisce la posizione indicizzata a partire da 0 di un giocatore in ordine decrescente di punteggio. Per mostrare 5 giocatori sopra e sotto un giocatore, si recupera la sua posizione e poi si usa ZREVRANGE dall'indice posizione-5 all'indice posizione+5. In questo modo si ottiene una visualizzazione personalizzata della classifica con due comandi Redis, senza ricorrere a complesse funzioni finestra SQL.

# 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)

Limitazione della frequenza con Redis

La limitazione della frequenza (ovvero limitare il numero di richieste che un client può effettuare in una determinata finestra temporale) è un altro caso d'uso di grande valore per Redis. L'algoritmo della finestra scorrevole utilizza uno sorted set in cui ogni membro è il timestamp di una richiesta. A ogni richiesta: rimuove i membri più vecchi della finestra, conta quelli rimanenti, rifiuta la richiesta se il conteggio supera il limite e aggiunge il nuovo timestamp. In questo modo si implementa una limitazione precisa con finestra scorrevole e risoluzione al millisecondo, molto più accurata dei contatori a finestra fissa e senza il sovraccarico di un database.

# 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 limited

Lock distribuiti con Redis

I lock distribuiti coordinano l'accesso esclusivo a una risorsa condivisa tra più server applicativi. Il comando SET key value NX EX ttl di Redis permette di acquisire il lock in modo atomico: imposta la chiave solo se questa non esiste (NX = Not eXists) e imposta un TTL per evitare deadlock se il detentore si arresta in modo anomalo. Al termine dell'operazione, il detentore elimina la chiave. L'algoritmo Redlock (che utilizza più nodi Redis per ottenere un quorum) offre un lock distribuito più robusto, ma aggiunge complessità. Per la maggior parte dei casi d'uso, è sufficiente un lock su un singolo nodo 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)

Archiviazione delle sessioni: ElastiCache e DynamoDB

Sia ElastiCache Redis sia DynamoDB possono archiviare i dati delle sessioni, ma presentano compromessi diversi. ElastiCache Redis: latenza di pochi microsecondi, dati in memoria (volatili se non viene abilitata la persistenza), modello di dati più semplice, richiede un VPC. DynamoDB: latenza nell'ordine dei millisecondi a una cifra (DAX può raggiungere prestazioni pari a Redis), servizio completamente gestito senza cluster da mantenere, durabilità predefinita, accessibile globalmente con Global Tables, serverless con capacità on-demand. Per l'esame SAA-C03: se la domanda enfatizza la latenza di pochi microsecondi o le operazioni complesse in memoria, scelga Redis. Se enfatizza durabilità, serverless o scalabilità globale, consideri DynamoDB.

Indicizzazione geospaziale con Redis

Redis dispone di un tipo di dati geospaziali integrato (comandi GEO) che memorizza coordinate di latitudine e longitudine e consente query di prossimità. Utilizzando GEOADD, GEODIST e GEORADIUS (ora GEOSEARCH in Redis 6.2), è possibile trovare tutte le posizioni entro un determinato raggio da un punto in O(n + log n). Casi d'uso: trovare autisti nelle vicinanze (ride sharing), trovare ristoranti entro 5 km, ordinare i risultati di ricerca per distanza. Ciò evita di dover utilizzare un database geospaziale separato e mantiene le query sulle posizioni alla velocità della 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 coordinates

HyperLogLog per il conteggio dei visitatori unici

Un HyperLogLog è una struttura dati probabilistica che stima il conteggio degli elementi unici in un insieme utilizzando una quantità fissa di memoria (12 KB in Redis), indipendentemente dal numero di elementi unici aggiunti. Fornisce un errore standard approssimativo dello 0,81%. Utilizzi PFADD per aggiungere elementi e PFCOUNT per ottenere la stima. È perfetto per contare gli utenti attivi giornalieri unici, le visualizzazioni di pagina uniche o gli indirizzi IP unici quando non sono richiesti conteggi esatti e l'efficienza della memoria è importante. Memorizzare milioni di ID utente unici come Redis Set consumerebbe diversi GB; HyperLogLog utilizza 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}')

Verifica rapida

Verifichi la Sua comprensione dei concetti di AWS Solutions Architect (SAA-C03) trattati in questa lezione.

Riepilogo della lezione

In questa lezione ha appreso che: l'archiviazione delle sessioni in Redis consente la scalabilità orizzontale senza stato, dando a tutte le istanze accesso allo stato condiviso delle sessioni con una latenza inferiore al millisecondo; gli sorted set di Redis alimentano classifiche in tempo reale con query sulla posizione in O(log n); e i tipi di dati Redis specializzati (HyperLogLog per i conteggi unici, GEO per la prossimità, lock distribuiti) risolvono in modo efficiente problemi architetturali comuni. Con questo si conclude il corso Caching with ElastiCache; ora esploreremo l'alta disponibilità e le architetture tolleranti ai guasti.

Domande Frequenti

La lezione «Archiviazione delle sessioni e pattern per le classifiche» è gratuita?

Sì — il testo completo di «Archiviazione delle sessioni e pattern per le classifiche» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Cloud & IT Cert Prep, passa a CoddyKit PRO. Il corso Cloud & IT Cert Prep include 4 lezioni in totale.

Cosa imparerò in «Archiviazione delle sessioni e pattern per le classifiche»?

Utilizzare ElastiCache per esternalizzare lo stato delle sessioni HTTP dai server applicativi e implementare classifiche in tempo reale con i set ordinati di Redis Eserciti Cloud & IT Cert Prep con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Cloud & IT Cert Prep?

Non è richiesta alcuna esperienza precedente. Cloud & IT Cert Prep su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Archiviazione delle sessioni e pattern per le classifiche»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Cloud & IT Cert Prep?

Sì. Ogni lezione Cloud & IT Cert Prep include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Redis e Memcached: scegliere il motore giusto
  2. Gruppi di replica Redis e modalità cluster di ElastiCache
  3. Strategie di caching: lazy loading e write-through
  4. Archiviazione delle sessioni e pattern per le classifiche
← Torna a Cloud & IT Cert Prep