English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

gast
1 / ?
terug naar lessen

Twee manieren om meer belasting te dragen

Welkom

Wanneer een service begint te krompen onder belasting, staat een operator voor een keuze. Maak de bestaande machine groter (meer CPU, meer RAM, snellere schijven). Of voeg meer machines toe die elk hetzelfde werk verrichten.

Het eerste pad heet verticale schaling (scale up). Het tweede pad heet horizontale schaling (scale out).

Deze les leert waarom bijna elke moderne webarchitectuur voor horizontale schaling kiest & welke eigenschap van de werkbelasting die keuze haalbaar maakt. Het antwoord schuilt in één woord: state.

Aan het einde begrijp je:

- De kostencurven van verticale versus horizontale schaling & wanneer elk van beide zinvol is

- Wat 'stateful' & 'stateless' in de praktijk betekenen, & waarom de ene variant goedkoper vermenigvuldigd kan worden

- De wiskunde die de grootte van een replica-vloot bepaalt onder verwacht & piekverkeer

- De headroom-regel die voorkomt dat een laag instortt na het kniepunt van de wachtrij

- Waar state moet staan (het verdwijnt nooit) & hoe je het uit de lagen haalt die moeten schalen

Waarom horizontaal schalen na een bepaalde drempel wint

Verticale schaling: één groter apparaat

Voordelen: eenvoudig. Geen codeveranderingen. Geen coördinatie. Hetzelfde proces heeft nu meer CPU.

Nadelen: plafond. De grootste commercieel verkrijgbare VM heeft een eindige hoeveelheid RAM & cores. Boven dat niveau koopt geen enkel geld meer extra capaciteit. De kosten stijgen superlineair zodra je het sweet spot van het aanbod van een leverancier overschrijdt. Een falen van die ene machine laat de hele service vallen.

Horizontale schaling: Veel kleinere machines

Voordelen: geen plafond (tot aan je bereidheid om te betalen voor & machines te coördineren). Capaciteit wordt lineair toegevoegd met het aantal replica's, voorspelbaar. Een falen van een enkele replica vermindert de capaciteit met 1/N, niet met 100%.

Nadelen: vereist dat de workload dit ondersteunt. Sommige workloads (een enkele grote database, een stateful gameserver met actieve sessies) weerstaan horizontale schaling. Coördinatie & belastingverdeling worden operationele zorgen.

Het kruispunt: elke productieservice die moet overleven bij een falen van een enkele machine, moet op minstens twee machines draaien. Zodra je twee accepteert, heb je al gekozen voor horizontale schaling. Vanaf dan is de vraag niet 'moeten we dit?' maar 'hoe goedkoop kunnen we de volgende replica toevoegen?'

De belangrijkste voorwaarde: een workload die geen per-aanvraag state op de machine zelf bewaart. Dan kan elke replica elk verzoek beantwoorden, & het toevoegen van een replica voegt capaciteit toe zonder coördinatie.

Verticale vs horizontale schaling: kostencurve & plafond

Een team draait een service op een enkele VM met 8 CPUs die 800 verzoeken per seconde verwerkt bij 60% CPU-gebruik. Ze verwachten dat het verkeer over het komende jaar met een factor 4 zal groeien. Ze debatteren: huur een VM met 32 CPUs (verticaal) of draai vier identieke VM's met 8 CPUs achter een load balancer (horizontaal). Welke optie zou je aanbevelen, en noem twee redenen die verder gaan dan ruwe capaciteit.

Stateful vs. Stateless in de praktijk

State verdwijnt nooit, het verplaatst zich alleen

Stateful component: bevat informatie waarvan het verlies het gedrag zou veranderen. Een database met gebruikersaccounts. Een cache met sessietokens. Een worker die een langlopende streamingverbinding aan een specifieke gebruiker koppelt.

Stateless component: bevat geen informatie waarvan het verlies er toe zou doen. Een webtier die een request leest, een database queryt & een response schrijft. Elke request staat op zichzelf; de tier onthoudt niets tussen requests.

Belangrijk inzicht: state verdwijnt nooit uit een systeem. Het verplaatst zich naar een laag die ontworpen is om het te bewaren (een database, een Redis-cluster, een objectstore). De lagen die verkeer ontvangen, kunnen dan stateless zijn, & stateless lagen schalen horizontaal omdat elke replica elke request kan beantwoorden.

Praktische test: als je willekeurig één proces in deze tier zou doden & opnieuw zou starten, zou dan een gebruiker een fout antwoord of een verloren sessie ervaren? Zo ja, dan bevat het state. Zo nee, dan niet.

Voorbeelden

- Een Python-webproces dat requests leest, Postgres queryt en JSON teruggeeft: stateless. De state zit in Postgres.

- Een Python-webproces dat gebruikerswinkels in het lokale geheugen houdt: stateful. Als je het proces doodt, gaan de winkels verloren.

- Een WebSocket-server die open verbindingen met chatgebruikers handhaaft: stateful in de zin van verbindingen. Als het proces wordt gestopt, vallen de verbindingen weg; clients moeten opnieuw verbinden. Vaak schalen deze nog steeds horizontaal, mits er zorgvuldig mee wordt omgegaan (sticky sessions, consistent hashing).

