Två Sätt Att Föra Mer Last
Välkomna
När en tjänst börjar knäcka under lasten står en operatör inför ett val. Gör den befintliga maskinen större (mer CPU, mer minne, snabbare diskar). Eller lägg till flera maskiner som var och en gör samma arbete.
Den första vägen kallas vertikal skalning (skala upp). Den andra går under horisontell skalning (skala ut).
Denna lektion undervisar om varför nästan varje modern webbarkitektur väljer horisontell och vilken egenskap hos arbetsbelastningen som gör den valbara. Svaret döljer sig i ett ord: stat.
Efter avslutad utbildning kommer du att förstå:
- Kostkurvorna för vertikal vs horisontell skalning & varje gång det är lämpligt
- Vad 'statfylld' & 'statlös' betyder i praktiken, & varför en av dem multipliceras billigt
- Matematiken som storleksbestämmer en replikflotta under förväntad & översvämningstrafik
- Regeln med luftunderlag som håller ett skikt från att kollapsa bortom köeffekten
- Var staten måste finnas (den försvinner aldrig) & hur man kan pressa ut den ur skikten som behöver skalas
Varför Horisontell Vinner Bortom ett Tröskelvärde
Vertikal Skalning: En Större Kartong
Fördelar: enkelt. Inga kodändringar. Ingen koordinering. Samma process nu har mer CPU.
Nackdelar: tak. Den största kommersiellt tillgängliga VM:en har begränsad minne & kärnor. Ovanför det, inga pengar köper mer utrymme. Kostnader går exponentiellt efter sweet spot för ett leverantörs erbjudande. En felaktighet i den ena maskinen tar hela tjänsten ner.
Horisontell Skalning: Många Mindre Kartonger
Fördelar: inget tak (upp till din vilja att betala för & koordinera maskiner). Kapacitet lägger sig linjärt med replikantalet, förutsägbart. En enda replikas fel tar bort 1/N av kapaciteten, inte 100%.
Nackdelar: kräver arbetsbelastningen att stödja det. Vissa arbetsbelastningar (en enda stor databas, en statfylld spelserver som håller levande sessioner) motstår horisontell skalning. Koordinering & lastfördelning blir operativa bekymmer.
Korsningspunkten: något produktions tjänst som måste överleva en enskild maskinavbrott måste köras på minst två maskiner. När du accepterar två har du redan valt horisontell skalning. Därifrån är frågan inte 'bör vi?' utan 'hur billigt kan vi lägga till nästa replika?'
Nyckelaktören: ett arbetsbelastning som inte håller någon per-anspråk information på maskinen själv. Då kan någon replika svara på något begäran, & lägga till en replika lägger kapacitet utan koordinering.
Tillståndsberoende mot tillståndsberoende i praktiken
Tillståndet försvinner aldrig, det flyttar bara
Tillståndsberoende komponent: innehåller information vars förlust skulle ändra beteendet. En databas som håller användarkonton. En cache som håller sessionstoken. En arbetsstation som fäster en långvarig strömmande anslutning till en specifik användare.
Tillståndsberoende komponent: innehåller ingen information vars förlust skulle vara viktig. En webbtjänst som läser en begäran, frågar en databas och skriver en svar. Varje begäran står själv; tjänsten minns ingenting mellan begäranden.
Nyckelinsikt: tillståndet försvinner aldrig ur ett system. Det flyttar till en lager som är designad att hålla det (en databas, en Redis kluster, en objekt lagring). De lager som möter trafiken kan då bli tillståndsberoende & tillståndsberoende lager skalar horisontellt eftersom någon replika kan svara på något begäran.
Praktisk test: om du slumpmässigt dödade en process i denna skikt & startade om den, skulle någon användare uppleva fel svar eller förlorad session? Om ja, innehåller den tillstånd. Om nej, innehåller den inte.
Exempel
- En Python-webbprocess som läser begäranden, frågar Postgres, returnerar JSON: tillståndsberoende. Tillståndet lever i Postgres.
- En Python-webbprocess som håller användarkassor i lokal minne: tillståndsberoende. Avbrott i processen förlorar kassor.
- En WebSocket-server som håller öppna anslutningar till chattanvändare: tillståndsberoende i anslutningssinnet. Avbrott i processen bryter anslutningar; klienter måste ansluta om. Detta sker ofta med försiktighet (limmade sessioner, konsekvent hashning).
- En Redis-cacheframning av Postgres: stående tillstånd för cacheminnet, men acceptabel om missar tolereras. En replikförlust innebär cachemiss, inte dataförlust.
Att designa för horisontell skalning = att flytta tillståndet ur lagret som behöver skalas.
Granska en misstänkt skikt
En grupp använder en rekommendations-Api på 6 bakre virtuella datorer bakom en reverser proxy. Programmet: läser en användar-Id från begäran, hämtar användarens senaste aktivitet från Postgres, kör en poängberäkning, returnerar en lista med rekommenderade objekt. Två icke-standardbeteenden:
- Programmet håller en 'senaste användaraktivitet' cache i processminne, populärd på första begäran för en användare, återanvänds vid senare begäranden.
- Programmet använder fast sessioner: när en användare träffar VM #3 går alla deras senare begäranden till VM #3 (proxyn är konfigurerad för fast routing på en cookie).
Replikformeln
Den enklaste kapacitetsformeln
När ett skikt blir stateless blir dimensioneringen till aritmetik. Du behöver tillräckligt många repliker så att den stadiga lasten anländer & avgår på samma sätt, med utrymme för överlast.
Formeln:
repliker = ⌈ (topplast × överlastfaktor) / per_replica_capacity ⌉ + utrymme för överlast
Där:
- topplast: maximalt upprätthållna begäranden/sekund du förväntar dig i normal drift
- överlastfaktor: multiplikator som täcker korta överskott över toppen (vanligtvis 1,5x till 2x för förutsägbar trafik, 3x eller mer för viral / oförutsägbar)
- per_replica_capacity: begäranden/sekund en replik hanterar med acceptabel latens & användning (vanligtvis mätet på 70% CPU, inte vid överbelastning)
- utrymme för överlast: extra repliker så att ett par replikförluster inte kollapsar skiktet (vanligtvis 1-2 repliker för små flottor, 10-20% för större)
Exempel: en bakre hanterar 100 begäranden per sekund (req/s) på 70% CPU per replika. Peakbelastning är 600 req/s. Du förväntar dig sällsynta 2-gångerliga ökningar. Du vill överleva 2 replikafel.
repliker = ⌈ (600 × 2) / 100 ⌉ + 2 = 12 + 2 = 14 repliker
Det 80-procentiga regeln
En per-replikakapacitet är inte den sättningpunkten. Mäta kapacitet på 70-80% CPU, aldrig på 100%.
Från omkring 80% utnyttjande ökar köer kraftigt: en kö som körde i 10 ms vid 60% utnyttjande kör i 80 ms vid 90% utnyttjande. Latens, inte genomströmning, bryter först. (Den kompletterande lektionen geometry_of_stateless_horizontal_scaling härleder denna kurva matematiskt.)
Autoskalning vs Statisk Tillhandahållning
Statisk: tillhandahåll för peak × rusge utrymme & acceptera kostnaden för att köra på låg utnyttjande utanför peak.
Autoskalning: en kontrollant lägger till & tar bort repliker baserat på observerad utnyttjande, måltidens latens eller ködjup.
Autoskalningens undantag: starttid för kyla betyder något. Om en ny replika tar 2 minuter att starta kan autoskalning inte svara på en 30-sekunders ökning. Mogen autoskalning håller en varm pool av förberedda repliker precis under skala-up-skytteln.
Storlek för en flotta för ett nytt tjänst
Ditt lag planerar att lansera en videometadatapi. Prestandabenchmark visar att en enda replika hanterar 250 begäranden per sekund (req/s) på 70% CPU och 50 ms p99-latens. Marknadsföring förutspår en toppbelastning på 4 000 req/s under prime-time-timmerna. En planerad marknadsföringshändelse kan öka till 3 gånger toppen kortvarigt. Du vill att tjänsten ska överleva 3 samtidiga replikfel utan att överskrida 80% utnyttjande på de överlevande.
Kallstart, långsam tömning och andra verkliga kanter
Verkliga flottar har verkliga kanter
Formeln antar att repliker dyker upp ögonblickligen, tar emot trafik ögonblickligen och avvisar trafik ögonblickligen. Ingen av dessa gäller i produktion.
Kall start: en ny replika måste starta operativsystemet, starta processen, ladda konfigurationen, värma cacheminnen och genomföra hälsokontroller. Mellan 5 sekunder (återställning av container) och 5 minuter (fullständig VM-start + bildladdning). Autoskalning kan inte svara på burstar kortare än denna fördröjning.
Förlängning: en replika som tas bort från poolen behöver tid att slutföra pågående begäranden innan den avslutas. Annars ser användare truncerade svar. Bakre proxys stöd för drain (avbryt acceptering av nya begäranden, slutför aktiva) men det tar sekunder till minuter.
Varm pool: produktionsflottan håller en pool med förberedda men inaktivt hållna repliker redo att ta trafik på signal. Handlar om att göra en liten stadig kostnad för snabb respons vid översvämning.
Drainning av anslutning vs omedelbar död: försiktig avslutning är viktigt. Ett SIGTERM som utlöser drainning tar längre tid än SIGKILL men bryter inte användarbegäranden.
Hälsokontrollsfönster: en replika som precis startats kan passera sin första hälsokontroll innan dess databasanslutningspool är varm; proxy skickar då verklig trafik och de första tolv begärandena är långsamma. Justera hälsokontroller för att testa den verkliga vägen, inte bara processens livskraft.
Fästhetens smyg: även nominellt stateless-skikt får fästhet över tid (CDN-cacheminnen, DNS-resolvercacheminnen, anslutningspooler). Var misstänksam inför 'identiska repliker' som ändå beter sig annorlunda.
Varm Ppool eller Reaktiv Autoskalning?
Ditt API för videometadataprogram (samma som i det föregående fråget, dimensionerat till 51 repliker för stadig topp + översvämning) upplever en 30-sekunders översvämning till 5x normal belastning varje gång ett nytt viral videoklipp läggs upp. Autoskalning tar just nu 90 sekunder att lägga till en ny replika från kall start (bildladdning + värmeup). Under de 90 sekunderna stiger latensen kraftigt och vissa begäranden tidsförlopp.
Designa ett stateless-skikt under restriktioner
Sammanfattning
Du har lärt dig varför horisontell skalning vinner efter en liten tröskel, vad state betyder i praktiken, hur du storleksställer en flotta under förväntad & överlast, & var horisontell skalning bryts vid kanten.
Använd alla fyra.
Designa en bakomliggande skikt för feed.example.com, en social-feed API. Restriktioner: per-replik kapacitet 200 begäranden/s vid 70% CPU; förväntad toppbelastning 1500 begäranden/s; överlastfaktor 2,5x (sällan trendande historier); överleva 2 samtidiga replikfels; kallstarttid 60 sekunder; rus kan vara 45 sekunder; budget tillåter vissa lediga kapacitet men inte 2,5x permanent provisoriskt.
Var Denna kurs Går Vidare
Var Denna kurs Går Vidare
Du har nu en fungerande mental modell av ett stateless skikt: varför det skalas, hur du storleksställer det, vad som bryts vid kanterna & var state måste flytta när du tvingar ut den ur lagret som behöver expandera.
Den nästa lektion i denna kurs (cs_distsys_ingress_egress_separation) tar upp en subtil problem: även en perfekt storleksställd stateless skikt kan misslyckas på överraskande sätt när inkommande & utgående trafik delar samma nätverkspåförd.
Kompletterande lektion: geometry_of_stateless_horizontal_scaling utvecklar körcylindern, Little's lag till en replikflotta & den geometriska betydelsen av 80% utnyttjandekänen.
Bra gjort. Vidare.