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

De drie foutconcepten die de moeite waard zijn om te kennen

Welkom

Gedistribueerde systemen falen in patronen. Zodra je de patronen kent, wordt elke postmortem een herkenningsoefening in plaats van een raadsel.

Drie concepten dekken het grootste deel van wat belangrijk is in de analyse van productiefouten:

Enkelvoudig falingspunt (SPOF): een component waarvan het falen een groter systeem laat zakken. Vaak verborgen: de DNS-server waar iedereen op is aangewezen; het certificaat waar alles tegen wordt vernieuwd; de enkele databasemeester.

Kaskadefout: het falen van één component veroorzaakt het falen van een ander, wat op zijn beurt weer een ander component laat falen. Een trage database veroorzaakt time-outs in de API-laag, wat leidt tot herhaalde pogingen (retries), wat de database verder belast, wat weer meer time-outs veroorzaakt. De schade verspreidt zich.

Blast radius (omvang van de schade): hoeveel van het systeem uitvalt wanneer één onderdeel faalt. Architecturale keuzes bepalen of deze omvang begrensd of onbegrensd is. Een SPOF (Single Point of Failure) heeft een onbegrenste blast radius. Een service met bulkheads (afscherming) heeft een begrenste radius.

Aan het einde van deze les kun je:

- SPOF's in een architectuur herkennen door inspectie

- Kaskadefoutpatronen herkennen: thundering herd, retry storm, queue of death

- Een echte tijdlijn lezen en de trigger scheiden van het latente defect dat door de trigger aan het licht kwam

- Schuldvrije actiepunten opstellen die zich richten op systemen in plaats van personen, met aandacht voor preventie / detectie / herstel

- Redeneren over bulkheads & circuit breakers als hulpmiddelen om de blast radius te begrenzen

Spreek het enkele falingspunt aan

Inspectie van gelaagde architectuur

Overweeg een kleine webarchitectuur:

- DNS: api.example.com -> één nameserver-IP 203.0.113.10 gehost door één DNS-aanbieder

- CDN: één CDN-aanbieder vóór api.example.com

- Ingress: twee reverse-proxy-machines achter een load balancer

- Backend: zes API-replica's in twee beschikbaarheidszones (drie per zone)

- Database: één primaire + één leesreplica, in dezelfde beschikbaarheidszone

- Cache: Redis-cluster, drie knooppunten verspreid over dezelfde twee beschikbaarheidszones

Vraag: welke componenten zijn SPOF's? Hint: SPOF's zijn niet altijd het voor de hand liggende 'enkele machine'-type. Een cluster van drie machines in één enkele beschikbaarheidszone is een SPOF voor het uitvallen van die zone.

Identificeer minstens drie SPOF's in deze architectuur. Noem voor elk van hen wat er misgaat wanneer het faalt, & stel een concrete wijziging voor die de SPOF zou wegnemen (zonder de applicatie te herschrijven).

Drie klassieke kaskadepatronen

Storingen reizen door afhankelijkheden

Patroon 1: Donderende kudde. Een gedeelde resource (cache, slot, database) faalt of herstart. Elke client die ervan afhankelijk was, probeert tegelijkertijd opnieuw. De stroom overweldigd wat er weer opstart; de opnieuw pogingen stapelen zich sneller op dan het herstel kan verwerken; het herstel voltooit zich nooit.

Patroon 2: Retry-storm. Een downstream-dienst wordt langzamer. Upstream-aanroepers falen in plaats daarvan niet, maar proberen opnieuw. De opnieuw pogingen vermenigvuldigen de oorspronkelijke belasting. De langzame dienst wordt nog langzamer, wat meer opnieuw pogingen veroorzaakt. Uiteindelijk overschrijdt de belasting zelfs de capaciteit van een gezonde versie van de dienst.

Patroon 3: Wachtrij van de dood. Een verwerkingswachtrij zonder backpressure ontvangt sneller dan hij verwerkt. De wachtrij groeit onbeperkt. Geheugen raakt op; de consument crasht; herstart; vindt een nog grotere wachtrij; crasht opnieuw.

Gemeenschappelijke draad: een kleine initiële verstoring triggert een positieve terugkoppelingslus. Het eigen antwoord van het systeem versterkt de storing in plaats van deze te dempen.

