De content op deze site is vertaald met behulp van kunstmatige intelligentie (AI) of machinevertalingstechnologie en kan fouten bevatten.

Skip to content

Hoe de cache van Roblox 1,38 miljard QPS volhield, ver boven de limieten van Redis

Omgaan met een tienvoudige toename van het verkeer met het oog op betrouwbaarheid en efficiëntie

In de grootschalige multiplayer-spelomgeving van Roblox lezen en schrijven gebruikers gegevens met een volume en snelheid die standaard cachingpatronen zouden overbelasten. Een gebruiker merkt misschien geen vertraging van 200 ms op een standaardwebpagina die statische gegevens in de cache opslaat, maar een vertraging van 200 ms bij het ophalen van interactiegegevens of servermetadata op Roblox kan het spel vertragen en de gesimuleerde spelwereld verstoren. Roblox werkt met een ecosysteem van onvoorspelbare, zeer snelle, vluchtige gegevens die binnen milliseconden moeten worden opgehaald om de immersie te behouden. 

Onze cachinglaag is ontworpen om te fungeren als een enorme schokdemper tussen miljoenen gelijktijdige gebruikers en onze persistente opslag. Deze verwerkt een piekbelasting van 1,38 miljard queries per seconde (QPS), waarbij afzonderlijke logische clusters meer dan 100 miljoen QPS halen. In dit bericht lichten we een tipje van de sluier op over hoe we een federatieve caching-service hebben ontworpen om verder te schalen dan de limieten van Redis®-knooppunten voor een enorme doorvoer, terwijl we tegelijkertijd een ongekende 10-voudige toename van het verkeer op ons grootste cluster het hoofd bieden.

Totale cache-lees-/schrijfbewerkingen over alle caching-knooppunten.

Schaalbaarheid voorbij de grenzen van de sector om aan de steeds groeiende vraag te voldoen

Bij Roblox is onze caching-service gebouwd op basis van de Redis®-technologie, en één Redis®-cluster kan in principe tot 1.000 knooppunten ondersteunen. De empirische en door de sector geaccepteerde limiet ligt echter veel lager: rond de 400–500 knooppunten.1 Dit komt door het gedecentraliseerde Gossip-protocol van Redis®, dat gebruikmaakt van communicatie tussen knooppunten om informatie over de gezondheid, status en shard-toewijzing te delen. In clusters met meer dan een paar honderd knooppunten begint de communicatie van het Gossip-protocol aanzienlijke CPU- en netwerkbronnen te verbruiken. Elk knooppunt moet statusupdates van een steeds groter wordend aantal peers verwerken, waardoor er bronnen worden onttrokken aan de primaire taak: het leveren van data met lage latentie. Deze overhead van het besturingsvlak kan leiden tot instabiliteit en onvoorspelbare prestaties, en daarom hanteren managed cloudproviders limieten voor het aantal knooppunten. Het is een praktisch plafond dat niet overschreden kan worden zonder de betrouwbaarheid in gevaar te brengen.

Deze praktische limiet voor één cluster is niet voldoende om een platform te ondersteunen dat op de schaal van Roblox draait, waar de grootste backend-service op piekmomenten meer dan 100 miljoen QPS van een van onze logische Redis®-clusters vroeg, een stijging van 10 miljoen binnen drie maanden.

We hebben een federatieve architectuur geïmplementeerd om deze architecturale beperking te overwinnen, waarbij we een client-reverse-proxy voor meerdere kleinere, onafhankelijke Redis®-clusters hebben geplaatst. We hanteren een limiet van 400 nodes per cluster om voorspelbare prestaties te garanderen. 

Vanuit het perspectief van onze duizenden applicaties en diensten presenteert de client reverse proxy deze uiteenlopende clusters als één enkele, uniforme en schaalbare cachingdienst. Deze federatie stelt ons in staat om vrijwel onbeperkt horizontaal te schalen door simpelweg meer clusters aan de federatie toe te voegen, waarbij we de beperkingen van het Gossip-protocol volledig omzeilen. Vandaag de dag bestaat onze grootste afzonderlijke caching-implementatie uit meer dan 6.000 Redis®-knooppunten, die worden ondersteund door meer dan 15 onafhankelijke Redis®-clusters – een schaal die alleen mogelijk is dankzij dit federatieve model.

Een schematisch overzicht van de federatieve architectuur.

Het migratieproces in drie fasen

De overstap van een traditionele opzet naar een federatieve architectuur, terwijl we honderden actieve productieclusters moesten beheren, was een enorme klus. Eind 2024 naderden veel van deze clusters al onze limiet van 400 knooppunten, waardoor een overgang naar een model met een hogere capaciteit dringend nodig was. De grootste uitdaging was dat standaard Redis®-instanties geïsoleerd werken en geen inherent bewustzijn hebben van andere clusters, waardoor een aangepaste methode nodig was om gegevens tijdens de verhuizing te repliceren.