- Een Redis-cache voor Postgres: stateful voor de cache-inhoud, maar acceptabel als cache-misses toelaatbaar zijn. Een replica-fout betekent een cache-miss, geen dataverlies.

Ontwerpen voor horizontale schaalbaarheid = de state uit de laag halen die moet schalen.

Een verdacht niveau auditen

Een team draait een aanbevelings-API op 6 backend-VM's achter een reverse proxy. De applicatie: leest een gebruikers-ID uit de request, haalt de recente activiteit van de gebruiker op uit Postgres, voert een score-algoritme uit en retourneert een lijst met aanbevolen items. Twee niet-standaard gedragingen:

- De applicatie houdt een 'recente gebruikersactiviteit'-cache in het procesgeheugen, die wordt gevuld bij de eerste request voor een gebruiker en hergebruikt wordt bij opeenvolgende requests.

- De applicatie gebruikt sticky sessions: zodra een gebruiker VM #3 raakt, gaan al hun opeenvolgende requests naar VM #3 (de proxy is geconfigureerd voor sticky routing op basis van een cookie).

Identificeer welk van deze twee gedragingen het niveau stateful maakt en leg uit wat er kapot zou gaan als het team probeerde te schalen van 6 VM's naar 12. Stel daarna een herontwerp voor dat het niveau horizontaal kan laten schalen zonder het voordeel van de gebruikers-cache te verliezen.

De Replica-formule

De eenvoudigste capaciteitsformule

Zodra een tier stateless is, wordt het dimensioneren ervan rekenkundig. Je hebt genoeg replica's nodig zodat de steady-state-belasting met dezelfde snelheid aankomt en vertrekt, met ruimte voor pieken.

De formule:

replica's = ⌈ (piekbelasting × piekfactor) / capaciteit_per_replica ⌉ + buffer

Waarbij:

- piekbelasting: het maximale aantal verzoeken per seconde dat je verwacht tijdens normale werking

- piekfactor: een vermenigvuldigingsfactor die korte uitstijgingen boven de piek dekt (meestal 1,5x tot 2x voor voorspelbaar verkeer, 3x of meer voor virale / onvoorspelbare situaties)

- capaciteit_per_replica: het aantal verzoeken per seconde dat één replica kan verwerken bij aanvaardbare latente tijd en benutting (meestal gemeten bij 70% CPU, niet bij verzadiging)

