Home » Comment ça marche, Internet, Sysadmin

Comment mesurer la bande passante

29 août 2010 4 928 vues 3 commentaires
tags : , , ,
Download PDF

Un petit article mi figue (explications) mi raisin (technique). Commençons par les figues. (ne regardez pas l’image ci-contre, elle n’a rien à voir avec la choucroute)

On distingue trois méthodes de facturation de la bande passante :

  • Au forfait, le fournisseur vous alloue un lien supportant un débit maximal et vous facture un prix fixe mensuel quel que soit la consommation faite sur le lien. C’est le cas de l’ADSL en France.
  • A la consommation, le fournisseur regarde, généralement sur un mois, le nombre de bits qui ont circulé sur la liaison et vous facture un prix par bit transféré
  • Au débit, le fournisseur utilisant généralement une méthode de calcul en centile.

C’est un terme assez peu connu, mais utilisé un peu partout. Dans le domaine médical par exemple, lors d’une naissance, on dit que la taille du bébé est dans le 70e centile, ce qui veut dire que sur 100 mesures effectuées à la naissance et triées dans l’ordre croissant, le bébé en question serait classé 70ème.

La plus part des fournisseurs facturent selon la méthode du 95e centile mensuel sur un échantillonnage de 5 minutes. Quelques uns ont adopté le 90e centile, plus avantageux pour le client.

Concrètement, un logiciel de mesure stock toutes les 5 minutes la différence de consommation entre l’instant T et la mesure précédente sur un port réseau. Elle obtient donc un débit en bits par tranche de 5 minutes qu’il suffit de diviser par 300 pour obtenir une moyenne de débit en Mbps sur les 5 minutes en question.

A la fin du mois, si on suppose un mois de 30 jours, on a donc obtenu 8640 valeurs de consommation moyenne sur 5 minutes. On trie ces valeurs par ordre croissant, on supprime les 5% (soit, en l’occurrence, 432 mesures) les plus hautes et on facture la valeur la plus haute restante.

De manière pratique cela revient à offrir au client les 432 tranches de 5 minutes ou il a consommé le plus (soit 36 heures pour un mois de 30 jours). C’est absolument inutile dans le cas d’un client qui consomme de la bande passante de façon purement linéaire, mais ce profil est très rare.

Pour prendre un cas concret, vous lancez un site web en grande pompe a grands renforts de pub radio/télé et de conférence de presse, votre trafic va exploser le jour du lancement puis décroitre rapidement avant de se stabiliser à sa valeur « normale » une dizaine de jours après la campagne de communication.

Pour un site s’adressant aux particuliers, les heures de pointes sont généralement entre 11h et 13h et entre 19h et 23h, soit 6 heures par jour, ce qui vous laisse donc 6 jours pendant lesquels votre consommation maximale ne sera pas comptabilisée.

On constate généralement que la facture 95e centile correspond environ a une valeur située entre 55 et 70% des pointes de consommation effectuées et entre 1.5 et 4 fois plus élevé que la consommation moyenne. Si vous aviez choisi une facturation forfaitaire à un débit limité a cette même valeur du 95e centile constatée, votre site aurait tourné au ralenti en moyenne une heure par jour, pile aux heures de pointe, ce qui n’est généralement pas acceptable.

Vous remarquerez, dans l’image ci-dessus, que la consommation maximale effectuée sur le lien (donc la taille indispensable pour que le trafic soit toujours fluide) a été, sur les 30 derniers jours, de 146Mbps, mais que le 95e centile est de 133Mbps, soit 10% d’économie sans souffrir du ralentissement.

Ceci étant, la méthode de calcul est compliquée à expliquer à un client final, elle n’est donc généralement utilisée que dans les relations contractuelles entre opérateurs qui savent déjà de quoi il retourne.


A présent, attaquons le raisin.

Pour générer le joli graphique ci-dessus, la première chose à faire est de faire des mesures de façon régulière. Il existe tout un tas de logiciels déjà fait pour ça (Cacti, Zabbix, MRTG …) mais je préfère toujours les choses faites à la main. Voici donc comment récupèrer les compteurs d’octets sur les interfaces d’un switch (l’OID SNMP en question est valable pour presque tous les équipements du marché) :

snmpwalk -v 1 -c .1.3.6.1.2.1.2.2.1