Om dit op te lossen, hebben we een transparante, driestaps migratiepijplijn ontwikkeld die is ontworpen om diensten over te zetten zonder enige betrokkenheid van de klant of wijzigingen aan de applicatiekant.

De migratieworkflow

  1. Dubbel schrijven: We hebben de reverse proxy van de client geconfigureerd om dubbel te schrijven, waarbij inkomende gegevens tegelijkertijd naar zowel het oorspronkelijke cluster als de nieuwe gefedereerde bestemming worden verzonden.
  2. Pariteit en leesschakeling: Zodra het dubbele schrijfproces het nieuwe cluster met identieke gegevens had gevuld, hebben we, aangezien alle gegevens gebonden zijn aan een time-to-live (TTL), het leesverkeer overgezet van het oude cluster naar de nieuwe gefedereerde architectuur.
  3. Buitengebruikstelling: Nadat we de stabiliteit van het nieuwe cluster hadden bevestigd, hebben we alle schrijfbewerkingen naar het oorspronkelijke cluster stopgezet en dit buiten gebruik gesteld.

We hebben onze meest kritieke diensten met succes verplaatst naar een gefedereerd model dat meer dan 6.000 knooppunten ondersteunt, wat de beperkingen van een enkel Redis®-cluster ver overstijgt. 

Omgaan met de explosieve groei van Grow a Garden

Vanaf april 2025 werden we geconfronteerd met een capaciteitsuitdaging van een omvang die maar weinig diensten ooit meemaken. De aanleiding was het fenomenale succes van Grow a Garden. Binnen enkele weken na de lancering begon Grow a Garden niet alleen Roblox-records te breken, maar ook alle records in de game-industrie voor gelijktijdige gebruikers (CCU). In slechts drie maanden tijd steeg het aantal spelers van de game van ons vorige CCU-record voor één game van 2,8 miljoen spelers naar een piek van meer dan 21 miljoen. Deze explosieve groei zorgde voor 10 keer meer verkeer naar ons grootste Redis®-cluster en 3 keer meer verkeer naar de totale caching.

Roblox draait onze caching-systemen op fysieke machines in onze eigen datacenters, en deze ongekende groei maakte geen deel uit van ons capaciteitsplan voor de lange termijn. Om deze vloedgolf te overleven en het platform stabiel te houden, moesten we de efficiëntie van ons bestaande machinepark drastisch verbeteren en tegelijkertijd prioriteit geven aan betrouwbaarheid. 

Efficiëntie verbeteren tijdens de piek

Ten eerste moesten we de meest impactvolle knelpunten in ons systeem identificeren, zodat we prioriteit konden geven aan optimalisatiewerkzaamheden. Roblox Caching draait op twee verschillende hardwarepools: één voor Redis®-backendknooppunten en één voor Envoy. Onze Redis®-vloot is voornamelijk geheugengebonden, terwijl de clientproxy rekenkrachtgebonden is. 

Voor onze geheugengebonden Redis®-vloot hebben we een nieuw planningsbeleid geïmplementeerd om het geheugengebruik beter te verdelen over onze groepen fysieke machines. We hebben ook de containergrootte verfijnd om geheugenfragmentatie te verminderen. 

Om het CPU-gebruik te verbeteren, hebben we twee belangrijke optimalisaties doorgevoerd in ons cachesysteem:

  1. Automatische schaalbaarheid van de clientproxy: we hebben het beleid voor automatische schaalbaarheid aangepast voor onze rekenintensieve clientproxy-vloot. Door de toegestane afwijking van de doel-CPU te verlagen, hebben we een hoger gemiddeld CPU-gebruik voor taken bereikt zonder de schaalbaarheidsdrempel te wijzigen.
  2. Interne cluster-statuscontroles: We hebben de interne statuscontroles geoptimaliseerd om onnodige heartbeats te elimineren, waarbij we het oorspronkelijke detectie-interval hebben behouden en tegelijkertijd rekenkracht hebben bespaard.

Deze wijzigingen resulteerden in een verbetering van bijna 10% in CPU-gebruik. Ten slotte hebben we deze twee zeer verschillende workloads ondergebracht in dezelfde machinepool met cgroup-isolatie op containerniveau, waardoor onze totale capaciteitsbehoefte met 25% is afgenomen.

Techniek voor onwrikbare betrouwbaarheid

Betrouwbaarheid bleef onze topprioriteit, zelfs toen we ons haastten om aan de recordbrekende vraag te voldoen. 

End-to-end observeerbaarheid