Dempende mechanismen

Exponentiële backoff met jitter. Clients die opnieuw proberen, wachten elke keer langer, met een willekeurige offset. Voorkomt gesynchroniseerde golfen van nieuwe pogingen.

Circuit breaker. Een aanroeper bijhoudt het falingspercentage van de downstream-service. Nadat een drempelwaarde is overschreden, stopt de aanroeper tijdelijk met aanroepen tijdens een afkoelperiode en faalt zijn eigen aanvragen direct. Voorkomt verspilde inspanning en geeft de downstream-service de kans om te herstellen.

Bulkhead. Zonder af te scheiden resources per afhankelijkheid. Verbindingspool A voor de database, een aparte verbindingspool B voor de cache. Een trage database kan niet alle verbindingen opslorpen; cache-aanvragen gaan door.

Load shedding. Bij overbelasting, verwerp aanvragen aan de rand in plaats van ze te accepteren en langzaam te laten falen. Een 429 in 1 ms is beter dan een 500 in 30 seconden.

Backpressure. Verlangzaam producenten wanneer consumenten niet bij kunnen. Wachten worden begrensd; afzenders blokkeren; de oorspronkelijke bron van werk voelt de weerstand.

Cascading failure: trigger -> amplification -> collapse, with damping mechanisms

Diagnosticeer een Cascade

De API-laag van een team stort in tijdens een routine database-failover. Tijdlijn:

- 14:00:00 — operator promoveert de standby-database. Verwachte onbeschikbaarheid: ~10 seconden.

- 14:00:08 — primaire database onbeschikbaar. Verzoeken van de API-laag beginnen te falen met databaseverbindingsfouten.

- 14:00:08 — API-laag probeert opnieuw (standaardconfiguratie: 5 pogingen, geen backoff, 100 ms tussenafstand).

- 14:00:11 — standby gepromoveerd, accepteert nieuwe verbindingen.

- 14:00:11 — API-laag opent duizenden nieuwe databaseverbindingen tegelijk (elke replica × elk concurrent verzoek × elke poging).

- 14:00:13 — verbindingenpool van de nieuwe primaire database uitgeput; nieuwe verbindingen geweigerd.

- 14:00:13-14:05:00 — replica's van de API-laag putten verbindingenpools uit, gooien uitzonderingen, crashen, herstarten, herhalen.

- 14:05:00 — operator stopt handmatig het verkeer van de API-laag; database stabiliseert.

- 14:10:00 — geleidelijke herstel van het verkeer is voltooid. Totale uitval: ~10 minuten (verwacht was ~10 seconden).

Identificeer het cascadepatroon dat hier speelt, noem de dempingsmechanismen die het hadden kunnen voorkomen (minimaal twee) & leg uit waarom de failover van primair naar standby (bedoeld als een blip van 10 seconden) in plaats daarvan een uitval van 10 minuten veroorzaakte.

DNS SERVFAIL: Twee samenvallende fouten

Een postmortem met een echte vorm

Wat volgt is een gesaniteerde versie van een echt incident. Leveranciersnamen zijn gewijzigd, IP-adressen zijn geanonimiseerd; de vorm, de tijdlijn en de lessen zijn wel echt.

Samenvatting

De site example.com gaf SERVFAIL terug vanuit alle openbare DNS-resolvers gedurende ongeveer 3-4 uur. Alle andere 46 zones op dezelfde DNS-master waren niet getroffen. Oorzaak: twee samenvallende fouten.

1. Leverancier A (een secundaire DNS-leverancier) voegde een nieuw intern sync-IP toe dat niet in de allow-axfr-ips-toestemmingslijst van de primaire stond.

2. De example.com-zone had een jarenoude CNAME-conflict in strijd met RFC's (demo.example.com had zowel CNAME- als MX/TXT-records op hetzelfde label) waardoor Leverancier A de zone weigerde bij een nieuwe AXFR.

Tijdlijn (UTC)

- ~15:00 — Leverancier A voegt nieuw synchronisatie-IP 198.51.100.42 toe aan hun infrastructuur

- 15:02 — eerste AXFR-out denied voor 198.51.100.42 verschijnt in de primaire DNS-logboeken (geen meldingen voor dit signaal)

