Nodi, Archi, Direzioni
Una Richiesta come Camminata su un Grafo
Ogni componente a cui una richiesta tocca è un nodo: client, resolver DNS, edge CDN, proxy inverso, replica backend, database, cache.
Ogni connessione tra due nodi è un arco orientato: le richieste fluiscono in avanti, le risposte fluiscono indietro. L'arco in avanti rappresenta una connessione TCP aperta più il protocollo sopra di essa.
Una singola richiesta è un percorso attraverso questo grafo. Il lavoro totale che il sistema esegue per rispondere alla richiesta è uguale alla somma del lavoro in ciascun nodo, più la latenza di ogni arco.
Perché è importante? Una volta disegnato il grafo, emergono proprietà invisibili nel codice:
- Numero di hop: il numero di archi nel percorso. Ogni hop aggiunge latenza (andata e ritorno di rete + elaborazione del nodo). Meno hop = limite inferiore più basso per la latenza.
- Grado in: quante archi puntano VERSO un nodo. Un grado in elevato significa che il nodo riceve richieste da molte fonti e deve scalare o proteggersi.
- Grado out: quante archi escono DA un nodo. Un grado out elevato significa che il nodo dipende da molti downstream e ha molti modi per fallire.
- Vertice di taglio: un singolo nodo la cui rimozione disconnette il grafo. Un reverse proxy senza pari è un vertice di taglio; la sua rimozione elimina l'accesso a tutti i suoi origin.
Dove il traffico si concentra
Fan-In = Concentrazione
Il grado di entrata di un nodo = numero di archi che puntano verso di esso. In un grafo di richieste, il grado di entrata = numero di sorgenti a monte che inviano richieste.
Pattern Fan-in: molti client -> un CDN; molti edge CDN -> pochi proxy di origine; molti proxy -> meno repliche backend; molti backend -> singolo database.
La concentrazione è importante perché il nodo con il massimo grado di ingresso (in-degree) subisce il carico aggregato più elevato. Il DB alla fine della catena potrebbe ricevere query da ogni richiesta attiva nell'intero sistema, anche se nessun singolo utente genera un carico significativo.
Fan-Out = Dipendenza
Il grado di uscita (out-degree) di un nodo = numero di archi che escono da esso. Un alto out-degree significa molte dipendenze a valle.
Un backend che chiama un database, due cache, tre API esterne e una coda ha un out-degree di 7. La sua probabilità di successo è approssimativamente il prodotto delle probabilità di successo di ciascuna dipendenza a valle (se tutte sono richieste per una risposta di successo).
0,999 ^ 7 ≈ 0,993: un backend con 7 dipendenze a valle, ciascuna con un'affidabilità del 99,9%, può raggiungere solo un'affidabilità di circa il 99,3% per se stesso, anche in assenza di bug propri.
Ridurre l'out-degree tramite: caching dei risultati a valle, rendendo opzionali le dipendenze non critiche (degradazione graduale), parallelizzando ciò che può essere parallelizzato.
L'Asimmetria
Il fan-in concentra il carico; il fan-out moltiplica il rischio. Un grafo ben strutturato minimizza entrambi nei nodi con il maggiore impatto.
Il database (fan-in più alto): usare la cache in modo aggressivo per ridurre il carico. Repliche di lettura per distribuire il fan-in su più nodi.
Il servizio orchestratore (fan-out più alto): circuit breaker per dipendenza, degradazione graduale, bulkhead.
Un Nodo Inserito Acquista Flessibilità
Indirezione = Aggiunta di un Nodo Intermedio
Senza un proxy, il grafo è: client -> backend. Il client deve conoscere l'indirizzo del backend. Spostare il backend richiede l'aggiornamento del client (tramite DNS o configurazione). Questo è un vincolo stretto.
Con un proxy, il grafo diventa: client -> proxy -> backend. Il client conosce solo il proxy. Spostare il backend richiede l'aggiornamento della configurazione upstream del proxy, non del client.
L'operazione sul grafo: inserire un nodo lungo un bordo esistente. Il nuovo bordo client -> proxy è stabile; il nuovo bordo proxy -> backend è ora di competenza del team.
Lettura geometrica: l'indirezione aggiunge un livello che disaccoppia il cambiamento upstream dal cambiamento downstream. I bordi di ciascun livello possono essere ricollegati in modo indipendente.
Costo dell'indirezione
Ogni livello aggiunge:
- Un hop di latenza in più (il collegamento dal client al proxy)
- Un ulteriore vertice di taglio sul percorso (il proxy stesso)
- Un ulteriore punto in cui può verificarsi una configurazione errata
I benefici (riconfigurazione, scalabilità, protezione, terminazione TLS, distribuzione del carico) superano di solito i costi per qualsiasi sistema non banale. Tuttavia, c'è un limite: ogni livello di indirezione aggiunge un altro hop e un altro candidato a SPOF (Single Point of Failure).
La regola della tradizione: qualsiasi problema può essere risolto aggiungendo un livello di indirezione (tranne il problema di avere troppi livelli di indirezione).
Leggere un'architettura come un grafo
Sintesi
Ora puoi leggere un'architettura di sistema come un grafo: contare i salti, identificare i vertici di taglio, misurare la concentrazione del fan-in, calcolare i limiti di disponibilità dal fan-out e valutare i compromessi dell'indirezione.
Applica tutti e quattro.
Un nuovo servizio ha questa architettura: clienti -> CDN -> proxy inverso (2 repliche) -> livello backend (8 repliche) -> { DB primario, cluster di cache (3 nodi), API esterna }.
Note di accompagnamento
Note di accompagnamento
Questa lezione di geometria ricalibra la lezione principale Proxies & Origins come un'analisi di grafo orientato.
Il prossimo accompagnamento in questo corso, geometry_of_stateless_horizontal_scaling, prende la matematica delle repliche dalla lezione principale sullo scaling e deriva geometricamente la curva di code, la legge di Little e il punto di ginocchio dell'80% di utilizzo.
Ben fatto.