Attention, cette commande va vous inonder si votre switch a beaucoup de ports. Vous trouverez, dans l’ordre :

  • Les numéro des interfaces (pour vous y retrouver)
  • Les descriptions des interfaces (telle qu’elle a été entrée dans l’équipement)
  • Le type d’interfaces
  • Les MTU des l’interfaces
  • Les vitesse des interfaces
  • Les adresses MAC des interfaces
  • Les statuts administratif des interfaces (activé ou pas)
  • Les statuts logiques des interfaces (pour une interface activé, est-ce qu’une machine est allumée au bout ou pas)
  • Les temps depuis lesquels les interfaces sont up (le cas échéant)
  • Les compteurs d’octets entrants
  • Les compteurs de paquets entrants
  • Les compteurs d’erreurs entrantes
  • La même chose avec le sortant

Tout ceci étant généralement suivi par un tas d’autres infos spécifiques aux équipements que je ne détaillerai pas ici.

Vous voici armé pour connaitre la quantité d’information (octets et paquets) qui circulent sur chaque port de chacun de vos switchs. Notez qu’il peut être pertinent de surveiller le reste et, par exemple, d’envoyer une alerte a qui de droit lorsqu’un port passe du statut UP à DOWN ou inversement.

Maintenant, comment les stocker. Vous pouvez tout bêtement mettre tout ça dans une jolie base SQL mais des gens ont réfléchi au problème de l’historisation du trafic réseau et ont trouvé une façon de faire plutôt sexy : round robin database. Il s’agit de créer une base de donnée d’une taille fixe qui ne bougera pas dans le temps et ou, lorsqu’on est arrivé à la remplir, les données suivantes effacent les données les plus anciennes.

Vous me direz, c’est bien joli, mais si on veut garder les infos 10 ans, il faut d’emblée prévoir l’espace disque pour 10 ans. Oui et non, RRD étant parfaitement capable de gérer une dégradation de la granularité (non, je n’insulte pas votre maman).

Explications : garder 10 ans les infos, c’est très bien, mais dans 6 ans, vous n’aurez probablement pas besoin de connaitre précisément la consommation de tel port sur une période de 5 minutes. Ce qui intéresse généralement les gens du réseau, c’est de pouvoir obtenir un graphique montrant l’évolution de la consommation sur les X dernières années. Il est donc idiot, dans ce cas, de garder 8640 valeurs de mesures mensuelles dans la base de donnée, RRD va donc faire une moyenne de ces valeurs.

Tous les calculs de moyennes sont paramétrables. On peut par exemple lui dire « conserve une mesure par tranche de 5 minutes pendant 6 mois, la moyenne sur une demi heure pendant 2 ans, sur une journée pendant 10 ans, et sur une semaine pendant 100 ans » ce qui, si vous calculez bien, vous donne 51840 + 35040 + 3650 + 5200 = 95730 points de mesure sauvegardés dans la base pour avoir la possibilité d’avoir un graphique sur 100 ans qui ait une belle gueule contre 10512000 points si vous aviez gardé l’ensemble des mesures faites toutes les 5 minutes. Biensur, si vous demandez le graphique d’une journée d’il y a 5 ans, avec ce système, vous obtiendrez un joli pâté qui vous indiquera la valeur moyenne de la bande passante consommée ce jour la.

Evidemment, pour avoir ce beau graphique, il faut encore penser a remplir son fichier RRD toutes les 5 minutes pendant 100 ans, ce qui est probablement impossible. Il faut par ailleurs prendre grand soin des déclaration de ces moyennes, car une fois que le fichier est constitué, il est relativement difficile de revenir sur ces choix.

Une autre fonction présente dès la déclaration de la base RRD, c’est la notion d’historisation des maximas, minimas et moyennes. En effet, conserver la moyenne de débit d’une journée d’il y a 4 ans, c’est bien, mais savoir quels étaient les maxima et minima de ce même jour, c’est encore mieux.

On déclare donc, lors de la création d’une base RRD, plusieurs RRA qui sont les fameux endroit ou seront stockés les données et qui calculerons automatiquement les moyennes.

Enfin, on peut inclure dans une même base plusieurs sources de données, DS

Par exemple :

« –step », « 300 »,
« DS:in:COUNTER:600:0:U »,
« DS:out:COUNTER:600:0:U »,
« RRA:AVERAGE:0.5:1:46080″,
« RRA:AVERAGE:0.5:60:43800″,
« RRA:AVERAGE:0.5:360:29200″,
« RRA:MAX:0.5:1:46080″,
« RRA:MAX:0.5:60:43800″,
« RRA:MAX:0.5:360:29200″,
« RRA:MIN:0.5:1:46080″,
« RRA:MIN:0.5:60:43800″,
« RRA:MIN:0.5:360:29200″