- ~18:00 — SOA-vervalvenster bereikt; Leverancier A verwijdert het example.com-zone uit de cache

- ~18:30 — SERVFAIL extern gedetecteerd

- ~19:45 — oorzaak geïdentificeerd

- 20:00 — 198.51.100.42 toegevoegd aan allow-axfr-ips; primaire opnieuw gestart

- 20:05 — NOTIFY verstuurd; AXFR gestart; zone NOG STEEDS SERVFAIL (CNAME-conflict)

- 20:07 — check-zone onthult 1 fout: CNAME-conflict op demo.example.com

- 20:09 — CNAME vervangen door A-record; zonecontrole schoon (0 fouten)

- 20:10 — NOTIFY verzonden; AXFR voltooid; Vendor A begint met het serveren van de zone

- 20:11 — dig @8.8.8.8 example.com A geeft het juiste IP-adres terug — OPGELÖST

Waarom alleen example.com?

Alle 47 zones delen dezelfde DNS-primaire. Het IP-blok voor AXFR beïnvloedde alle zones. Maar alleen example.com had het CNAME-conflict, & alleen example.com had op het moment dat de weigering werd afgedwongen een verse AXFR nodig. Andere zones hadden vóór de weigering al hun data vernieuwd of hadden op dat moment nog geen vernieuwing nodig.

Latent defect

Het CNAME-conflict op demo.example.com bestond al jaren. Het werkte omdat de primaire de zone diende vanuit zijn database (tolerant voor RFC-overschrijdingen) & Vendor A diende vanuit verouderde gecachte data van vóór de overtreding was geïntroduceerd. Toen Vendor A zijn cache verloor & verse data nodig had, werd de overtreding zichtbaar.

Trigger

Leverancier A voegde stilletjes een nieuwe sync-IP toe. De allowlist van de primaire server bevatte deze niet. AXFR werd geweigerd. Drie uur later (SOA expire) verwijderde Leverancier A de zone. Het latente defect werd zichtbaar toen het systeem probeerde te herstellen.

Schrijf schuldloze actiepunten

Schuldloos: richt je op systemen, niet op mensen

Een schuldloos actiepunt noemt iets dat het systeem anders moet doen, niet iets dat een persoon anders moet doen. 'Breng de operator in opleiding' is schuldtoekennend. 'Voeg een geautomatiseerde controle toe die dit vangt vóór de deploy' is schuldloos.

Goede schuldloze actiepunten vallen in drie dimensies:

- Preventie: maak het slechte ding moeilijker of onmogelijk

- Detectie: merk het eerder op als het gebeurt

- Herstel: beperk de schade wanneer het gebeurt

Elk item moet (1) de specifieke systeemwijziging, (2) een verantwoordelijk team en (3) de dimensie die het dient, benoemen.

Schrijf drie schuldvrije actiepunten die het bovenstaande postmortem over DNS-SERVFAIL aanpakken. Verdeel ze over preventie / detectie / herstel (één per dimensie). Elk item moet een specifieke systeemwijziging en een verantwoordelijk team benoemen. Richt je NIET op een mens als oorzaak.

Compartimenten die zinken zonder het schip

Geleend uit de scheepsbouw

Scheppen hebben waterdichte schotten: verticale wanden die de romp in compartimenten verdelen. Eén compartiment kan vollopen zonder dat het schip zinkt; een ander kan falen zonder de rest te beïnvloeden.

Gedistribueerde systemen lenen hetzelfde woord én hetzelfde idee.

Bulkhead-patroon: isoleer resources per afhankelijkheid. Een service die drie downstream-API's aanroept, gebruikt drie aparte verbindingspools, drie aparte threadpools en drie aparte retry-budgets. Een trage of falende downstream kan de resources die voor de andere twee zijn toegewezen, niet opslorpen.

Zonder bulkheads: één trage afhankelijkheid put de gedeelde threadpool leeg; aanroepen naar andere afhankelijkheden blokkeren terwijl ze op threads wachten; de hele service wordt onbeantwoord.

Met bulkheads: één trage afhankelijkheid put zijn eigen pool leeg; aanroepen naar deze afhankelijkheid falen snel; aanroepen naar andere afhankelijkheden verlopen normaal; de blast radius blijft beperkt tot de falende afhankelijkheid.

