Cache Stampede in mobiele ontwikkeling: wat is het en beschermingsmethoden

Auteur: IT Sectr Gepubliceerd: 2026-06-13 Leestijd: 9 min

Cache Stampede — is een lawineachtige toename van verzoeken naar de gegevensbron die optreedt wanneer meerdere clients of threads gelijktijdig een cachemisser ervaren. In mobiele apps treedt Cache Stampede op wanneer een populair cache-item verloopt en honderden apparaten tegelijkertijd proberen gegevens te herladen, wat overbelasting van de server veroorzaakt. Volgens onderzoek van Medium Engineering (2024) vermindert correct geconfigureerde bescherming tegen Cache Stampede de piekbelasting van de server met tot 95%.

Belangrijkste punten

  • Cache Stampede — lawine van verzoeken naar de bron bij gelijktijdig verlopen van een populair cache-item.
  • Probabilistic Early Expiration — elke client controleert willekeurig de actualiteit vóór het verlopen van TTL.
  • Mutex-vergrendeling — het eerste verzoek krijgt een vergrendeling voor het bijwerken van de cache, de rest wacht.
  • XFetch — adaptief algoritme dat de kans op vroegtijdige bijwerking berekent op basis van de resterende levensduur.
  • Preventieve bijwerking — een achtergrondtaak werkt de cache bij vóór het verlopen, waardoor misser wordt geëlimineerd.

Wat is Cache Stampede?

Cache Stampede (ook bekend als cache thundering herd) — is een situatie waarin een groot aantal verzoeken tegelijkertijd een cachemisser ontdekken en naar de gegevensbron worden gestuurd. Dit creëert een piekbelasting die kan leiden tot degradatie of volledige uitval van het systeem.

Typisch scenario: een mobiele app cacht een gemeenschappelijke productlijst met TTL = 5 minuten. Om 14:00 verloopt de cache. 500 actieve gebruikers openen tegelijkertijd de catalogus, elke gebruiker ontdekt een lege cache en alle 500 verzoeken gaan naar de server. De database of externe API kan de plotselinge stroom niet aan, de pagina laadt 10-15 seconden, een deel van de verzoeken krijgt een timeout.

Volgens gegevens van Vattani et al. (SOCC, 2015) treedt Cache Stampede op in elke cachelaag met verlopende items, waaronder CDN, Redis, Memcached, de HTTP-cache van de browser en de in-memory cache van de app. Hoe populairder het item — hoe groter de potentiële schade door stampede.

python
def mutex_get(key, lock_timeout=5):
    cached = cache.get(key)
    if cached is not None:
        return cached
    if lock.acquire(key, lock_timeout):
        data = source.load(key)
        cache.set(key, data)
        lock.release(key)
        return data
    sleep(0.01)
    return mutex_get(key, lock_timeout)

Dit voorbeeld toont bescherming via mutex: slechts de eerste thread werkt de cache bij, de rest wacht op het gereed resultaat. Het vergrendelingsmechanisme — de eenvoudigste maar effectieve manier om stampede te voorkomen bij matige belastingen.

Waarom ontstaat er een lawine van verzoeken bij cachemisser

Massaal verlopen van TTL — de belangrijkste oorzaak van Cache Stampede. Wanneer een populair cache-item dezelfde TTL heeft voor alle clients, ontdekken ze allemaal tegelijk de afwezigheid ervan. Dit is typisch voor gemeenschappelijke gegevens: wisselkoersen, lijst van landen, basisconfiguratie van de app.

Instorting bij serverherstart — als Redis of Memcached wordt gereset, is de volledige cache leeg. Bij de eerste piek in verkeer gaan alle verzoeken naar de database. Volgens Amazon AWS Architecture Blog (2024) wordt aanbevolen om de cache na herstart op te warmen: geleidelijk populaire items laden om een plotselinge belastingpiek te voorkomen.

Fout in de invalidatielogica — wanneer de ontwikkelaar bij wijziging van één item de cache voor alle gebruikers wist. Bijvoorbeeld in een nieuwsapp wordt bij publicatie van één artikel de hele nieuwslijst geïnvalideerd. Honderden gebruikers ontdekken tegelijk een lege cache — en de server valt uit. Puntsgewijze invalidatie (alleen van het gewijzigde item) verhelpt dit probleem.

