AWS Solutions Architect · Oppitunti

Istuntojen tallennus ja tulostaulukuviot

Käytä ElastiCachea HTTP-istuntojen tilan siirtämiseen pois sovelluspalvelimilta ja toteuta reaaliaikaisia tulostauluja Redisin järjestetyillä joukoilla.

Oppitunti 4/413 vaihetta

Istuntojen tallennus ja tulostaulukuviot on ilmainen AWS Solutions Architect-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu AWS Solutions Architect-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. AWS Solutions Architect-kurssilla on yhteensä 4 oppituntia.

Palvelinpuolen istuntojen ongelma

Perinteiset verkkosovellukset tallentavat istuntotiedot palvelimen muistiin. Tämä toimii yhdellä palvelimella, mutta rikkoutuu vaakasuuntaisessa skaalauksessa — jos käyttäjän seuraava pyyntö reititetään toiselle EC2-instanssille, sillä instanssilla ei ole tietoa käyttäjän istunnosta ja käyttäjä kirjataan ulos. Tahmeat istunnot (istunnon sitominen kuormantasaajaan) ratkaisevat ongelman osittain, mutta heikentävät kuormantasaamisen tehokkuutta. Skaalautuva ratkaisu on siirtää istunnon tila jaettuun, pieniviiveiseen tallennussäilöön, johon kaikki instanssit pääsevät käsiksi — juuri tämän ElastiCache Redis tarjoaa.

Redis istuntojen tallennukseen

Istuntojen tallentaminen Redisiin tarjoaa seuraavat edut: alle millisekunnin istuntoluvut kaikilta sovelluspalvelimilta, sisäänrakennetun TTL:n istuntojen automaattiseen vanhenemiseen, atomiset istuntopäivitykset kilpailutilanteiden estämiseksi sekä mahdollisuuden mitätöidä istunto heti poistamalla avain. Sovellus tallentaa istunnon tunnisteen evästeeseen ja hakee jokaisen pyynnön yhteydessä istunnon tunnisteella istuntotiedot Redisistä. Kaikki sovelluspalvelimet käyttävät samaa Redis-instanssia, joten mikä tahansa palvelin voi käsitellä minkä tahansa käyttäjän pyynnön.

# 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

Istunnon TTL ja liukuva vanheneminen

Kiinteä TTL tarkoittaa, että istunto vanhenee N sekuntia luomisen jälkeen toiminnasta riippumatta. Liukuva TTL (vanhenemisen jatkaminen jokaisen käyttökerran yhteydessä) on käyttäjäystävällisempi — istunto vanhenee N sekuntia viimeisimmän käyttökerran jälkeen. Toteuttakaa liukuva TTL Redisissä kutsumalla EXPIRE- (tai EXPIREAT-) komentoa istuntoavaimelle jokaisen onnistuneen istuntoluvun yhteydessä, jotta vanhenemisajan laskenta alkaa uudelleen. Näin aktiivisia käyttäjiä ei kirjata odottamatta ulos, kun taas epäaktiiviset istunnot vanhenevat automaattisesti ja vapauttavat muistia.

# 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

Ostoskori Redisissä

Verkkokaupan ostoskori sopii luontevasti Redisiin. Kukin ostoskori tallennetaan Redis Hash -rakenteena, jossa kenttänä on tuotteen SKU ja arvona määrä. Hash-operaatiot, kuten HINCRBY ja HDEL, mahdollistavat atomiset päivitykset ilman koko ostoskorin lukemista ja uudelleenkirjoittamista. Kun tähän yhdistetään TTL (hylättyjen ostoskorien vanhentamiseen 24 tunnin jälkeen), Redis tarjoaa nopean ja pysyvän ostoskoritallennuksen ilman relaatiotietokannan käytön aiheuttamaa kuormaa jokaiselle ostoskoriin lisäämiselle.

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

Tulostauluarkkitehtuuri

