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

un

gäst
1 / ?

Två sätt att hantera mer last

Välkommen

När en tjänst börjar ge efter under last står en operatör inför ett val. Antingen gör man den befintliga maskinen större (mer CPU, mer RAM, snabbare diskar). Eller så lägger man till fler maskiner som var och en utför samma arbete.

Den första vägen kallas vertikal skalning (scale up). Den andra kallas horisontell skalning (scale out).

Denna lektion lär dig varför nästan all modern webbarkitektur väljer horisontell skalning och vilken egenskap hos arbetsbelastningen som gör det möjligt. Svaret gömmer sig i ett ord: tillstånd.

Till slut kommer du att förstå:

- Kostnadskurvor för vertikal respektive horisontell skalning & när respektive metod passar

- Vad 'stateful' och 'stateless' betyder i praktiken, & varför den ena kan multipliceras billigt

- Matematiken som dimensionerar en replikflott under förväntad och spiklast

- Marginalregeln som förhindrar att en nivå kollapsar bortom köans knä

- Var tillstånd måste finnas (det försvinner aldrig) & hur man flyttar ut det ur de lager som behöver skalas

Varför horisontell skalning vinner vid en viss gräns

Vertikal skalning: En större maskin

Fördelar: enkel. Inga koden ändringar. Ingen samordning. Samma process har nu mer CPU.

Nackdelar: tak. Den största kommersiellt tillgängliga VM:en har ändlig RAM & kärnor. Ovanför det köper inget pengar mer utrymme. Kostnaderna ökar superlinjärt bortom säljarens optimala punkt. Ett fall av den enskilda maskinen tar ner hela tjänsten.

Horisontell skalning: Många mindre maskiner

Fördelar: inget tak (upp till din vilja att betala för & koordinera maskiner). Kapaciteten ökar linjärt med antalet repliker, förutsägbart. Ett enskilt replik-fall tar bort 1/N av kapaciteten, inte 100 %.

Nackdelar: kräver att arbetsbelastningen stödjer det. Vissa arbetsbelastningar (en enda stor databas, en statfull spelserver som håller live-sessioner) motstår horisontell skalning. Samordning & lastfördelning blir driftsmässiga frågor.

Övergångspunkten: en produktions-tjänst som behöver överleva ett enskilt maskinfall måste köras på minst två maskiner. När du accepterar två, har du redan valt horisontell skalning. Från och med då är frågan inte 'ska vi?' utan 'hur billigt kan vi lägga till nästa replik?'

Nyckelaktiveraren: en arbetsbelastning som inte håller per-förfrågnings-tillstånd på maskinen själv. Då kan varje replik svara på varje förfrågan, & att lägga till en replik ökar kapaciteten utan samordning.

Vertikal vs horisontell skalning: kostnadskurva & tak

Ett team kör en tjänst på en enskild VM med 8 CPU:er som hanterar 800 förfrågningar per sekund vid 60 % CPU-användning. De förväntar sig att trafiken ska öka med 4 gånger under det kommande året. De diskuterar: hyra en VM med 32 CPU:er (vertikal skalning) eller köra fyra identiska VM:er med 8 CPU:er bakom en lastbalanserare (horisontell skalning). Vilket alternativ rekommenderar du, och namnge två skäl som går utöver ren kapacitet.

Stateful vs Stateless i praktiken

Tillstånd försvinner aldrig, det flyttar bara

Komponent med tillstånd: innehåller information vars förlust skulle ändra beteendet. En databas som innehåller användarkonton. En cache som innehåller sessionstokens. En worker som fäster en långvarig strömanslutning till en specifik användare.

Komponent utan tillstånd: innehåller ingen information vars förlust skulle vara betydelsefull. En webb-tjärn som läser en begäran, frågar en databas & skriver ett svar. Varje begäran står på egen hand; tjärnen minns ingenting mellan begäran.

Nyckelinsikt: tillstånd försvinner aldrig ur ett system. Det flyttas till en lager som är designad för att hålla det (en databas, en Redis-cluster, ett objektarkiv). Lagren som möter trafik kan då göras tillståndsfriska, & tillståndsfriska lager skalas horisontellt eftersom varje replik kan svara på vilken begäran som helst.

Praktisk test: om du slumpmässigt dödade en process i denna tjärn & startade om den, skulle någon användare uppleva ett felaktigt svar eller en förlorad session? Om ja, håller den tillstånd. Om nej, gör den det inte.

Exempel

- En Python-webbprocess som läser begäran, frågar Postgres, returnerar JSON: tillståndsfrisk. Tillståndet ligger i Postgres.

- En Python-webbprocess som håller användarnas varukorgar i lokalt minne: med tillstånd. Att döda processen förlorar varukorgarna.