Circuit Breakers

Circuit breaker-patroon: een statische wrapper rond een downstream-afhankelijkheid die het falingspercentage bijhoudt. Drie staten:

- Gesloten (normaal): aanroepen gaan door. Falen worden geteld.

- Open (uitgeschakeld): zodra een falingsdrempel wordt overschreden (bijvoorbeeld 50% falen in de laatste 30 seconden), gaat de breaker open. Aanroepen falen onmiddellijk zonder de afhankelijkheid te proberen. Dit spaart de aanroeper van nutteloos werk; het spaart de afhankelijkheid van belasting terwijl deze ongezond is.

- Half-open (testen): na een afkoelperiode laat de breaker een klein deel van de aanroepen door. Als deze slagen, sluit hij weer naar de normale staat. Als ze falen, gaat hij opnieuw open voor een andere afkoelperiode.

De kerninzicht: de circuit breaker voorkomt verspilling van inspanning tijdens perioden waarin de afhankelijkheid bekend is als ongezond, & geeft de downstream een kans om te herstellen zonder voortdurende belasting.

Bulkheads beperken de blast radius. Circuit breakers voorkomen dat de blast zichzelf in stand houdt.

Beperk de Blast Radius

Je API-service roept vier downstream-services aan: User Service, Recommendation Service, Notification Service, & een derden Payment API. Het team heeft gehoord dat 'de Recommendation Service wat onbetrouwbaar is' & wil ervoor zorgen dat wanneer deze faalt, de rest van het systeem gezond blijft.

Vandaag gebruikt de service een enkele gedeelde thread pool van 200 threads & een enkele gedeelde HTTP-verbindingenpool. Alle vier de downstreams concurreren om deze resources. Er zijn geen circuit breakers.

Stel een bulkhead- + circuit-breaker-ontwerp voor voor deze API-service. Wees specifiek: hoe verdeel je de thread- / verbindingenpools over de vier afhankelijkheden, welke circuit-breaker-drempelwaarden zijn zinvol voor de onbetrouwbare Recommendation Service, & wat moet de voor de gebruiker bestemde API doen wanneer de Recommendation Service open-circuïteerd is?

Een falingsmodusbeoordeling ontwerpen

Synthese

Je hebt geleerd om SPOFs (Single Points of Failure) te herkennen door inspectie, kaskadefalingspatronen te herkennen, de trigger te scheiden van het latente defect bij het lezen van een postmortem, schuldloze actiepunten op te stellen voor preventie / detectie / herstel, & de blast radius (omvang van de schade) te beperken met bulkheads + circuit breakers + graciele degradatie.

Pas alle vijf toe.

Je team lanceert een nieuwe service search.example.com die afhankelijk is van drie downstream-services: een primaire zoekindex (index.example.com), een analytics-service (analytics.example.com), & een aanbevelingsservice (recs.example.com). Het team wil dat je een 'failure-mode review' leidt vóór de lancering.

Schets de failure-mode review die je zou leiden. Neem op: hoe je SPOFs zou blootleggen (één techniek), hoe je kaskadefalen tussen de zoekservice & zijn drie downstreams zou voorkomen (twee patronen), één concreet actiepunt voor de aanbevelingsservice (die het team als minst betrouwbaar heeft gemarkeerd), & welke monitoring je vereist zou stellen om op het moment van lancering aanwezig te zijn.

Waar deze cursus naartoe gaat

Waar deze cursus naartoe gaat

Je kunt nu een SPOF herkennen, een cascade identificeren, een postmortem productief lezen, schuldloze actiepunten opstellen & de blast radius door ontwerp beperken.

De laatste les in deze cursus (cs_distsys_observability_and_capacity) leert wat je moet meten, zodat je erachter komt dat er een probleem optreedt voordat gebruikers dat merken. Health checks, versie-endpoints, de vier gouden signalen op een proxy-laag & hoe beslissingen over piekcapaciteit terugkoppelen naar waargenomen data.

Begeleidelijke les: geometry_of_failure_modes_and_blast_radius leidt betweenness centraliteit af (welke graafknooppunt de bottleneck is) & min-cut (de grens van de blast radius).

Goed gedaan. Voorwaarts.