I Tre Concetti di Fallimento da Conoscere
Benvenuti
I sistemi distribuiti falliscono in modi ricorrenti. Appena impari i modi, ogni postmortem diventa un esercizio di riconoscimento invece di un mistero.
Tre concetti coprono la maggior parte di ciò che conta nell'analisi delle fallite in produzione:
Punto Unico di Fallimento (SPOF): un componente la cui fallita porta giù un sistema maggiore. Spesso nascosto: il server DNS su cui tutti dipendono; il certificato contro cui tutto si rinnova; il database master unico.
Fallita a Cascata: la fallita di un componente attiva un altro, che attiva un altro. Una database lento causa timeout nell'API tier, che causa richieste di nuovo tentativo, che carica ulteriormente il database, che causa ancora più timeout. L'esplosione si propaga.
Raggio d'Influenza: quanto della system si ferma quando un pezzo fallisce. Le scelte architettoniche limitano o non limitano il raggio. Un SPOF ha raggio non limitato. Un servizio bulkheaded ha raggio limitato.
Alla fine di questa lezione, saprai:
- Identificare SPOF in un'architettura per ispezione
- Riconoscere i modi ricorrenti di fallita a cascata: stormo di uccelli, tempesta di richiesta, coda della morte
- Leggere un timeline reale e separare il trigger dalla fallita latente che il trigger ha portato alla luce
- Scrivere elementi di azione incolpevoli che mirano ai sistemi invece delle persone, coprendo prevenzione/detect/recovery
- Rasonare sui bulkheads & i circuit breakers come strumenti per limitare il raggio d'espansione
Individua il Punto Unico di Fallimento
Ispezione dell'Architettura Stratificata
Considera una piccola architettura web:
- DNS: api.example.com -> IP del server nameserver singolo 203.0.113.10 ospitato da un unico provider DNS
- CDN: un unico fornitore CDN davanti a api.example.com
- Ingress: due macchine reverse proxy dietro un load balancer
- Backend: sei repliche API in due zone di disponibilità (tre per zona)
- Database: un master + un replica di sola lettura, nella stessa zona di disponibilità
- Cache: cluster Redis, tre nodi sparsi nelle stesse due zone di disponibilità
Domanda: quali componenti sono SPOF? Suggerimento: i SPOF non sono sempre il tipo 'unica macchina'. Un cluster di tre macchine tutte nella stessa zona di disponibilità è un SPOF per il fallimento della zona.
Tre Modelli Classici di Cascata
Gli Errori Si Propagano Attraverso le Dipendenze
Modello 1: Stormo di Tuoni. Una risorsa condivisa (cache, lock, database) fallisce o si riavvia. Ogni client che dipendeva da essa tenta di nuovo contemporaneamente. L'onda di richieste sovrasta ciò che torna in funzione; i tentativi di riavvio si accumulano più rapidamente della loro capacità di ripresa; la ripresa non viene completata.
Modello 2: Tempesta di Ricontro. Un servizio a valle si lentifica. I chiamanti in alto, invece di fallire, ricontrollano. I ricontrolli moltiplicano la carica originale. Il servizio lento si lentifica ulteriormente, scatenando ulteriori ricontrolli. Infine, il carico supera anche una versione sana del servizio.
Modello 3: Coda della Morte. Una coda di elaborazione senza pressione retrospettiva riceve più rapidamente di quanto elabori. La coda cresce illimitatamente. L'esaurimento della memoria porta al crash del consumatore; il riavvio; trova una coda ancora più grande; si ferma di nuovo.
Filo conduttore comune: una piccola perturbazione iniziale scatena un ciclo a feedback positivo. La risposta del sistema amplifica il fallimento invece di attenuarlo.
Meccanismi di Damping
Ritardo esponenziale con scostamento casuale. I client che ricontrollano aspettano più a lungo ognuna delle volte, con un offset casuale. Evita le onde sincronizzate di ricontrolli.
Interruttore di circuito. Un chiamante traccia il tasso di fallimento a valle. Oltre un certo soglia, il chiamante smette di chiamare per un periodo di raffreddamento e fallisce immediatamente le proprie richieste.
Bulkhead. Isolare le risorse per dipendenza. Piscina di connessioni A per il database, piscina di connessioni B per il cache. Un database lento non può privare tutte le connessioni; i chiami al cache continuano.
Svergognamento. Quando sovraccaricato, rifiutare le richieste all'ingresso invece di accettarle e fallire lentamente. Un 429 in 1 ms è meglio di un 500 in 30 secondi.
Pressione retrospettiva. Lenti produttori quando i consumatori non possono tenere il passo. Le code diventano limitate; i mittenti si bloccano; la fonte originale di lavoro sente la pressione.
Diagnosi di una Cascata
Un team ha una fusione del livello API durante un failover di database di routine. Cronologia:
- 14:00:00 — operatore promuove il database di standby. Disponibilità prevista: ~10 secondi.
- 14:00:08 — primario non disponibile. Inizia ad avere errori di connessione al database per il livello API.
- 14:00:08 — il livello API riprova (configurazione predefinita: 5 tentativi, nessuna backoff, 100ms di distanza).
- 14:00:11 — standby promosso, accetta nuove connessioni.
- 14:00:11 — il livello API apre migliaia di nuove connessioni al database contemporaneamente (ogni replica × ogni richiesta concorrente × ogni riprova).
- 14:00:13 — la nuova prima connessione del pool del database è esaurita; nuove connessioni rifiutate.
- 14:00:13-14:05:00 — le replica del livello API esauriscono i pool di connessioni, lanciano eccezioni, si fermano, ricominciano, ripetono.
- 14:05:00 — operatore ferma manualmente il traffico del livello API; il database si stabilizza.
- 14:10:00 — la restituzione del traffico si completa gradualmente. Interruzione totale: ~10 minuti (contro le previsioni di ~10 secondi).
SERVFAIL DNS: Due Difetti Compensativi
Un Postmortem di Forma Reale
Ciò che segue è una versione sanificata di un incidente reale. I nomi dei fornitori sono cambiati, gli IP sono anonimizzati; la forma, la cronologia e le lezioni sono reali.
Riassunto
Il sito example.com ha restituito SERVFAIL da tutti i resolver DNS pubblici per circa 3-4 ore. Tutte le altre 46 zone sullo stesso master DNS non sono state colpite. Causa radice: due difetti compensativi.
1. Vendor A (un fornitore di DNS secondario) ha aggiunto un nuovo IP di sincronizzazione interno che non era incluso nell'allowlist allow-axfr-ips del primario.
2. La zona example.com aveva un conflitto CNAME di anni fa violante RFC (demo.example.com aveva sia CNAME che MX/TXT record allo stesso etichetta) che ha causato il rifiuto della zona da parte di Vendor A su AXFR fresco.
Cronologia (UTC)
- ~15:00 — Vendor A aggiunge nuovo IP di sincronizzazione 198.51.100.42 nel loro infrastructure
- 15:02 — first AXFR-out denied for 198.51.100.42 appears in primary DNS logs (no alerting on this signal)
- ~18:00 — SOA expire window reached; Vendor A drops example.com zone from cache
- ~18:30 — SERVFAIL detected externally
- ~19:45 — root cause identified
- 20:00 — 198.51.100.42 added to allow-axfr-ips; primary restarted
- 20:05 — NOTIFY sent; AXFR initiated; zone STILL SERVFAIL (CNAME conflict)
- 20:07 — check-zone reveals 1 error: CNAME conflict on demo.example.com
- 20:09 — CNAME replaced with A record; zone check clean (0 errors)
- 20:10 — NOTIFY sent; AXFR completes; Vendor A begins serving zone
- 20:11 — dig @8.8.8.8 example.com A returns correct IP — RESOLVED
Perché solo example.com?
Le 47 zone condividono lo stesso DNS primario. L'IP di AXFR colpito tutte le zone. Ma solo example.com aveva il conflitto CNAME e solo example.com aveva bisogno di un nuovo AXFR nel momento in cui è stata applicata la negazione. Le altre zone avevano già rinfrescato prima della negazione o non avevano ancora bisogno di farlo.
Difetto latente
Il conflitto CNAME a demo.example.com esisteva da anni. Funzionava perché il primario serviva la zona dal suo database (lascivo su violazioni RFC) e Vendor A stava servendo dati cache scaduti prima che la violazione venisse introdotta. Quando Vendor A ha eliminato la cache e ha avuto bisogno di dati freschi, la violazione è emersa.
Trigger
Vendor A ha aggiunto in silenzio un nuovo IP di sincronizzazione. La lista di concessione del primario non lo includeva. Negato AXFR. Tre ore dopo (SOA scadenza), Vendor A ha eliminato la zona. Il difetto latente è emerso quando il sistema ha cercato di riprendersi.
Scrivi Azioni Senza Colpa
Senza Colpa: Mirare ai Sistemi, Non alle Persone
Un elemento di azione senza colpa nomina qualcosa che il sistema dovrebbe fare in modo diverso, non qualcosa che una persona dovrebbe fare diversamente. 'Addestrare l'operatore' è colpevole. 'Aggiungere un controllo automatizzato che individua questo prima del rilascio' è senza colpa.
Le buone azioni senza colpa si raggruppano in tre dimensioni:
- Prevenzione: rendere la cosa cattiva più difficile o impossibile
- Detection: notarlo prima se accade
- Recovery: limitare il danno quando accade
Ogni elemento dovrebbe nominare (1) il cambiamento specifico del sistema, (2) un team di proprietà e (3) la dimensione a cui serve.
Compartimenti che affondano senza far affondare la nave
Prestito dall'ingegneria navale
Le navi trasportano paratie stagni: mura verticali che dividono la carena in compartimenti. Un compartimento può affondare senza far affondare la nave; un altro può fallire senza influenzare il resto.
I sistemi distribuiti prestito la stessa parola e la stessa idea.
Pattern paratie stagni: isolare le risorse per dipendenza. Un servizio che chiama tre API downstream utilizza tre piscine di connessioni separate, tre budget di thread separate, tre budget di ripetizione separate. Una API downstream lenta o che fallisce non può consumare le risorse assegnate per le altre due.
Senza paratie stagni: una dipendenza lenta esaurisce la propria pool di thread condivisi; le chiamate alle altre dipendenze bloccano in attesa di thread; l'intero servizio diventa non rispondente.
Con paratie stagni: una dipendenza lenta esaurisce la propria pool; le chiamate a essa falliscono rapidamente; le chiamate alle altre dipendenze continuano normalmente; il raggio d'azione dell'esplosione rimane limitato alla dipendenza fallita.
Interruttori a circuito
Pattern interruttori a circuito: un involucro a stato attorno a una dipendenza downstream che traccia il tasso di fallimento. Tre stati:
- Chiuso (normale): le chiamate passano. Gli errori vengono conteggiati.
- Aperto (bloccato): oltre un soglia di fallimento (ad esempio, il 50% di errori negli ultimi 30 secondi), il interruttore si apre. Le chiamate falliscono immediatamente senza provare la dipendenza. Salva il chiamante dal spreco di lavoro; salva la dipendenza dal ricevere carico mentre è poco salute.
- Mezzo aperto (testando): dopo un periodo di raffreddamento, il interruttore consente una piccola frazione di chiamate. Se riescono, si chiude di nuovo al normale. Se falliscono, si riapre per un altro periodo di raffreddamento.
La chiave di comprensione: l'interruttore a circuito impedisce lo spreco di sforzo durante i periodi di non salute conosciuta, e dà alla downstream una chance di riprendersi senza carico continuo.
Le paratie stagni limitano il raggio d'azione dell'esplosione. Gli interruttori a circuito impediscono allo spreco di sostenersi.
Limita il raggio d'azione dell'esplosione
Il tuo servizio API chiama quattro servizi downstream: User Service, Recommendation Service, Notification Service e un Payment API di terze parti. La squadra ha sentito dire che 'il Recommendation Service ha avuto qualche problema' e vuole essere sicura che quando fallisce, il resto del sistema rimanga sano.
Oggi il servizio utilizza una sola coda condivisa di 200 thread e una sola coda condivisa di connessioni HTTP. Tutti e quattro i downstream competono per queste risorse. Non ci sono interruttori di circuito.
Progetta una revisione dei modi di fallimento
Sintesi
Hai imparato a individuare i SPOFs per ispezione, riconoscere i modelli di fallimento a catena, leggere un postmortem separando il trigger dal difetto latente, scrivere azioni incolpevoli per prevenzione, rilevamento e recupero, e limitare l'area di distruzione con scatole di contenimento, interruttori di circuito e degrado graduale.
Applica tutti e cinque.
La tua squadra sta lanciando un nuovo servizio search.example.com che dipende da tre servizi downstream: un indice di ricerca primario (index.example.com), un servizio di analisi (analytics.example.com) e un servizio di raccomandazioni (recs.example.com). La squadra vuole che tu conduda una 'revisione dei modi di fallimento' prima del lancio.
Dove va questo corso
Dove va questo corso
Ora puoi individuare un SPOF, riconoscere una cascata, leggere un postmortem in modo produttivo, scrivere azioni incolpevoli e limitare l'area di distruzione progettando.
La lezione finale in questo corso (cs_distsys_observability_and_capacity) insegna cosa misurare per scoprire che un problema sta avvenendo prima che gli utenti lo facciano. Controlli di salute, endpoint della versione, le quattro segnali d'oro a un livello di proxy, e come le decisioni sulla capacità di sopravvivenza si collegano ai dati osservati.
Lezione correlata: geometry_of_failure_modes_and_blast_radius deriva la centralità di betweenness (qual è il nodo grafo che è il punto di bottiglia) e il min-cut (il vincolo sulla radiazione di esplosione).
Ben fatto. Avanti.