- En WebSocket-server som håller öppna anslutningar till chattanvändare: tillståndsberoende i anslutningssammanhang. Om processen avslutas förloras anslutningarna; klienter måste ansluta om. Ofta kan dessa ändå skalas horisontellt med omsorg (klibbiga sessioner, konsistent haschning).

- En Redis-cache framför Postgres: tillståndsberoende för cachen innehållet, men acceptabelt om cache-missar är tolerabla. En replikfel innebär cache-miss, inte dataförlust.

Att designa för horisontell skalning = att flytta ut tillståndet ur det lager som behöver skalas.

Auditera en misstänkt tier

Ett team kör ett rekommendations-API på 6 backend-VM:er bakom en reverse proxy. Applikationen: läser en användar-ID från förfrågan, hämtar användarens senaste aktivitet från Postgres, kör en poängsättningsalgoritm och returnerar en lista med rekommenderade objekt. Två icke-standardiserade beteenden:

- Applikationen håller en cache för 'senaste användaraktivitet' i processminnet, som fylls vid första förfrågan för en användare och återanvänds vid efterföljande förfrågningar.

- Applikationen använder klibbiga sessioner: när en användare träffar VM #3, skickas alla deras efterföljande förfrågningar till VM #3 (proxyn är konfigurerad för klibbig routing via en cookie).

Identifiera vilket av dessa två beteenden som gör tieren tillståndsberoende och förklara vad som skulle gå sönder om teamet försökte skala från 6 VM:er till 12. Föreslå sedan en omdesign som låter tieren skalas horisontellt utan att förlora fördelarna med användar-cachen.

Formeln för repliker

Den enklaste kapacitetsformeln

När en tier blir stateless blir storleksbestämningen aritmetik. Du behöver tillräckligt med repliker så att belastningen i jämviktstillstånd anländer och lämnar med samma hastighet, med marginal för toppar.

Formeln:

repliker = ⌈ (topplast × spikfaktor) / kapacitet_per_replika ⌉ + marginal

Där:

- topplast: maximal upprätthållen antal förfrågningar per sekund du förväntar dig under normal drift

- spikfaktor: en multiplikator som täcker korta utbrott ovanför toppen (vanligtvis 1,5x till 2x för förutsägbar trafik, 3x eller mer för viral / oförutsägbar trafik)

- kapacitet_per_replika: antal förfrågningar per sekund en replika hanterar vid acceptabel latens och utnyttjandegrad (vanligtvis mätt vid 70 % CPU, inte vid mättnad)

- marginal: extra repliker så att ett fåtal replikfel inte kollapsar tieren (vanligtvis 1–2 repliker för små flottiller, 10–20 % för större)

Exempel: En backend hanterar 100 req/s vid 70 % CPU per replik. Topplasten är 600 req/s. Du förväntar dig tillfälliga 2-gångsökar. Du vill klara av att 2 repliker går sönder.

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

80 %-regeln

Kapaciteten per replik är inte mättnadspunkten. Mät kapaciteten vid 70–80 % CPU, aldrig vid 100 %.

Över cirka 80 % utnyttjande stiger kökurvorna brant: en kö som tog 10 ms vid 60 % utnyttjande tar 80 ms vid 90 % utnyttjande. Latens, inte genomsnittlig prestanda, bryter först. (Den tillhörande lektionen geometry_of_stateless_horizontal_scaling härleder denna kurva matematiskt.)

Autoskalning jämfört med statisk dimensionering

Statisk: dimensionera för topp × ökar och acceptera kostnaden av att köra med låg utnyttjandegrad under lågsäsong.

Autoskalning: en kontrollenhet lägger till och tar bort repliker baserat på observerat utnyttjande, mållatens eller ködjup.

Autoscaling-varning: starttid vid kallstart är avgörande. Om en ny replik tar 2 minuter att starta, kan autoscaling inte reagera på en 30-sekunders topp. Mogen autoscaling håller en varm pool av förberedda repliker precis under tröskeln för skalning uppåt.

Formel för replikstorlek med räknexempel

Stora en flotta för en ny tjänst

Ditt team planerar att lansera en API för videometadata. Mätningar visar att en enskild replik hanterar 250 req/s vid 70 % CPU och 50 ms p99-lägg. Marketing förutspår en toppbelastning på 4 000 req/s under primstimma. En planerad kampanj kan tillfälligt öka belastningen till 3 gånger toppen. Du vill att tjänsten ska klara 3 simultana replikfel utan att överstiga 80 % utnyttjandegrad på de återstående replikerna.

Använd replikformeln för att dimensionera lanseringsflottan. Visa dina beräkningar steg för steg, och förklara sedan en anledning till att ditt tal fortfarande kan vara felaktigt (kallstart, cache-uppvärmning, beroendelägg, eller vad du än kan motivera).