We hebben ons eerst gericht op het in kaart brengen van potentiële storingen door fors te investeren in onze observability-stack voor uitgebreide, end-to-end statusmonitoring van ons caching-systeem. Door het succes van de server en storingen aan de clientzijde gedurende de gehele levenscyclus van een verzoek te volgen, konden we problemen snel opsporen en diagnosticeren, waardoor we vaak de impact op gebruikers konden voorkomen. We hebben bijvoorbeeld hotkey-detectie toegevoegd, die live verkeer bemonstert om gegevens te identificeren die overmatig worden geraadpleegd en de cachinglaag belasten. Wanneer het systeem een hotkey signaleert, kunnen we het verkeer naar deze keys proactief afremmen, zowel aan de server- als aan de clientzijde, om overbelasting van het systeem te voorkomen.

Omgaan met storingen

In elk gedistribueerd systeem van deze omvang doen zich soms gedeeltelijke storingen voor. We hebben ons systeem zo ontworpen dat deze storingen soepel worden afgehandeld en de impact ervan tot een minimum wordt beperkt.

  • Gedeeltelijke storingen in batchverzoeken: We hebben het systeem opnieuw ontworpen om gedeeltelijke storingen in batchverzoeken op te vangen. Voorheen zou één enkele fout in een geschateld batchverzoek de hele batch doen mislukken. Nu kunnen verzoeken slagen, zelfs als sommige sleutels niet kunnen worden opgehaald.
  • Head-of-line blocking beperken: Van caching-systemen wordt verwacht dat ze snel zijn. Zelfs een kleine vertraging in het netwerk kan ervoor zorgen dat verzoeken zich opstapelen en een time-out krijgen, een fenomeen dat bekend staat als head-of-line blocking. We hebben intelligente herhalingsmechanismen en strategieën voor het delen van verbindingen geïmplementeerd in zowel de client- als de proxy-laag om te voorkomen dat één traag verzoek invloed heeft op andere.
  • Fout- en latentie-injectie: Om de veerkracht te testen, injecteren we regelmatig gecontroleerde storingen (uitval van knooppunten, uitval van racks, netwerklatentie, API-fouten) in de productie met behulp van ons framework voor foutinjectie. Door het systeemgedrag onder deze omstandigheden te analyseren, identificeren en verhelpen we proactief zwakke punten, waardoor we continue betrouwbaarheid garanderen.

Veerkracht aan de clientzijde

Om te voorkomen dat ons cachesysteem overbelast raakt door plotselinge pieken in het verkeer, hebben we robuuste veerkracht tegen storingen aan de clientzijde geïmplementeerd. Dit mechanisme werkt op applicatieniveau en zorgt ervoor dat geen enkele dienst de cachebronnen kan monopoliseren.

  • Snelheidsbeperking voor stroomregeling: Onze client heeft een limiet op het totale uitgaande verkeer, waardoor er niet meer verzoeken worden verzonden dan de backend-service aankan. Verzoeken worden afgeremd wanneer deze limiet wordt overschreden, waardoor de service niet overbelast raakt.
  • Herhalings- en time-outmechanismen: onze clientbibliotheken maken gebruik van zorgvuldig afgestemde herhalingsmechanismen, waaronder time-outs en een herhalingsbudget, om 'thundering herd'-problemen te voorkomen. Dit beperkt de omvang van de impact, maakt bronnen vrij en verbetert de algehele reactiesnelheid van het systeem door te voorkomen dat het systeem overbelast raakt door oneindige vastlopers en gelijktijdige herhalingspogingen.

De toekomst van caching bij Roblox

De caching-reis van Roblox begon met bare-metal Redis®-clusters die rechtstreeks door elke applicatie-eigenaar werden beheerd, ging vervolgens over naar Memcached-clusters die door ons caching-team werden beheerd, en maakte uiteindelijk de overstap naar een Redis®-as-a-service-model, waarbij een Redis®-cluster als een beheerde service wordt aangeboden. Hoewel dit model zeer effectief is gebleken op onze huidige schaal, erkennen we de beperkingen ervan op het gebied van service-efficiëntie en resource-isolatie voor een platform dat zo dynamisch is als Roblox.

Naarmate het platform blijft groeien, zijn we van plan om aanzienlijk te investeren in een multitenant caching-service van de volgende generatie, gebouwd op ValKey. Deze architectuur is ontworpen om de kosten drastisch te verlagen door gemeenschappelijke resources te delen via multitenancy, terwijl de isolatie van data, resources en storingen voor elke tenant wordt gewaarborgd. Ons doel is om de prestaties, schaalbaarheid, betrouwbaarheid en kostenefficiëntie van onze caching-infrastructuur aanzienlijk te verbeteren om te voldoen aan de eisen van de steeds grotere ervaringen op Roblox.

Dankwoord: 

Deze prestatie was het resultaat van een gezamenlijke inspanning. Dank aan de andere teamleden die een belangrijke bijdrage hebben geleverd: Utkarsh Singh, Karthick Ramachandran, Vineesha Kasireddy, Weiji Hu en Leon Gao.

1AWS beperkt ElasticCache tot 500 knooppunten.

*Redis is een handelsmerk van Redis Labs Ltd. Alle rechten hierop zijn voorbehouden aan Redis Labs Ltd.