Reaaliaikainen tulostaulu on perinteinen Redis-käyttötapa, jonka mahdollistavat järjestetyt joukot (ZSETit). Jokaisella pelaajatietueella on pistemäärä, ja järjestetty joukko pitää jäsenet jatkuvasti pistemäärän mukaisessa nousevassa järjestyksessä. Tulostaulukyselyt (parhaat N pelaajaa, pelaajan sijoitus ja tietyn pistemäärävälin pelaajat) ovat aikavaativuudeltaan O(log n) tai O(log n + m) — erittäin nopeita jopa miljoonille pelaajille. Redis-järjestetyt joukot muodostavat perustan monille pelien, kuntoilusovellusten ja sosiaalisten palvelujen sijoitusominaisuuksille ilman monimutkaisia tietokantakyselyitä tai sijoituksen uudelleenlaskentaa jokaisella sivun katselukerralla.

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

Pelaajan sijoitus ja lähellä olevat pelaajat

Kaksi yleistä tulostauluominaisuutta "näytä 10 parasta" -toiminnon lisäksi ovat pelaajan sijoituksen näyttäminen ja tietyn pelaajan lähellä olevien pelaajien näyttäminen. Molemmat ovat Redis-järjestettyjen joukkojen avulla yksinkertaisia. ZREVRANK palauttaa pelaajan nollapohjaisen sijoituksen laskevassa pistemääräjärjestyksessä. Jos haluat näyttää viisi pelaajaa pelaajan ylä- ja alapuolelta, hae ensin hänen sijoituksensa ja käytä sitten ZREVRANGE-komentoa välillä sijoitus−5–sijoitus+5. Näin saat henkilökohtaisen tulostaulunäkymän kahdella Redis-komennolla — monimutkaisia SQL-ikkunafunktioita ei tarvita.

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

Pyyntöjen rajoittaminen Redisillä

Pyyntöjen rajoittaminen (sen rajoittaminen, kuinka monta pyyntöä asiakas voi tehdä tietyn ajanjakson aikana) on toinen Redis-järjestelmän arvokas käyttötapa. Liukuva aikaikkuna-algoritmi käyttää järjestettyä joukkoa, jonka jokainen jäsen on pyynnön aikaleima. Jokaisen pyynnön yhteydessä poistetaan aikaikkunaa vanhemmat jäsenet, lasketaan jäljelle jäävät jäsenet, hylätään pyyntö, jos määrä ylittää rajan, ja lisätään uusi aikaleima. Näin toteutetaan tarkka liukuvan aikaikkunan rajoitus millisekunnin tarkkuudella — huomattavasti kiinteän aikaikkunan laskureita täsmällisemmin ja ilman tietokannan aiheuttamaa kuormitusta.

# 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

Hajautettu lukitus Redisillä

Hajautetut lukot koordinoivat jaetun resurssin yksinomaista käyttöä useiden sovelluspalvelinten välillä. Redisin SET key value NX EX ttl -komento tarjoaa atomisen lukon hankinnan: se asettaa avaimen vain, jos sitä ei ole olemassa (NX = Not eXists), ja määrittää TTL:n estämään lukkiutumisen, jos lukon haltija kaatuu. Kun toiminto valmistuu, haltija poistaa avaimen. Redlock-algoritmi (jossa käytetään useita Redis-solmuja päätösvaltaisuuden saavuttamiseksi) tarjoaa vankemman hajautetun lukon, mutta lisää monimutkaisuutta. Useimmissa käyttötapauksissa yhden Redis-solmun lukko riittää.

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

Istuntojen tallennus: ElastiCache vai DynamoDB

Sekä ElastiCache Redis että DynamoDB voivat tallentaa istuntotietoja, mutta niiden kompromissit ovat erilaiset. ElastiCache Redis: mikrosekuntien viive, muistissa oleva (haihtuva, ellei pysyvyyttä ole otettu käyttöön), yksinkertaisempi tietomalli, edellyttää VPC:tä. DynamoDB: yksinumeroisten millisekuntien viive (DAX voi yltää Redisin tasolle), täysin hallittu eikä ylläpidettävää klusteria, oletusarvoisesti kestävä, maailmanlaajuisesti käytettävissä Global Tables -ominaisuudella ja palvelimeton tarvittaessa varattavalla kapasiteetilla. SAA-C03-kokeessa: jos kysymyksessä korostetaan mikrosekuntien viivettä tai monimutkaisia muistissa suoritettavia toimintoja, valitse Redis. Jos siinä korostetaan kestävyyttä, palvelimettomuutta tai maailmanlaajuista skaalautuvuutta, harkitse DynamoDB:tä.