- buffer: extra replica's zodat het falen van een paar replica's de tier niet doet instorten (meestal 1-2 replica's voor kleine vlootten, 10-20% voor grotere)

Voorbeeldoplossing: een backend verwerkt 100 req/s bij 70% CPU per replica. De piekbelasting is 600 req/s. Je verwacht af en toe 2x pieken. Je wilt overleven bij 2 replica-fouten.

replicas = ⌈ (600 × 2) / 100 ⌉ + 2 = 12 + 2 = 14 replicas

De 80%-regel

De capaciteit per replica is niet het verzadigingspunt. Meet de capaciteit bij 70-80% CPU, nooit bij 100%.

Boven ongeveer 80% benutting stijgen de wachtrijcurves scherp: een wachtrij die bij 60% benutting in 10 ms verwerkt wordt, duurt 80 ms bij 90% benutting. Latency, niet doorvoer, faalt het eerst. (De bijbehorende les geometry_of_stateless_horizontal_scaling leidt deze curve wiskundig af.)

Autoscaling vs. Statische Provisioning

Statisch: provisioneer voor piek × piekmarge en accepteer de kosten van draaien bij lage benutting buiten piekuren.

Autoscaling: een controller voegt replicas toe en verwijdert ze op basis van waargenomen benutting, doel-latency of wachtrijdiepte.

Let op bij autoscaling: de opstarttijd (cold-start) is cruciaal. Als een nieuwe replica 2 minuten nodig heeft om op te starten, kan autoscaling niet reageren op een piek van 30 seconden. Geavanceerde autoscaling houdt een warme pool van vooraf gereserveerde replicas bij, net onder de drempelwaarde voor schalen omhoog.

Formule voor replica-grootte met uitgewerkt voorbeeld

Bepaal de grootte van een vloot voor een nieuwe service

Jouw team plant de lancering van een video-metadata API. Benchmarks tonen aan dat een enkele replica 250 req/s verwerkt bij 70% CPU-gebruik en een p99-latentie van 50 ms. Marketing verwacht een piekbelasting van 4.000 req/s tijdens de prime-time uren. Een gepland promotie-evenement kan kortstondig voor een piek van 3x de piekbelasting zorgen. Je wilt dat de service 3 gelijktijdige replica-storingen overleeft zonder dat het gebruik van de overgebleven replicas 80% overschrijdt.

Pas de replica-formule toe om de grootte van de startvloot te bepalen. Toon je berekening stap voor stap en leg daarna één reden uit waarom je aantal in de praktijk toch onjuist zou kunnen zijn (cold start, cache warm-up, afhankelijkheidslatentie, of wat je maar kunt onderbouwen).

Cold Start, Langzame afvoer & andere echte randgevallen

Echte vloten hebben echte randgevallen

De formule gaat ervan uit dat replica's onmiddellijk verschijnen, onmiddellijk verkeer aannemen & onmiddellijk verkeer afstoten. Geen van deze aannemen geldt in productie.

Cold start: een nieuwe replica heeft tijd nodig om het besturingssysteem op te starten, het proces te starten, configuratie te laden, caches te verwarmen & gezondheidscontroles te doorlopen. Dit kan variëren van 5 seconden (containerherstart) tot 5 minuten (volledige VM-opstart + image-pull). Autoscaling kan niet reageren op pieken die korter duren dan deze vertraging.

Langzame afvoer: een replica die uit de pool wordt verwijderd, heeft tijd nodig om lopende aanvragen af te ronden voordat deze wordt beëindigd. Anders zien gebruikers afgekorte antwoorden. Reverse proxies ondersteunen afvoer (stop met het aannemen van nieuwe aanvragen, ronde actieve aanvragen af), maar dit duurt seconden tot minuten.

Warm pool: productieloketten houden een pool van vooraf geconfigureerde, maar inactieve replica's bij die klaarstaan om verkeer over te nemen zodra er een signaal komt. Dit ruilt een kleine, constante kostenpost in voor een snelle respons op pieken.

Connection draining vs. directe afsluiting: een geordende afsluiting is belangrijk. Een SIGTERM die draining triggert duurt langer dan een SIGKILL, maar onderbreekt geen gebruikersverzoeken.

Health check window: een replica die net is gestart, kan zijn eerste health check doorstaan voordat zijn database-verbindingenpool warm is; de proxy stuurt dan echt verkeer door & de eerste twaalf verzoeken zijn traag. Stel health checks zo in dat ze de echte paden testen, niet alleen de levendigheid van het proces.

Stickiness creep: zelfs nominale stateless lagen verwerven na verloop van tijd stickiness (CDN-caches, DNS-resolvercaches, verbindingenpools). Wees sceptisch ten opzichte van 'identieke replica's' die toch anders gedragen.

Warm Pool of Reactief Autoscaling?

Je videometadaten-API (dezelfde als in de vorige vraag, dimensioneerd op 51 replica's voor stabiele piek + surge) ondervindt een 30-seconden surge tot 5x het normale verkeer telkens wanneer een nieuw virale video wordt geüpload. Autoscaling duurt momenteel 90 seconden om een nieuwe replica vanuit de koude toe te voegen (image pull + warmup). Tijdens deze 90-seconden gap stijgt de latentie scherp & time sommige verzoeken uit.

Stel een oplossing voor. Kies: (a) behoud reactief autoscaling maar stel het anders af, (b) provisioneer een warm pool van inactieve replica's, of (c) provisioneer statisch voor de 5x piek permanent. Verdedig je keuze & noem één kostenpost die de andere twee opties zouden opleggen.

Ontwerp een stateless tier onder beperkingen

Synthese

Je hebt geleerd waarom horizontale schaling wint zodra een kleine drempelwaarde wordt overschreden, wat staat in de praktijk betekent, hoe je een vloot dimensioneert onder verwachting & piekbelasting, en waar horizontale schaling aan de randen faalt.

Pas alle vier toe.

Ontwerp een backend-tier voor feed.example.com, een social-feed API. Beperkingen: capaciteit per replica 200 req/s bij 70% CPU; verwachting piekbelasting 1500 req/s; piekfactor 2,5x (af en toe trending verhalen); overleef 2 gelijktijdige replica-fouten; cold-start tijd 60 seconden; pieken kunnen 45 seconden duren; budget staat wat idle-capaciteit toe, maar geen permanente provisioning van 2,5x.

Bepaal de grootte van de stabiele vloot (toon de berekening), kies je strategie voor piekafhandeling (warm pool / reactiva autoscaling / beide) & identificeer één stuk per-gebruiker status dat de applicatie waarschijnlijk houdt & waarheen dit moet verhuizen om de tier stateless te houden.

Waar deze cursus naartoe gaat

Waar deze cursus naartoe gaat

Je hebt nu een werkend mentaal model van een stateless tier: waarom deze schaalbaar is, hoe je de grootte ervan bepaalt, wat er op de randen kapotgaat, en waar state naartoe moet wanneer je de laag die moet groeien onder druk zet.

De volgende les in deze cursus (cs_distsys_ingress_egress_separation) behandelt een subtieler probleem: zelfs een perfect gedimensioneerde stateless tier kan op verrassende manieren falen wanneer inkomend en uitgaand verkeer hetzelfde netwerkpad delen. Het klassieke voorbeeld betreft een proxy die probeert verbinding te maken met zichzelf; de oplossing bestaat uit het splitsen van één tier in twee met verschillende verantwoordelijkheden.

Begeleidelijke les: geometry_of_stateless_horizontal_scaling leidt de wachtrijcurve af, past de Wet van Little toe op een replica-fleet, en legt de geometrische betekenis van de knik bij 80% benutting uit.

Goed gedaan. Verder zo.