Nœuds, arêtes, directions
Une requête comme une marche sur un graphe
Chaque composant qu'une requête touche est un nœud : client, résolveur DNS, bord de CDN, proxy inverse, réplique backend, base de données, cache.
Chaque connexion entre deux nœuds est une arête orientée : les requêtes circulent vers l'avant, les réponses vers l'arrière. L'arête avant représente une connexion TCP ouverte plus le protocole au-dessus.
Une seule requête est un chemin à travers ce graphe. Le travail total effectué par le système pour répondre à la requête est égal à la somme du travail effectué à chaque nœud, plus la latence de chaque arête.
Pourquoi s'en soucier ? Une fois le graphe dessiné, des propriétés deviennent visibles qui sont invisibles dans le code :
- Nombre de sauts (hop count) : le nombre d'arêtes dans le chemin. Chaque saut ajoute de la latence (aller-retour réseau + traitement par le nœud). Moins de sauts = plancher de latence plus bas.
- Degré entrant (in-degree) : le nombre d'arêtes pointant VERS UN nœud. Un degré entrant élevé signifie que le nœud reçoit des requêtes de nombreuses sources et doit se mettre à l'échelle ou se protéger.
- Degré sortant (out-degree) : le nombre d'arêtes pointant DEPUIS UN nœud. Un degré sortant élevé signifie que le nœud dépend de nombreux services en aval et a de nombreuses façons de tomber en panne.
- Sommet de coupure (cut vertex) : un nœud unique dont la suppression déconnecte le graphe. Un proxy inverse sans pair est un sommet de coupure ; sa suppression supprime tout accès à ses origines.
Où le trafic se concentre
Convergence = Concentration
Le degré d'entrée d'un nœud = nombre d'arêtes pointant vers lui. Dans un graphe de requêtes, le degré d'entrée = nombre de sources amont qui envoient des requêtes.
Motif de convergence (fan-in) : de nombreux clients -> un CDN ; de nombreuses extrémités CDN -> quelques proxys d'origine ; de nombreux proxys -> moins de répliques backend ; de nombreux backends -> une base de données unique.
La concentration est importante car le nœud avec le plus grand degré d'entrée (in-degree) subit la charge agrégée la plus élevée. La base de données à l'extrémité de la chaîne peut recevoir des requêtes de toutes les requêtes actives dans l'ensemble du système, même si aucun utilisateur individuel n'en génère beaucoup.
Fan-Out = Dépendance
Le degré de sortie (out-degree) d'un nœud = le nombre d'arêtes pointant vers l'extérieur. Un degré de sortie élevé signifie de nombreuses dépendances en aval.
Un backend qui appelle une base de données, deux caches, trois API externes et une file d'attente a un degré de sortie de 7. Sa probabilité de réussite est approximativement le produit de la probabilité de réussite de chaque composant en aval (si tous sont nécessaires pour une réponse réussie).
0,999 ^ 7 ≈ 0,993 : un backend avec 7 dépendances en aval, chacune ayant une fiabilité de 99,9 %, ne peut atteindre qu'une fiabilité d'environ 99,3 % lui-même, même sans aucun bug de son propre fait.
Réduire le degré de sortie par : la mise en cache des résultats en aval, la rendue des dépendances non critiques optionnelles (dégradation gracieuse), et la parallélisation de ce qui peut l'être.
L'Asymétrie
L'entrée multiple (fan-in) concentre la charge ; la sortie multiple (fan-out) multiplie le risque. Un graphe bien conçu minimise les deux aux nœuds à plus fort impact.
La base de données (fan-in le plus élevé) : utiliser un cache de manière agressive pour réduire la charge. Utiliser des répliques de lecture pour répartir le fan-in sur plusieurs nœuds.
Le service orchestrateur (fan-out le plus élevé) : disjoncteurs (circuit breakers) par dépendance, dégradation gracieuse, cloisonnement (bulkheads).
Un nœud inséré offre 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 un couplage fort.
Avec un proxy, le graphe devient : client -> proxy -> backend. Le client ne connaît que le proxy. Déplacer le backend nécessite de mettre à jour la configuration amont du proxy, et non le client.
L'opération sur le 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 désormais sous la responsabilité de l'équipe.
Lecture géométrique : l'indirection ajoute une couche qui découple les changements amont des changements aval. Les arêtes de chaque couche peuvent être réaffectées indépendamment.
Coût de l'indirection
Chaque couche ajoute :
- Un saut de latence supplémentaire (l'arête entre le client et le proxy)
- Un sommet de coupure supplémentaire sur le chemin (le proxy lui-même)
- Un lieu supplémentaire où une mauvaise configuration peut survenir
Les avantages (réacheminement, mise à l'échelle, protection, terminaison TLS, répartition de la charge) dépassent généralement les coûts pour tout système non trivial. Mais il y a une limite : chaque couche d'indirection ajoute un saut supplémentaire et un candidat supplémentaire à point de défaillance unique (SPOF).
La règle folklorique : tout problème peut être résolu en ajoutant une couche d'indirection (sauf le problème de trop de couches d'indirection).
Lire une architecture comme un graphe
Synthèse
Vous pouvez désormais lire une architecture système comme un graphe : compter les sauts, identifier les sommets de coupure, mesurer la concentration de l'entrée (fan-in), calculer les plafonds de disponibilité à partir de la sortie (fan-out) et évaluer les compromis liés à l'indirection.
Appliquez les quatre.
Un nouveau service a cette architecture : clients -> CDN -> reverse proxy (2 répliques) -> backend tier (8 répliques) -> { DB primaire, cluster de cache (3 nœuds), API externe }.
Notes de l'accompagnant
Notes de l'accompagnant
Cette leçon de géométrie reformule la leçon principale Proxies & Origines comme une analyse de graphe orienté.
Le prochain accompagnant de ce cours, geometry_of_stateless_horizontal_scaling, prend les calculs de répliques de la leçon principale sur le dimensionnement horizontal et dérive géométriquement la courbe de file d'attente, la loi de Little et le point d'inflexion à 80 % de taux d'utilisation.
Bravo.