Sessionslagring og leaderboard-mønstre
Brug ElastiCache til at aflaste HTTP-sessionstilstand fra dine applikationsservere, og implementér leaderboards i realtid med Redis-sorterede sæt
Sessionslagring og leaderboard-mønstre er en gratis Cloud & IT Cert Prep-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Cloud & IT Cert Prep, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Cloud & IT Cert Prep-kurset indeholder 4 lektioner i alt.
Problemet med sessioner på serversiden
Traditionelle webapplikationer gemmer sessionsdata i hukommelsen på serveren. Det fungerer med én server, men bryder sammen, når du skalerer horisontalt — hvis en brugers efterfølgende forespørgsel dirigeres til en anden EC2-instans, har den instans ingen viden om brugerens session, og brugeren logges ud. Sticky sessions (sessionstilknytning i load balanceren) løser kun problemet delvist, men reducerer effektiviteten af belastningsfordelingen. Den skalerbare løsning er at flytte sessionstilstanden til et delt lager med lav latenstid, som alle instanser har adgang til — og det er netop, hvad ElastiCache Redis leverer.
Redis til sessionslagring
Hvis du gemmer sessioner i Redis, får du: sessionslæsninger på under et millisekund på tværs af alle applikationsservere, indbygget TTL til automatisk udløb af sessioner, atomare sessionsopdateringer for at forhindre kapløbstilstande og mulighed for straks at ugyldiggøre en session ved at slette nøglen. Applikationen gemmer session-id'et i en cookie; ved hver forespørgsel slår den session-id'et op i Redis for at hente sessionsdataene. Alle applikationsservere deler den samme Redis, så enhver server kan håndtere enhver brugers forespørgsel.
# 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 NoneSessionens TTL og glidende udløb
En fast TTL betyder, at sessionen udløber N sekunder efter oprettelsen uanset aktivitet. En glidende TTL (hvor udløbet forlænges ved hver adgang) er mere brugervenlig — sessionen udløber N sekunder efter den seneste adgang. I Redis implementerer du en glidende TTL ved at kalde EXPIRE (eller EXPIREAT) på sessionsnøglen ved hver vellykkede sessionslæsning for at nulstille nedtællingen til udløb. Det sikrer, at aktive brugere aldrig uventet logges ud, mens inaktive sessioner automatisk udløber og frigiver hukommelse.
# 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 foundIndkøbskurv i Redis
En indkøbskurv i en e-handelsløsning passer naturligt til Redis. Hver kurv gemmes som en Redis-hash, hvor feltet er produktets SKU, og værdien er antallet. Hash-handlinger som HINCRBY og HDEL gør det muligt at udføre atomare opdateringer uden at hente og omskrive hele kurven. Kombineret med en TTL (så forladte kurve udløber efter 24 timer) giver Redis et hurtigt, persistent lager til kurve uden den ekstra belastning ved at bruge en relationsdatabase til hver eneste hændelse, hvor en vare lægges i kurven.
# 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)Leaderboard-arkitektur
En leaderboard i realtid er et klassisk anvendelsesområde for Redis, som aktiveres af sorterede sæt (ZSET'er). Hver spillerpost har en score, og det sorterede sæt vedligeholder altid medlemmerne i stigende scoreorden. Forespørgsler til leaderboardet (de øverste N spillere, en spillers placering, spillere inden for et scoreinterval) har kompleksiteten O(log n) eller O(log n + m) — ekstremt hurtigt, selv med millioner af spillere. Redis' sorterede sæt er grundlaget for mange funktioner til rangordning inden for spil, fitness og sociale tjenester, uden behov for en kompleks databaseforespørgsel eller genberegning af placeringen ved hver sidevisning.
# 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)Spillerens placering og spillere i nærheden
To almindelige leaderboard-funktioner ud over »vis top 10« er at vise en spillers placering og at vise spillere i nærheden af en bestemt spiller. Begge dele er trivielle med Redis' sorterede sæt. ZREVRANK returnerer en spillers nulbaserede placering i faldende scoreorden. Hvis du vil vise 5 spillere over og under en spiller, skal du hente spillerens placering og derefter bruge ZREVRANGE fra placering-5 til placering+5. Det giver en personlig leaderboard-visning med to Redis-kommandoer — der er ikke behov for komplekse SQL-vinduesfunktioner.
# 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)Begrænsning af anmodningshastighed med Redis
Begrænsning af anmodningshastighed (begrænsning af, hvor mange anmodninger en klient kan sende i et tidsvindue) er endnu et værdifuldt anvendelsesområde for Redis. Algoritmen med glidende vindue bruger et sorteret sæt, hvor hvert medlem er et tidsstempel for en anmodning. Ved hver anmodning: Fjern medlemmer, der er ældre end vinduet, tæl de resterende medlemmer, afvis anmodningen, hvis antallet overskrider grænsen, og tilføj det nye tidsstempel. Det implementerer præcis begrænsning af anmodningshastigheden med et glidende vindue og millisekundopløsning — langt mere nøjagtigt end tællere med faste vinduer og uden belastningen fra en 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 limitedDistribueret låsning med Redis
Distribuerede låse koordinerer eksklusiv adgang til en delt ressource på tværs af flere applikationsservere. Redis-kommandoen SET key value NX EX ttl giver atomisk erhvervelse af låsen — den angiver kun nøglen, hvis den ikke findes (NX = Not eXists), og angiver en TTL for at forhindre deadlocks, hvis indehaveren går ned. Når handlingen er fuldført, sletter indehaveren nøglen. Redlock-algoritmen (som bruger flere Redis-noder til at opnå et quorum) giver en mere robust distribueret lås, men øger kompleksiteten. Til de fleste anvendelsesområder er en lås på en enkelt Redis-node tilstrækkelig.
# 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)Sessionslagring: ElastiCache sammenlignet med DynamoDB
Både ElastiCache Redis og DynamoDB kan lagre sessionsdata, men de har forskellige afvejninger. ElastiCache Redis: mikrosekund-latenstid, lagring i hukommelsen (flygtig, medmindre persistens er aktiveret), enklere datamodel, kræver VPC. DynamoDB: latenstid på encifrede millisekunder (DAX kan matche Redis), fuldt administreret uden en klynge, der skal vedligeholdes, holdbar som standard, globalt tilgængelig med Global Tables, serverløs med kapacitet efter behov. Til SAA-C03-eksamen: Hvis spørgsmålet fremhæver mikrosekund-latenstid eller komplekse handlinger i hukommelsen, skal du vælge Redis. Hvis det fremhæver holdbarhed, serverløshed eller global skala, skal du overveje DynamoDB.
Geospatial indeksering med Redis
Redis har en indbygget geospatial datatype (GEO-kommandoer), der lagrer breddegrads- og længdegradskoordinater og muliggør nærhedsforespørgsler. Med GEOADD, GEODIST og GEORADIUS (nu GEOSEARCH i Redis 6.2) kan du finde alle positioner inden for en given radius fra et punkt på O(n + log n)-tid. Anvendelsesområder: find chauffører i nærheden (samkørsel), find restauranter inden for 5 km, og sortér søgeresultater efter afstand. Det eliminerer behovet for en separat geospatial database og holder positionsforespørgsler på hastigheder fra hukommelsen.
# 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 til optælling af unikke besøgende
En HyperLogLog er en probabilistisk datastruktur, der estimerer antallet af unikke elementer i et sæt ved hjælp af en fast mængde hukommelse (12 KB i Redis), uanset hvor mange unikke elementer der tilføjes. Den har en standardfejl på cirka 0,81 %. Brug PFADD til at tilføje elementer og PFCOUNT til at hente estimatet. Det er perfekt til at tælle unikke dagligt aktive brugere, unikke sidevisninger eller unikke IP-adresser, når nøjagtige optællinger ikke er nødvendige, og hukommelseseffektivitet er vigtig. Lagring af millioner af unikke bruger-ID'er som et Redis-sæt ville bruge flere GB; HyperLogLog bruger 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}')Hurtig kontrol
Afprøv din forståelse af AWS Solutions Architect- (SAA-C03-)koncepterne fra denne lektion.
Opsummering af lektionen
I denne lektion lærte du, at Redis-sessionslagring muliggør tilstandsløs horisontal skalering ved at give alle instanser adgang til en delt sessionstilstand med latenstid under et millisekund, at Redis' sorterede sæt driver leaderboards i realtid med placeringsforespørgsler på O(log n), og at specialiserede Redis-datatyper (HyperLogLog til optælling af unikke elementer, GEO til nærhed og distribuerede låse) effektivt løser almindelige arkitekturproblemer. Dette afslutter kurset Caching med ElastiCache — næste gang udforsker vi arkitekturer med høj tilgængelighed og fejltolerance.
Lær Cloud & IT Cert Prep med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 150
- Lektioner
- 600
Ofte stillede spørgsmål
Er lektionen “Sessionslagring og leaderboard-mønstre” gratis?
Ja — hele teksten til “Sessionslagring og leaderboard-mønstre” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Cloud & IT Cert Prep-kurset, skal du opgradere til CoddyKit PRO. Cloud & IT Cert Prep-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Sessionslagring og leaderboard-mønstre”?
Brug ElastiCache til at aflaste HTTP-sessionstilstand fra dine applikationsservere, og implementér leaderboards i realtid med Redis-sorterede sæt Du øver dig i Cloud & IT Cert Prep med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Cloud & IT Cert Prep?
Der kræves ingen tidligere erfaring. Cloud & IT Cert Prep på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.
Hvor lang tid tager lektionen “Sessionslagring og leaderboard-mønstre”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Cloud & IT Cert Prep-lektion?
Ja. Alle Cloud & IT Cert Prep-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Redis kontra Memcached: Valg af den rigtige motor
- ElastiCache Redis-replikationsgrupper og klyngetilstand
- Cachingstrategier: Lazy Loading og Write-Through
- Sessionslagring og leaderboard-mønstre