C’est une déclaration classique de base RRD pour le trafic entrant et sortant d’un port de switch. Décortiquons :

  • On indique pour commencer l’intervalle de temps entre deux mesures. Ici, 5 minutes.
  • On déclare ensuite deux sources de données distinctes en leur donnant un nom (« in » et « out »). On indique ensuite que cette source est un compteur et qu’on va donc lui donner une valeur qui ne fera qu’augmenter avec le temps (sauf quand le compteur revient à 0 quand il a dépassé sa valeur maximale) et qu’il faut donc soustraire la valeur précédente à la nouvelle valeur pour trouver la différence. On indique ensuite le temps en seconde après lequel, si on n’a pas mis à jour la base RRD, elle considèrera que la valeur est inconnue et génèrera un trou dans le graphique (ici 10 minutes). Suivent les valeurs minimale et maximale possibles, soit 0 (le débit sur un lien n’est jamais négatif) et U qui signifie unknown, inconnu, et, dans le cas de RRD, illimité.
  • On déclare ensuite une première granularité de RRA pour la valeur moyenne (AVERAGE), suivi du facteur XFF qui indique combien il faut de valeurs inconnues pour que, dans le calcul d’une moyenne, le résultat soit inconnu. Ici, on estime que si la moitié des valeurs sont inconnues, alors, le résultat de la moyenne sera inconnu. On indique ensuite combien de mesures sont utilisées pour faire une moyenne (la première déclaration indiquant généralement 1 pour stocker exactement les mesures prises dans le premier RRA). Enfin, on indique le nombre de points de mesure qu’on stock dans le RRA en question.

Comme vous le remarquez, il n’y a donc pas de notion de temps attachées directement au RRA, tout se joue avec le step déclaré au début. Dans mon exemple, le premier RRA stock 46080 mesures sans faire aucune moyenne puisque le nombre de valeur à prendre en compte pour une mesure est de 1. Le step étant de 300 secondes, ce RRA sera valable pour 46080*300 secondes, soit 160 jours. Je vais donc conserver mes mesures exactes à un interval de 5 minutes pendant 160 jours. Notez que rien ne vous empeche de remplir plus souvent la base RRD

Le RRA suivant indique 43800 points de mesure à stocker mais une moyenne de 60 valeurs pour constituer une mesure. Le second RRA aura donc une durée de 43800*60*300 secondes, soit 25 ans et stockera une mesure toute les 60*300 secondes, soit 5 heures. Le dernier RRA aura une durée de 29200*360*300 secondes, soit 100 ans.

Il est important de noter que les RRA ne sont pas successifs, c’est a dire que ces 3 déclarations ne donneront pas une durée de vie de 100 ans + 25 ans + 160 jours mais bien une durée globale égale à la durée du plus grand RRA.

Concrètement, lorsque vous entrez une valeur dans la base RRD, elle va dans le premier RRA et, dans le cas de notre exemple, dès qu’il y a 60 valeurs entrées dans le premier RRA, la moyenne est calculée et constitue la première valeur du second RRA. Une fois que le premier RRA a 360 valeurs disponibles, il renseigne la moyenne de ces 360 valeurs dans le 3ème RRA, et ainsi de suite. Ceci est bien sur valable pour le RRA AVERAGE. Pour le RRA « MAX », ce sera la plus grande valeur des 360 retenues qui sera stockées dans le RRA du dessus, et pour MIN ce sera le minimum.

Il existe tout un tas de façon de créer et de mettre à jour une base RRD. La plus simple est probablement avec les commandes shell, mais vous trouverez des librairies perl, php etc .. En Perl, ça donne, pour la base constituée dans notre exemple :

RRDs::update (« fichier.rrd », « DATE:valeur_in:valeur_out »);

La date en question est idéalement le moment précis ou la mesure à été relevée (et pas le moment ou on met à jour le fichier, ce qui permet de créer un fonctionnement asynchrone, d’un coté les relevés dument horodatés, de l’autre l’alimentation des bases RRD). La date est exprimée au format EPOCH, soit le nombre de secondes écoulées depuis le 1er janvier 1970 à minuit. Si vous ne voulez pas vous enquiquiner à gérer l’horodatage des mesures et que vous êtes certain que la base RRD sera mise à jour juste après la prise de mesure, vous pouvez remplacer la date par « N », la base RRD prendra l’heure sur la machine au moment ou vous la mettez à jour.

Notez que vous devez faire les mises à jour de façon séquentielle. Vous ne pouvez pas insérer la mesure effectuée à 10h05 après avoir inséré la mesure effectuée à 10h20.

Si votre fichier RRD dispose d’une source (une mesure de température, par exemple), vous ne mettrez bien sur qu’une seule valeur après la date lors de la mise à jour.