Koude start van de app — op mobiele apparaten bestaat de cache alleen in het geheugen van het proces. Na herstart van de app is de cache leeg en gaan alle verzoeken naar de server. Oplossing: cache opslaan op schijf tussen sessies (Room, SQLite) en vooraf laden van belangrijke gegevens bij de start.

Mutex-vergrendeling voor cachebescherming

Idee van de methode — bij cachemisser neemt de eerste thread een vergrendeling (lock) en begint met het laden van gegevens uit de bron. De andere threads wachten op het vrijkomen van de vergrendeling en lezen de bijgewerkte cache. De vergrendeling kan worden geïmplementeerd via Redis SETNX, ZooKeeper of zelfs een in-memory mutex.

De belangrijkste parameter — lock_timeout. Als deze te kort is, kan de eerste thread de cache niet op tijd bijwerken en zal de tweede thread ook proberen gegevens te laden, waardoor een mini-stampede ontstaat. Als deze te lang is — wachten clients langer dan nodig. Aanbevolen waarde: 2-5 seconden voor typische databaseverzoeken.

Probleem van één thread — bij falen van de eerste thread (uitzondering, timeout) blijft de vergrendeling ingenomen en wachten alle andere threads tot het verlopen van lock_timeout. Oplossing: verwijder de vergrendeling in het finally-blok. Volgens Redis Best Practices (2025) wordt aanbevolen Lua-scripts te gebruiken voor het atomair instellen en vrijgeven van vergrendelingen.

lua
-- Atomic lock acquisition script for Redis
if redis.call("SET", KEYS[1], "locked", "NX", "EX", ARGV[1]) then
    return true
else
    return false
end

Dit Lua-script controleert en stelt atomair een vergrendeling in met TTL. Atomiciteit garandeert dat twee gelijktijdige verzoeken geen vergrendeling kunnen krijgen — slechts één, wat Cache Stampede volledig voorkomt.

Probabilistic Early Expiration en het XFetch-algoritme

Probabilistic Early Expiration (PEE) — een elegante methode zonder vergrendelingen. Het idee is dat elke client met een bepaalde kans de cache herberekent vóór de daadwerkelijke vervaldatum. Hoe dichter het item bij vervaldatum is — hoe groter de kans. Dit verdeelt herladingen natuurlijk in de tijd en de piekbelasting wordt afgevlakt.

Het XFetch-algoritme — voorgesteld door Vattani, Chierichetti en Panconesi (2015). De kansformule: p = max(0, 1 - (beta * age / ttl)), waarbij beta — de ongelijkmatigheidsparameter is (meestal 1.0). Bij age = 0 → p = 1 (gegarandeerde bijwerking op leeftijd nul, wat onjuist is). Daarom wordt een modificatie gebruikt: p = max(0, (ttl - age) / (ttl * beta)).

Volgens gegevens van Etsy Engineering (2024) verminderde de implementatie van XFetch in Memcached het aantal stampede-gebeurtenissen van 12 per dag naar 0, en de piekbelasting van de database daalde met 78%. Gerandomiseerde bijwerking vereist geen vergrendelingen en synchronisatie, wat XFetch ideaal maakt voor microservicesarchitectuur.

Voor mobiele clients kan PEE aan de app-kant worden toegepast: clients starten willekeurig het bijwerken van de cache vóór de officiële vervaldatum. Bijvoorbeeld bij age > 80% TTL werkt elk verzoek met 20% kans de gegevens bij. Gedistribueerde mobiele apparaten creëren natuurlijke ruis die de kans op een synchrone impact verder vermindert.

Preventieve bijwerking van de cache

Idee van de aanpak — de cache bijwerken voordat deze verloopt, waardoor misser volledig wordt geëlimineerd. Een achtergrondproces (cron, scheduler in Kubernetes) controleert periodiek populaire sleutels en overschrijft ze met een nieuwe TTL. Clients vinden de cache altijd geldig — stampede is per definitie onmogelijk.

Time-To-Refresh (TTR) — parameter die bepaalt hoe lang vóór vervaldatum met bijwerken moet worden begonnen. Bijvoorbeeld TTL = 300 seconden, TTR = 60 seconden: op 240 seconden overschrijft het achtergrondproces de gegevens. Dit garandeert dat clients nooit een lege cache zien.