Paikkatietoindeksointi Redisillä

Redisissä on sisäänrakennettu paikkatietotietotyyppi (GEO-komennot), joka tallentaa leveys- ja pituuskoordinaatteja ja mahdollistaa läheisyyskyselyt. Komentojen GEOADD, GEODIST ja GEORADIUS (Redis 6.2:ssa nykyinen komento on GEOSEARCH) avulla voit etsiä kaikki sijainnit tietyn säteen sisältä pisteen ympäriltä ajassa O(n + log n). Käyttötapauksia ovat lähellä olevien kuljettajien etsiminen (kyytien jakaminen), 5 kilometrin säteellä olevien ravintoloiden etsiminen ja hakutulosten järjestäminen etäisyyden mukaan. Näin erillistä paikkatietokantaa ei tarvita ja sijaintikyselyt pysyvät muistissa suoritettavien operaatioiden nopeudella.

# 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 yksittäisten kävijöiden laskemiseen

HyperLogLog on probabilistinen tietorakenne, joka arvioi joukon yksittäisten alkioiden määrän käyttäen kiinteän määrän muistia (Redisissä 12 kt) riippumatta lisättyjen yksittäisten alkioiden määrästä. Sen vakiovirhe on noin 0,81 %. Lisää alkioita komennolla PFADD ja hae arvio komennolla PFCOUNT. Tämä sopii erinomaisesti päivittäin aktiivisten yksittäisten käyttäjien, yksittäisten sivukatselujen tai yksittäisten IP-osoitteiden laskemiseen, kun tarkkaa lukumäärää ei tarvita ja muistin tehokas käyttö on tärkeää. Miljoonien yksittäisten käyttäjätunnusten tallentaminen Redis Set -joukkona kuluttaisi gigatavuja, kun taas HyperLogLog käyttää 12 kt.

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

Pikatarkistus

Testatkaa ymmärrystänne tämän oppitunnin AWS Solutions Architect (SAA-C03) -käsitteistä.

Oppitunnin yhteenveto

Tässä oppitunnissa opitte, että Redis-istuntojen tallennus mahdollistaa tilattoman horisontaalisen skaalauksen antamalla kaikille instansseille pääsyn jaettuun istunnon tilaan alle millisekunnin viiveellä, Redis-järjestetyt joukot mahdollistavat reaaliaikaiset tulostaulut O(log n) -sijoituskyselyillä ja Redis-erikoistietotyypit (HyperLogLog yksittäisten alkioiden laskemiseen, GEO läheisyyskyselyihin ja hajautetut lukot) ratkaisevat yleisiä arkkitehtuuriongelmia tehokkaasti. Tämä päättää ElastiCache-välimuistia käsittelevän kurssin — seuraavaksi tutustumme korkean käytettävyyden ja vikasietoisuuden arkkitehtuureihin.

Aloita maksutta

Opi AWS Solutions Architect tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
30
Oppitunnit
120

Usein kysytyt kysymykset

Onko oppitunti ”Istuntojen tallennus ja tulostaulukuviot” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa AWS Solutions Architect-oppimispolun 3 oppituntia, myös oppitunnin “Istuntojen tallennus ja tulostaulukuviot”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. AWS Solutions Architect-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Istuntojen tallennus ja tulostaulukuviot”?

Käytä ElastiCachea HTTP-istuntojen tilan siirtämiseen pois sovelluspalvelimilta ja toteuta reaaliaikaisia tulostauluja Redisin järjestetyillä joukoilla. Harjoittelet AWS Solutions Architect-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni AWS Solutions Architect-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin AWS Solutions Architect-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”Istuntojen tallennus ja tulostaulukuviot”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä AWS Solutions Architect-oppitunnilla?

Kyllä. Jokainen AWS Solutions Architect-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Redis vai Memcached: oikean moottorin valinta
  2. ElastiCache Redis -replikointiryhmät ja klusteritila
  3. Välimuististrategiat: lazy loading ja write-through
  4. Istuntojen tallennus ja tulostaulukuviot
← Takaisin: AWS Solutions Architect