Nœuds, Arêtes, Directions
Une demande comme une marche sur un graphe
Chaque composant que touche une demande est un nœud : client, résolveur DNS, bord de CDN, proxy inversé, instance de back-end, base de données, cache.
Chaque connexion entre deux nœuds est une arête orientée : les demandes s'écoulent en avant, les réponses s'écoulent en arrière. L'arête en avant représente une connexion TCP ouverte ainsi que le protocole qui s'y trouve dessus.
Une seule demande est une chemin à travers ce graphe. Le travail total que le système effectue pour répondre à la demande est égal à la somme du travail à chaque nœud, plus la latence de chaque arête.
Pourquoi s'en soucier? Une fois que vous avez tracé le graphe, des propriétés sautent qui sont invisibles dans le code:
- Nombre d'étapes : le nombre d'arêtes dans le chemin. Chaque saut ajoute de la latence (tour de ronde réseau + traitement du nœud). Moins de sauts = un plancher inférieur plus bas sur la latence.
- Degres de nœud entrant : combien d'arêtes pointent DANS un nœud. Haut degré de nœud entrant signifie que le nœud reçoit des demandes de nombreuses sources et doit s'échelonner ou se protéger.
- Degres de nœud sortant : combien d'arêtes pointent DEHORS d'un nœud. Haut degré de nœud sortant signifie que le nœud dépend de nombreux downstreams et a de nombreuses façons de faillir.
- Sommets de section : un seul nœud dont la suppression coupe le graphe. Un proxy inversé sans homologue est un sommet de section ; en le supprimant, on coupe tout accès à ses origines.
Où la circulation se concentre
Fan-In = Concentration
Degré en entrée d'un nœud = nombre d'arêtes pointant vers lui. Dans un graphe de demande, le degré en entrée = nombre de sources upstream qui envoient des demandes.
Modèle de fan-in: de nombreuses clients -> un CDN; de nombreuses bords CDN -> quelques proxies d'origine; de nombreux proxies -> moins de réplicas backend; de nombreuses backends -> une seule base de données.
**La concentration compte parce que le nœud de plus haut degré en entrée voit le plus grand chargement cumulé. La base de données à la fin de la chaîne peut voir des requêtes de chaque demande active dans l'ensemble du système, même si aucune demande individuelle ne génère grand-chose.
Fan-Out = Dépendance
Degré en sortie d'un nœud = nombre d'arêtes pointant hors de lui. Un grand degré en sortie signifie de nombreuses dépendances downstream.
Un backend qui appelle une base de données, deux caches, trois API externes et une file d'attente a un degré en sortie de 7. Sa probabilité de succès est environ le produit des probabilités de succès de chaque downstream (si toutes sont nécessaires pour une réponse réussie).
0,999 ^ 7 ≈ 0,993: un backend avec 7 downstreams chacun à 99,9% de fiabilité peut seulement atteindre ~99,3% de fiabilité lui-même, même sans bugs de sa propre part.
Réduire le degré en sortie par: mise en cache des résultats downstream, rendre les downstreams non critiques optionnels (dégradation gracieuse), parallélisation de ce qui peut l'être.
L'asymétrie
Le fan-in concentre le chargement; le fan-out multiplie le risque. Un graphe bien conçu minimise les deux aux nœuds les plus impactants.
La base de données (plus haut fan-in): cache agressivement pour réduire le chargement. Répliques de lecture pour répartir le fan-in sur plusieurs nœuds.
Le service de tournage (plus haut fan-out): couvre-feu par dépendance, dégradation gracieuse, bulkheads.
Un nœud inséré achète de la flexibilité
Indirection = Ajout d'un Nœud Intermédiaire
Sans proxy, le graphe est : client -> backend. Le client doit connaître l'adresse du backend. Déplacer le backend nécessite de mettre à jour le client (via DNS ou configuration). C'est une liaison étroite.
Avec un proxy, le graphe devient : client -> proxy -> backend. Le client connaît seulement le proxy. Déplacer le backend nécessite de mettre à jour la configuration upstream du proxy, pas le client.
L'opération du graphe : insérer un nœud le long d'une arête existante. La nouvelle arête client -> proxy est stable ; la nouvelle arête proxy -> backend est maintenant entre les mains de l'équipe.
Lecture géométrique : l'indirection ajoute un niveau qui décuple les changements upstream des changements downstream. Chaque niveau peut reconfigurer indépendamment les arêtes.
Coût de l'Indirection
Chaque niveau ajoute :
- Un saut de latence (l'arête allant de client à proxy)
- Une autre arête de coupe sur la voie (le proxy lui-même)
- Un autre endroit où une erreur de configuration peut survenir
Les avantages (réparer, échelonner, protéger, terminer TLS, distribuer la charge) surpasse généralement les coûts pour tout système non-négligeable. Mais il y a une limite : chaque niveau d'indirection ajoute un autre saut & un autre candidat SPOF.
La règle du folklore : tout problème peut être résolu en ajoutant un niveau d'indirection (sauf le problème de trop de niveaux d'indirection).
Lire une Architecture Comme un Graphe
Synthèse
Vous pouvez maintenant lire une architecture de système comme un graphe : compter les sauts, identifier les nœuds de coupure, mesurer la concentration du fan-in, calculer les plafonds d'availability à partir du fan-out & évaluer les avantages et les inconvénients de l'indirection.
Appliquez tout.
Un nouveau service a cette architecture : clients -> CDN -> proxy inversé (2 réplicas) -> niveau back-end (8 réplicas) -> { base de données primaire, cluster de cache (3 nœuds), API externe }.
Notes de Compagnon
Notes de Compagnon
Cette géométrie de leçon reformule l'enseignement principal Proxies & Origins en tant qu'analyse de graphe orienté.
La prochaine note de compagnon dans ce cours, geometry_of_stateless_horizontal_scaling, prend les mathématiques de réplica de l'enseignement principal d'échelle et dérive la courbe de file d'attente, la loi de Little et le genou géométrique de 80% de utilisation.
Bien fait.