Je cause, je cause, mais nous n’avons pour l’instant pas généré de joli graphique. Revenons à une commande utilisable en shell :

rrdtool graph demo.gif –title= »Bande passante » –end=now –start=end-3600s \
DEF:ind=fichier.rrd:in:AVERAGE \
DEF:outd=fichier.rrd:out:AVERAGE \
AREA:ind#00FF00:Input bytes \
LINE1:outd#0000FF:Output bytes

On crée ici un graph intitulé « Bande passante », basé sur la valeur moyenne des deux sources in et out définies dans notre fichier RRD. On crée pour cela des définitions de source (DEF) et on leur donne des noms (ind et outd). On dit ensuite qu’on veut dessiner une zone pleine partant du bas (AREA) avec la définition ind et en vert (#00FF00). On lui donne un nom un peu plus explicite. On fait pareil avec outd mais avec une ligne bleue.

Nous obtenons donc un graph avec nos deux valeurs qui termine à l’instant présent et qui démarre à l’instant présent moins 3600 secondes (une heure).

Mais nos amis du réseau préfèrent obtenir des graphs exprimés en megabits bits par secondes, pas en octets. On va donc introduire un peu de mathématique en notation polonaise inversée pour rire un peu. Il s’agit de passer d’o/s à Mbps, donc multiplier les octets par 8 pour obtenir des bits, puis diviser deux fois par 1024 pour passer à des Kbps puis à des Mbps. On modifie donc l’appel à graph comme ceci :

rrdtool graph demo.gif –title= »Bande passante » –end=now –start=end-3600s \
DEF:ind=fichier.rrd:in:AVERAGE \
DEF:outd=fichier.rrd:out:AVERAGE \
CDEF:inbits=ind,8,*,1000,/,1000,/ \
CDEF:outbits=outd,8,*,1000/,1000,/ \
AREA:inbits#00FF00:Input Mbps \
LINE1:outbits#0000FF:Output Mbps

Les lignes CDEF créent de nouvelles sources de données basées sur des sources existantes et précisant le fonctionnement. en l’occurence, le CDEF inbits correspond au DEF ind mutliplié par 8, divisé par 1000, et redivisé par 1000. Si vous n’avez pas eu droit à des cours de notation polonaise inversée à l’école, voyez par ici.

On n’oublie bien sur pas de modifier les directives de graph pour qu’elles dessinent des choses en se basant sur les CDEF et pas sur les DEF.

Pour finir, comment afficher sur ce même graph une ligne rouge pour indiquer le 95e centile ? RRD embarque tout ce qu’il faut pour ca, il suffit de modifier notre demande de graph comme ceci (avec affichage sur un mois) :

rrdtool graph demo.gif –title= »Bande passante » –end=now –start=end-2678400s \
DEF:ind=fichier.rrd:in:AVERAGE \
DEF:outd=fichier.rrd:out:AVERAGE \
CDEF:inbits=ind,8,*,1000,/,1000,/ \
CDEF:outbits=outd,8,*,1000,/,1000,/ \
VDEF:inpct=inbits,95,PERCENT \
VDEF:outpct=outbits,95,PERCENT \
AREA:inbits#00FF00:Input Mbps \
LINE1:outbits#0000FF:Output Mbps

HRULE:outpct#FF00FF \
HRULE:inpct#FF0000 \

La directive VDEF crée une valeur fixe sur le graph et les directives HRULE dessinent la ligne elle-même.

Voila, vous savez à peu près tout ce qu’il faut pour démarrer. RRDTool est une suite d’outils très riche, on peut faire de très jolies choses pleines de couleurs. Allez faire un tour par la pour voir certaines oeuvres. Vous pouvez aussi remonter en haut du présent billet pour voir les statistiques des vélib à Paris. Graph réalisé par mat sur son site dédié à vélib.

3 Comments »

  • Jérôme Dossard said:

    Article très intéressant, merci !
    Juste pour préciser que quand on parle de kbit/s ou Mbit/s en réseau-télécoms, on utilise généralement des puissances de 10. Donc j’aurai plutôt mis :
    [...]
    CDEF:inbits=ind,8,*,1000000,/
    CDEF:outbits=outd,8,*,1000000,/
    [...]
    dans vos exemples.

  • Bruno (author) said:

    Fort juste ! Les unités de débit en multiples de 1024 sont en réalité le Kibibit, mebibit, gibibit, tebibit, etc ..

  • coincoin said:

    a quand un post sur les mille et une maniere de calculer le 95th percentile =)

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.


+ 6 = quinze