AWS Solutions Architect · Les

Sessiesopslag en leaderboard-patronen

Gebruik ElastiCache om HTTP-sessiestatus van uw applicatieservers te ontlasten en implementeer realtime leaderboards met gesorteerde Redis-sets.

Les 4 van 413 stappen

Sessiesopslag en leaderboard-patronen is een gratis AWS Solutions Architect-les op CoddyKit. Dit is les 4 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject AWS Solutions Architect. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus AWS Solutions Architect bevat in totaal 4 lessen.

Het probleem met sessies aan de serverzijde

Traditionele webtoepassingen slaan sessiegegevens op in het geheugen van de server. Dit werkt met één server, maar gaat mis wanneer je horizontaal schaalt: als het volgende verzoek van een gebruiker naar een andere EC2-instantie wordt gerouteerd, kent die instantie de sessie van de gebruiker niet en wordt de gebruiker uitgelogd. Sticky sessions (sessieaffiniteit in de load balancer) lossen dit gedeeltelijk op, maar verminderen de effectiviteit van load balancing. De schaalbare oplossing is om de sessiestatus te verplaatsen naar een gedeelde opslag met lage latentie die toegankelijk is voor alle instanties. Precies dat biedt ElastiCache Redis.

Redis voor sessieopslag

Sessies opslaan in Redis biedt je: sessieleesbewerkingen in minder dan een milliseconde op alle toepassingsservers, ingebouwde TTL voor het automatisch verlopen van sessies, atomische sessie-updates om racecondities te voorkomen en de mogelijkheid om een sessie onmiddellijk ongeldig te maken door de sleutel te verwijderen. De toepassing slaat de sessie-ID op in een cookie en zoekt bij elk verzoek de sessie-ID op in Redis om de sessiegegevens op te halen. Alle toepassingsservers delen dezelfde Redis, zodat elke server elk verzoek van elke gebruiker kan verwerken.

# 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

Sessie-TTL en verschuivende vervaldatum

Een vaste TTL betekent dat de sessie N seconden na het aanmaken verloopt, ongeacht de activiteit. Een verschuivende TTL (waarbij de vervaldatum bij elke toegang wordt verlengd) is gebruiksvriendelijker: de sessie verloopt N seconden na de laatste toegang. Implementeer een verschuivende TTL in Redis door bij elke geslaagde sessieleesbewerking EXPIRE (of EXPIREAT) aan te roepen op de sessiesleutel om het aftellen opnieuw in te stellen. Zo worden actieve gebruikers nooit onverwacht uitgelogd, terwijl inactieve sessies automatisch verlopen en geheugen vrijmaken.

# 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

Winkelwagentje in Redis

Een winkelwagentje voor e-commerce past goed bij Redis. Elk winkelwagentje wordt opgeslagen als een Redis Hash, waarbij het veld de SKU van het product is en de waarde de hoeveelheid. Hash-bewerkingen zoals HINCRBY en HDEL maken atomische updates mogelijk zonder het volledige winkelwagentje op te halen en opnieuw te schrijven. In combinatie met een TTL (om verlaten winkelwagentjes na 24 uur te laten verlopen) biedt Redis een snelle, persistente opslag voor winkelwagentjes zonder de overhead van een relationele database voor elke gebeurtenis waarbij een product aan het winkelwagentje wordt toegevoegd.

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

Architectuur van ranglijsten

Een ranglijst in realtime is een klassiek gebruiksscenario voor Redis, mogelijk gemaakt door gesorteerde sets (ZSETs). Elke speler heeft een score; de gesorteerde set houdt de leden voortdurend in oplopende volgorde van score. Query's voor ranglijsten (de bovenste N spelers, de rang van een speler en spelers binnen een scorebereik) hebben een complexiteit van O(log n) of O(log n + m) — extreem snel, zelfs bij miljoenen spelers. Gesorteerde sets in Redis vormen de basis van veel rangschikkingsfuncties voor games, fitness en sociale toepassingen, zonder dat je een complexe databasequery nodig hebt of de rang bij elke weergave opnieuw moet berekenen.

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

Rang en spelers in de buurt

Twee veelgebruikte functies van ranglijsten naast 'de top 10 tonen' zijn de rang van een speler tonen en spelers in de buurt van een bepaalde speler tonen. Met gesorteerde sets in Redis zijn beide eenvoudig. ZREVRANK geeft de op nul gebaseerde rang van een speler in aflopende volgorde van score terug. Als je 5 spelers boven en onder een speler wilt tonen, haal je eerst diens rang op en gebruik je vervolgens ZREVRANGE van rang-5 tot rang+5. Zo krijg je met twee Redis-opdrachten een gepersonaliseerde ranglijstweergave — complexe SQL-vensterfuncties zijn niet nodig.

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

Verzoeklimieten instellen met Redis

Verzoeklimieten instellen (beperken hoeveel verzoeken een client binnen een tijdsvenster kan doen) is nog een waardevol gebruiksscenario voor Redis. Het algoritme voor een schuivend venster gebruikt een gesorteerde set waarin elk lid een tijdstempel van een verzoek is. Bij elk verzoek worden leden die ouder zijn dan het venster verwijderd, de overgebleven leden geteld, het verzoek geweigerd als de telling de limiet overschrijdt en een nieuwe tijdstempel toegevoegd. Hiermee implementeer je nauwkeurige verzoeklimieten met een resolutie van milliseconden — veel nauwkeuriger dan tellers met een vast venster en zonder de overhead van een 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