Kallstart, långsam dränering & andra reella gränsfall

Reella flottor har reella gränsfall

Formeln antar att repliker dyker upp omedelbart, tar emot trafik omedelbart & lägger av trafik omedelbart. Inget av detta stämmer i produktion.

Kallstart: En ny replik behöver starta operativsystemet, starta processen, läsa in konfiguration, värma upp cachar & passera hälsokontroller. Allt från 5 sekunder (containeromstart) till 5 minuter (fullständig VM-start + bildhämtning). Autoskalning kan inte reagera på toppar som är kortare än denna fördröjning.

Långsam dränering: En replik som tas bort från poolen behöver tid att slutföra pågående förfrågningar innan den avslutas. Annars ser användare avhuggna svar. Omvända proxyer stödjer dränering (sluta acceptera nya förfrågningar, slutför aktiva) men det tar sekunder till minuter.

Varm pool: produktionsflottiller håller en pool av förberedda men inaktiva repliker redo att ta emot trafik vid signal. Det byter en liten, konstant kostnad mot snabb reaktion vid spikar.

Connection draining vs omedelbar avstängning: graciös avstängning är viktig. En SIGTERM som initierar dränering tar längre tid än SIGKILL men bryter inte användarbegäranden.

Hälsokontrollfönster: en replik som precis har startat kan passera sin första hälsokontroll innan dess databasanslutningspool är varm; proxyn skickar sedan riktig trafik & de första dussinet begärandena är långsamma. Justera hälsokontrollerna så att de testar den verkliga vägen, inte bara processens livskraft.

Klibbigt beteende (stickiness creep): även nominellt tillståndslösa lager skaffar sig klibbigt beteende över tid (CDN-cachar, DNS-resolver-cachar, anslutningspools). Var misstänksam mot 'identiska repliker' som ändå beter sig olika.

Varm pool eller reaktiv autoskalning?

Din videometadata-API (samma som i föregående fråga, dimensionerad till 51 repliker för stabil topp + spikar) upplever en 30-sekunders spik till 5 gånger normal belastning varje gång en ny viral video laddas upp. Autoskalning tar för närvarande 90 sekunder att lägga till en ny replik från kall start (bildhämtning + uppvärmning). Under det 90-sekunders fönstret stiger latensen kraftigt & vissa begäranden löper ut i timeout.

Föreslå en lösning. Välj: (a) behåll reaktiv autoskalning men justera den annorlunda, (b) etablera en varm pool med inaktiva repliker, eller (c) statiskt dimensionera för 5-gångers toppen permanent. Motivera ditt val & nämna en kostnad som de andra två alternativen skulle medföra.

Designa ett tillståndsberoende lager under begränsningar

Synthes

Du har lärt dig varför horisontell skalning vinner bortom en viss tröskel, vad tillstånd innebär i praktiken, hur man dimensionerar en flotta under förväntad och spiklast, och var horisontell skalning bryter vid gränsfall.

Tillämpa alla fyra.

Designa en backend-tier för feed.example.com, en social feed-API. Begränsningar: kapacitet per replik är 200 req/s vid 70 % CPU; förväntad toppbelastning är 1500 req/s; spikfaktor 2,5x (tillfälliga trendande inlägg); överleva 2 simultana replikfel; kallstartstid 60 sekunder; spikar kan pågå i 45 sekunder; budgeten tillåter viss ledig kapacitet men inte permanent dimensionering på 2,5x.

Dimensionera den stabila flottan (visa beräkningen), välj din strategi för hantering av spikar (varm pool / reaktiv autoskalning / båda) & identifiera en del av användarspecifik tillstånd som applikationen sannolikt håller & var den måste flyttas till för att hålla tiern tillståndsfrå.

Vart denna kurs går vidare

Vart kursen går härnäst

Du har nu en fungerande mental modell för ett tillståndslöst lager: varför det skalar, hur man dimensionerar det, vad som bryts vid dess gränser och var tillståndet måste flyttas när du trycker ut det ur det lager som behöver växa.

Nästa lektion i denna kurs (cs_distsys_ingress_egress_separation) tar upp ett subtilare problem: Även ett perfekt dimensionerat tillståndslöst lager kan misslyckas på överraskande sätt när inkommande och utgående trafik delar samma nätverksväg. Det klassiska exemplet involverar en proxy som försöker ansluta till sig själv; lösningen innebär att dela upp ett lager i två med olika ansvarsområden.

Sällskapslektion: geometry_of_stateless_horizontal_scaling härleder kökurvan, Little's lag tillämpad på en replikflottilla, och den geometriska innebörden av knäet vid 80 % utnyttjandegrad.

Bra jobbat. Framåt.