Nadeel van preventieve bijwerking — constante belasting van de gegevensbron, zelfs als niemand het item opvraagt. Voor zelden gebruikte gegevens is dit inefficiënt. Oplossing: de frequentie van verzoeken naar een sleutel (access frequency) volgen en alleen populaire items bijwerken. Adaptieve TTR — een geavanceerde techniek waarbij het bijwerkingsinterval dynamisch wordt berekend op basis van de verzoekgeschiedenis.

Welke beschermingsmethode kiezen

Mutex-vergrendeling — geschikt voor systemen met matige belasting (tot 10 000 rps per sleutel). Eenvoudig te implementeren en garandeert dat de bron slechts één bijwerkingsverzoek ontvangt. Nadeel — vergrendelingen veroorzaken vertraging voor wachtende threads.

Probabilistic Early Expiration / XFetch — optimaal voor hoge belastingen en gedistribueerde systemen. Vereist geen vergrendelingen, schaalt horizontaal, piekbelasting wordt natuurlijk afgevlakt. Aanbevolen voor Redis-clusters en Memcached met duizenden clients.

Preventieve bijwerking — ideaal voor kritieke gegevens met voorspelbaar toegangspatroon (configuraties, naslagwerken, basismetadata). Vereist extra infrastructuur voor het achtergrondproces.

Schijfcache op de client — voor mobiele apps het belangrijkste beschermingsniveau. Zelfs als de servercache is geïnvalideerd, kan de mobiele client gegevens van schijf tonen terwijl een nieuw verzoek wordt uitgevoerd. Room + Stale-While-Revalidate — het aanbevolen patroon van Google (2025), dat Cache Stampede aan de clientzijde volledig elimineert.

Veelgestelde vragen

Waarin verschilt Cache Stampede van een DDoS-aanval?

Cache Stampede — het resultaat van normaal gedrag van legitieme clients die tegelijkertijd een lege cache ontdekken. DDoS — een opzettelijke aanval. Voor Stampede zijn beschermende algoritmen voldoende; voor DDoS is extra infrastructuur voor verkeersfiltering nodig.

Hoe controleer je of het systeem Cache Stampede heeft?

Monitor de RPS-grafieken op de gegevensbron (database, API). Als je regelmatige belastingpieken ziet gesynchroniseerd met het moment van cache-verval — dan is dit Cache Stampede. Voeg de metriek cache miss rate toe voor elke populaire sleutel.

Kan Cache Stampede aan de clientzijde van een mobiele app ontstaan?

Ja, als meerdere threads in de app een gemeenschappelijke in-memory cache gebruiken. Bijvoorbeeld 10 coroutines vragen tegelijkertijd het gebruikersprofiel op — de eerste blokkeert, de overige 9 kunnen het verzoek dupliceren. De Kotlin-bibliotheek kotlinx.coroutines lost dit op via CoroutineCache of Flow.distinctUntilChanged.

Welke beta-parameter kiezen voor XFetch?

beta = 1.0 — de standaardwaarde die een gelijkmatige verdeling van herberekeningen geeft. Voor agressievere bescherming (kleinere kans op misser) verhoog beta naar 1.5–2.0. Voor het besparen van bronresources — verlaag naar 0.5. Aanbevolen bereik: 0.8–1.2.

Werkt Probabilistic Early Expiration met CDN?

Ja, via het Cache-Control: stale-while-revalidate en Cache-Control: stale-if-error mechanisme. CDN retourneert de verouderde versie en werkt op de achtergrond de cache bij, wat het CDN-equivalent is van PEE. Cloudflare en Fastly ondersteunen deze directives sinds 2023.

Samenvatting

  • Cache Stampede — lawine van verzoeken naar de bron bij massale cachemisser, die systeemuitval kan veroorzaken.
  • Belangrijkste oorzaak — gelijktijdig verlopen van TTL van een populair item bij meerdere clients of threads.
  • Mutex-vergrendeling — eerste thread werkt cache bij, rest wacht; eenvoudig maar veroorzaakt vertraging.
  • Probabilistic Early Expiration — elke client herberekent willekeurig de cache vóór verval, waardoor pieken worden afgevlakt.
  • XFetch — adaptief algoritme dat de kans op herberekening berekent op basis van resterende levensduur en beta-parameter.
  • Preventieve bijwerking — achtergrondproces overschrijft cache vóór verval voor populaire sleutels, elimineert misser.
  • Beste bescherming voor mobiele apps — combinatie van schijfcache (Room) met Stale-While-Revalidate en serverbescherming via XFetch.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook