Estimer ce qu'on ne peut pas mesurer
Une matrice de trafic déduite des compteurs de liens, le collecteur de flux que j'ai décidé de ne pas construire, et les limites honnêtes de mon propre laboratoire
Michel Wijnberg
Le billet précédent s’est arrêté une question trop tôt, exprès. Osprey peut vous dire
que couper nrt1-cr1 ↔ sea1-cr1 change 56 chemins et n’isole personne. La question
que pose ensuite un exploitant est celle qui décide si le changement est sûr :
Où va le trafic, et est-ce que quelque chose déborde ?
Personne ne valide un changement sur le seul décompte des chemins. Le nombre qui décide, c’est la capacité : les liens qui héritent du trafic ont-ils la place de l’absorber ? Ce billet parle de la distance qu’on peut honnêtement parcourir vers ce nombre quand rien dans le réseau ne le mesure directement, et de l’endroit où cette réponse cesse d’être une réponse sur laquelle s’appuyer.
Y répondre suppose de savoir combien de trafic circule de chaque source vers chaque destination : une matrice de trafic. Presque personne n’en a une.
Ce que j’ai décidé de ne pas construire
La voie classique vers une matrice de trafic est l’export de flux : NetFlow, sFlow, IPFIX. Les routeurs échantillonnent des flux, expédient des enregistrements à un collecteur, et vous les agrégez en demandes origine-destination.
J’avais prévu cela. Il y a dans ce dépôt un document de conception de 1 139 lignes pour un collecteur de flux avec déduplication consciente de la LSDB. Il est marqué, dès sa première ligne :
Status: SHELVED (2026-03-12). Deferred indefinitely after cross-plan feasibility review.
avec cinq raisons énoncées. Les deux qui ont réellement tranché :
- Volume. 70 à 220 Go par semaine à 500 routeurs, environ cent fois tout le reste de la base. PostgreSQL est le seul magasin de données de ce produit, à dessein ; avaler un pipeline de flux implique soit un second magasin, soit une base qui s’écroule.
- Valeur marginale. Environ 80 % de la visibilité trafic utile en pratique était déjà disponible via les compteurs d’interface SNMP, déjà collectés.
Ce n’est pas une impossibilité technique. C’est un jugement : les derniers 20 % coûtent un nouveau sous-système, une nouvelle charge d’exploitation et une catégorie de risque de stockage, et je n’ai pas trouvé que cela en valait la peine. Des gens raisonnables en jugent autrement ; certains réseaux ont vraiment besoin de flux. Ce qui compte ici, c’est que la décision est écrite avec son raisonnement, de sorte que quiconque évalue Osprey peut vérifier si sa situation ressemble à la mienne.
Donc : pas d’enregistrements de flux. Ce qui laisse le problème intéressant.
Déduire la matrice de ce que les liens admettent
Ce qu’Osprey a, c’est la charge de chaque lien, mesurée correctement : compteurs
64 bits ifHCInOctets / ifHCOutOctets, relevés sur un cycle, différenciés en bits
par seconde, corrigés des rebouclages, et divisés par le débit de l’interface pour un
pourcentage d’utilisation.
C’est un ensemble de totaux par lien. Ce que vous voulez, c’est un ensemble de demandes par paire. Récupérer le second depuis le premier est un problème inverse sous-déterminé : de nombreuses matrices de trafic différentes produisent exactement les mêmes charges de liens. Il existe une approche bien connue : Tomogravity (Zhang, Roughan et al., 2003).
Elle se joue en deux temps, et Osprey implémente les deux :
// computeTrafficEstimate estimates traffic redistribution after topology
// mutations using the gravity model (Zhang/Roughan et al., "Tomogravity" 2003).
//
// Without a full traffic demand matrix, per-pair demands are estimated using
// the gravity model: demand(i,j) ∝ V(i)·V(j)/V_total, where V(i) is the
// total traffic volume at device i (derived from SNMP interface utilization).
// These gravity demands are then calibrated against observed per-link loads
// so that the model's predictions match reality.
L’étape gravitaire suppose que le trafic entre deux routeurs est proportionnel au produit de ce que chacun porte au total, la même forme que la gravitation newtonienne, ou qu’un modèle d’échanges entre deux économies. C’est un a priori, pas une mesure, et il est faux de façons précises : il n’a aucune notion de paire de voisins bavarde ou silencieuse.
L’étape tomographique est ce qui le rend utilisable. L’estimation gravitaire est mise à l’échelle pour que, une fois chaque demande estimée routée sur les chemins que l’IGP sélectionne réellement, les charges de liens obtenues correspondent aux charges mesurées. L’a priori est corrigé par les preuves, et les preuves sont ici la seule chose qui ne soit pas une supposition.
Alors, et alors seulement, les demandes calibrées sont reroutées sur les chemins d’après-panne (pondérés ECMP, de sorte qu’une paire dont le trafic se divise en quatre contribue pour un quart à chaque lien), et la différence est la redistribution projetée.
Trois choix délibérément peu spectaculaires
L’ingénierie intéressante dans un estimateur est tout entière dans les endroits où vous l’empêchez d’être confiant.
Calibrer globalement, pas par lien. La version tentante calcule un facteur d’échelle pour chaque lien indépendamment. Elle colle mieux aux données et elle est bien pire :
// Compute a GLOBAL calibration factor: total observed bps / total gravity sum.
// Per-link calibration can amplify noise when gravitySumPerLink is small
// relative to observed traffic, producing extreme scaling factors that
// inflate per-pair demands unrealistically. Global calibration distributes
// the error uniformly, producing more stable and realistic results.
Un lien silencieux avec une somme gravitaire quasi nulle et un peu de trafic mesuré produit un facteur d’échelle énorme, qui gonfle ensuite chaque paire qui le traverse. L’ajustement plus serré vous achète des absurdités occasionnelles. Un seul facteur global répartit l’erreur uniformément et n’explose jamais.
Plafonner toute paire à 5 % du volume total. Un plafond dur sur la part du réseau qu’une demande estimée a le droit de représenter, parce que le mode de défaillance d’un problème inverse est qu’une paire absorbe tout.
Refuser de signaler les petits changements. Un déplacement projeté inférieur à 0,5 % d’utilisation de lien est écarté, et 0,1 % sur le chemin des changements de coût, qui porte aussi les liens et nœuds hypothétiques et répartit finement l’effet d’un nouveau nœud de transit sur de nombreux liens. En dessous, le nombre est indiscernable du bruit des compteurs, et l’imprimer invite quelqu’un à agir sur du bruit.
Chacun de ces choix rend la sortie moins précise en apparence. La précision n’est pas le but ; le but est qu’un nombre affiché à l’écran soit un nombre sur lequel vous pouvez vous appuyer.
Et maintenant la partie où mon laboratoire ne peut pas m’aider
Tout ce qui précède dans les huit billets antérieurs a été validé face à un laboratoire capable de me contredire. 4 032 paires de routeurs contrôlées contre de vraies tables de routage. 360 couloirs fictifs trouvés. Trois protocoles, trois chemins de découverte, d’accord sur le même point de défaillance unique.
Pour le trafic, le laboratoire est quasiment inutile, et je veux être exact sur le pourquoi.
Les routeurs de ce laboratoire n’acheminent presque rien. Ils font tourner des protocoles, ils échangent des LSA et des mises à jour BGP, et c’est à peu près tout. Les mesures :
| Mesure | Valeur |
|---|---|
| Interfaces avec données d’utilisation | 1 279 |
| …sous 0,05 % d’utilisation | 1 241 |
| Utilisation maximale observée | 0,431 %, sur un port à 10 Mbps |
| Débit d’interface maximal observé | ~43 kbps |
| Pic sur les 368 interfaces prévues pour 10 Gbps | ~24 kbps, soit 0,00024 % |
Vous pouvez en voir la conséquence dans la capture de simulation du billet précédent, si vous savez où regarder. L’en-tête des liens coupés indique “2 links, 6Kbps displaced”, six kilobits, et le panneau ne montre aucune section de redistribution de trafic et aucun risque de congestion. Non parce que le code n’a pas tourné. Parce que chaque déplacement projeté est tombé sous ce plancher de bruit de 0,5 % et a été correctement écarté.
La plomberie est vérifiablement juste : les compteurs sont lus, les débits différenciés, les demandes gravitaires formées, la calibration tourne, la redistribution est calculée sur les chemins ECMP d’après-panne, et le plancher de bruit rejette ce qu’il doit rejeter. Ce que le laboratoire ne peut pas me dire, c’est si l’estimation est bonne, parce que valider un estimateur exige une vérité de terrain à laquelle se comparer, et la vérité de terrain ici signifie du vrai trafic avec une matrice origine-destination connue.
Un laboratoire sans trafic ne peut pas en produire une. Ajouter de la charge synthétique n’y changerait rien non plus : je générerais du trafic à partir d’une matrice que j’aurais choisie, puis féliciterais l’estimateur d’avoir retrouvé la matrice que je venais de lui donner. Ce n’est pas de la validation, c’est une façon très lente de tester ma propre arithmétique.
Alors, quelle confiance lui accorder ?
Voici l’échelle honnête, dans l’ordre où les nombres deviennent moins solides :
- Utilisation des liens, en direct et historique : mesurée. Compteurs 64 bits, différenciés, corrigés des rebouclages, contrôlés par rapport au débit d’interface. Ce sont des données.
- Quels chemins changent après une mutation : calculé depuis la topologie. Déterministe, et la topologie sous-jacente est celle validée sur 4 032 paires de routeurs.
- Combien de trafic se déplace sur chaque lien : estimé, à partir d’un a priori gravitaire corrigé par les charges de liens mesurées. Utile en tendance, calibré sur de vraies preuves, et ce n’est pas une mesure.
Le barreau 3 a une vraie valeur. C’est la différence entre « ces douze liens absorbent la panne » et « ce lien-ci en absorbe l’essentiel et il est déjà à 70 % ». C’est aussi le seul barreau de toute cette série à côté duquel je ne peux pas poser un chiffre de validation, et il serait malhonnête de le présenter sur le même ton que « 4 032 sur 4 032 ».
Le produit trace cette ligne là où il le peut. Quand le trafic d’un voisin BGP doit
être déduit de ratios de nombres de préfixes au lieu d’une interface SNMP appariée,
la ligne porte une infobulle qui le dit exactement, “Traffic estimated from prefix
count ratios (no SNMP interface match)”, à côté de lignes badgées SNMP qui
viennent de compteurs. Même tableau, gradué, ce qui est le motif sur lequel toute
cette série ne cesse de retomber, et c’est la troisième fois qu’il prend la même
forme. Un chemin interdomaine note ses segments resolved / inferred / opaque
(billet quatre) ; une annotation de port note
ses quatre verdicts du fait énoncé jusqu’à l’ambiguïté explicite
(billet six) ; les trois barreaux ci-dessus notent
un nombre de trafic. Trois échelles, une habitude : là où les preuves sous une
réponse sont inégales, notez-les sur place plutôt que d’émettre une confiance unique
pour l’ensemble.
À quoi sert le laboratoire, reformulé
Le billet sept soutenait que le laboratoire n’est pas là pour faire bien paraître Osprey, mais pour prouver qu’Osprey a tort. Ce billet-ci en est le corollaire que personne n’apprécie : un laboratoire ne peut réfuter que ce qu’il est capable de mettre en jeu.
Le mien est exceptionnellement bon pour me contredire sur la topologie, la sémantique des protocoles et l’acheminement, parce qu’il a 192 vrais routeurs avec de vraies tables de routage que je peux lire et comparer. Il est incapable de me contredire sur le trafic, parce qu’il n’en porte aucun.
Savoir dans laquelle de ces deux situations vous êtes, pour chaque nombre que votre produit imprime, fait l’essentiel de ce qui sépare un outil digne de confiance d’un outil simplement confiant. Je sais exactement quelles affirmations d’Osprey reposent sur la mesure, lesquelles sur un calcul au-dessus d’un modèle validé, et laquelle sur un estimateur auquel je crois mais que je ne peux pas prouver ici.
Ce billet est la troisième catégorie. Il y en a exactement une, et vous savez maintenant où elle se trouve.
Ensuite, le dernier billet de la série : le modèle est correct, et c’est aussi un modèle du maintenant. À quoi ressemblait le réseau une heure avant la panne ? Le réseau a une mémoire.