Gedistribueerde vergrendeling met Redis

Gedistribueerde vergrendelingen coördineren exclusieve toegang tot een gedeelde bron over meerdere applicatieservers. De Redis-opdracht SET key value NX EX ttl biedt atomische vergrendelingsverwerving: de sleutel wordt alleen ingesteld als die niet bestaat (NX = Not eXists) en er wordt een TTL ingesteld om deadlocks te voorkomen als de houder crasht. Wanneer de bewerking is voltooid, verwijdert de houder de sleutel. Het Redlock-algoritme (waarbij meerdere Redis-knooppunten voor een quorum worden gebruikt) biedt een robuustere gedistribueerde vergrendeling, maar maakt de oplossing complexer. Voor de meeste gebruiksscenario's is een vergrendeling op één Redis-knooppunt voldoende.

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

Sessies opslaan: ElastiCache versus DynamoDB

Zowel ElastiCache Redis als DynamoDB kan sessiegegevens opslaan, maar ze hebben verschillende voor- en nadelen. ElastiCache Redis: latentie van microseconden, in het geheugen (vluchtig tenzij persistentie is ingeschakeld), eenvoudiger gegevensmodel, vereist een VPC. DynamoDB: latentie van enkele milliseconden (DAX kan Redis evenaren), volledig beheerd zonder cluster dat je moet onderhouden, standaard duurzaam, wereldwijd toegankelijk met Global Tables, serverloos met capaciteit op aanvraag. Voor het SAA-C03-examen geldt: als de vraag de nadruk legt op latentie van microseconden of complexe bewerkingen in het geheugen, kies je Redis. Als de nadruk ligt op duurzaamheid, serverloos werken of wereldwijde schaal, overweeg je DynamoDB.

Geospatiale indexering met Redis

Redis heeft een ingebouwd geospatiaal gegevenstype (GEO-opdrachten) dat breedtegraad- en lengtegraadcoördinaten opslaat en nabijheidsquery's mogelijk maakt. Met GEOADD, GEODIST en GEORADIUS (in Redis 6.2 nu GEOSEARCH) kun je alle locaties binnen een bepaalde straal van een punt vinden in O(n + log n) tijd. Gebruiksscenario's zijn onder meer: chauffeurs in de buurt vinden (ritdelen), restaurants binnen 5 km vinden en zoekresultaten op afstand sorteren. Zo heb je geen aparte geospatiale database nodig en blijven locatiequery's werken met de snelheid van gegevens in het geheugen.

# 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 voor het tellen van unieke bezoekers

Een HyperLogLog is een probabilistische gegevensstructuur die het aantal unieke elementen in een set schat met een vaste hoeveelheid geheugen (12 KB in Redis), ongeacht hoeveel unieke items worden toegevoegd. De standaardfout is ongeveer 0,81%. Gebruik PFADD om elementen toe te voegen en PFCOUNT om de schatting op te vragen. Dit is ideaal voor het tellen van dagelijks actieve unieke gebruikers, unieke paginaweergaven of unieke IP-adressen wanneer exacte aantallen niet nodig zijn en geheugenefficiëntie belangrijk is. Miljoenen unieke gebruikers-ID's opslaan als een Redis Set zou GB's aan geheugen gebruiken; HyperLogLog gebruikt 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}')

Korte controle

Toets je begrip van de AWS Solutions Architect-concepten (SAA-C03) uit deze les.

Samenvatting van de les

In deze les heb je geleerd dat opslag van Redis-sessies stateless horizontaal schalen mogelijk maakt doordat alle instanties toegang krijgen tot gedeelde sessiestatus met een latentie van minder dan een milliseconde, dat gesorteerde sets in Redis ranglijsten in realtime mogelijk maken met rangquery's van O(log n), en dat gespecialiseerde gegevenstypen in Redis (HyperLogLog voor unieke tellingen, GEO voor nabijheid en gedistribueerde vergrendelingen) veelvoorkomende architectuurproblemen efficiënt oplossen. Hiermee is de cursus Caching met ElastiCache voltooid — hierna bekijken we architecturen met hoge beschikbaarheid en fouttolerantie.

Gratis beginnen

Leer AWS Solutions Architect met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
30
Lessen
120

Veelgestelde vragen

Is de les “Sessiesopslag en leaderboard-patronen” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad AWS Solutions Architect, waaronder “Sessiesopslag en leaderboard-patronen”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus AWS Solutions Architect bevat in totaal 4 lessen.

Wat leer ik in “Sessiesopslag en leaderboard-patronen”?

Gebruik ElastiCache om HTTP-sessiestatus van uw applicatieservers te ontlasten en implementeer realtime leaderboards met gesorteerde Redis-sets. Je oefent met AWS Solutions Architect door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met AWS Solutions Architect te beginnen?

Ervaring vooraf is niet nodig. AWS Solutions Architect op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Sessiesopslag en leaderboard-patronen”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over AWS Solutions Architect?

Ja. Elke les over AWS Solutions Architect bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Redis versus Memcached: de juiste engine kiezen
  2. ElastiCache Redis-replicatiegroepen en clustermodus
  3. Cachingstrategieën: lazy loading en write-through
  4. Sessiesopslag en leaderboard-patronen
← Terug naar AWS Solutions Architect