la trilogie classique : iostat, vmstat, netstat
Dans un monde où tout est connecté, l'administrateur système doit pouvoir savoir ce qui se passe dans ses machines à trois niveaux : le réseau bien sûr, mais aussi le disque et la mémoire. Voici quelques explications sur les usages et les conclusions à en tirer.
La performance d'un système ne peut être réduite à la fréquence du processeur de la machine qu'il exploite. Il faut également prendre en compte le système d'entrées/sorties et le réseau, le tout relié à l'environnement général (d'où la notion de système eh eh) : applications utilisés, services ouverts, etc.
Dans la plupart des environnements Unix, iostat, vmstat et netstat sont les outils dédiés pour savoir ce qui se passe sous le capot et choisir la bonne configuration pour le bon usage. Passons-les en revue avec leurs différentes options et voyons comment on peut les relier aux autres composants du système et prendre le cas échéant, les décisions qui s'imposent.
iostat
iostat est la concaténation de "input output statistics". Il s'appelle sous Linux sysstat et n'est pas installé par défaut sur Ubuntu par exemple. Pas de problème, un petit :
sudo apt-get install sysstatfait l'affaire.
Que ce soit sous ce vocable (iostat) ou un autre (sysstat), ce binaire fournit des informations à propos de l'ensemble des périphériques d'entrée et sortie, à savoir : les disques (on suppose que vous en avez plus d'un), le ou les terminaux, les autres périphériques série et bien sur, la mémoire. En fonction des plates-formes, les options divergent mais l'esprit d'ensemble est le même. Nous allons nous concentrer ici sur les données qui concernent les disques.
La syntaxe de base est la suivante :
iostatinterval count
- option – chaque système est bien évidemment différent, excusez la répétition (c'est tout le charme du monde Unix) – un bon coup de manuel ne fera pas de mal, mais on peut voir quelques exemples pratiques;
- interval – c'est la période de temps entre chaque collecte d'information; iostat 5 fournira donc des données toutes les cinq secondes; faisons quand même attention à ne pas donner un intervale trop restreint qui surchargerait le système
- count – c'est le nombre de prélèvements que l'on veut effectuer; iostat 5 4 par exemple donnera donc des informations à 4 reprises espacées de 5 secondes; si aucun comptage n'est spécifié, la commande envoie les infos jusqu'à la fin des temps (ou presque) ou jusqu'à un fatidique ^C; en règle générale, l'on observe le rendu pendant quelques minutes durant des phases d'activité particulière pour un prélèvement qui présente un intérêt dans la durée
Prenons l'exemple d'une commande iostat typique sur un système Solaris (en train de roupiller comme vous pourrez le constater).
me@box:~$ iostat -xtc 5 2
extended device statistics tty cpu
device r/s w/s kr/s kw/s wait actv svc_t %w %b tin tout us sy wt id
cmdk0 1.0 2.3 10.9 19.4 0.0 0.0 5.4 0 1 0 59 13 3 0 84
fd0 0.0 0.0 0.0 0.0 0.0 0.0 986.3 0 0
sd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
sd1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
extended device statistics tty cpu
device r/s w/s kr/s kw/s wait actv svc_t %w %b tin tout us sy wt id
cmdk0 0.0 9.3 0.0 35.3 0.0 0.0 3.5 0 3 0 0 7 2 0 90
fd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
sd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
sd1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
- wait – le nombre moyen de transactions en attente d'être traitées
- actv – le nombre moyen de transactions en cours de traitement (elles ne sont plus dans la queue mais ne sont pas pour autant terminées)
- svc _t – le temps moyen de traitement
- %w – le pourcentage du temps durant lequel des transactions sont en attente d'un traitement
- %b – pourcentage du temps durant lequel le disque est occupé
Les colonnes r/s, w/s, kr/s, et kw/s montrent respectivement les read et write par secondes en octets et kilo-octets.
Sur OpenBSD, on obtiendrait le résultat suivant avec simplement iostat 5 2 :
iostat : les bonnes résolutions
Sur Solaris, les colonnes importantes à observer sont : svc_t, wait %w et %b – plus le temps de traitement est élevé, plus la performance s'en ressent bien évidemment. Couplés l'un à l'autre, le temps de traitement et le temps d'occupation donnent une bonne impression sur l'état des entrées / sorties d'un disque. Un taux d'occupation de plus de deux-tiers et un temps de traitement de plus de 50 millisecondes sont les indicateurs d'un goulot d'étranglement.
Que faire ? Voilà quelques pistes à explorer :
- répartir la charge sur plusieurs disques en utilisant un meilleur partitionnement;
- distribuer le swap (la pagination) sur plusieurs disques, ce qui a d'autant plus de sens que le swapping est important sur son système;
- faire figurer dans la mesure du possible les données liées sur la même partition;
- augmenter la mémoire (RAM) pour diminuer la pagination; c'est le cas par exemple lors de l'utilisation de SGBD qui sont très gourmands en mémoire, mais peu demandeurs de capacités de traitement rapides par le processeur;
- utiliser autant que faire se peut les ressources en cache des applications développées; php a par exemple un système de cache plutôt efficace aujourd'hui, très utile pour les requêtes et traitements récurrents;
- bien entendu, éviter d'écrire des requêtes qui parcourent les tables inutilement; cela demande donc une modélisation a priori qui arbitre entre un modèle E/R approprié et les capacités matérielles requises, sans oublier la manière dont on écrit les applications;
- si le disque est utilisé à 100%, on peut répartir le système de fichier sur deux disques ou plus en utilisant l'utilitaire de gestion des volumes disques que l'on trouve sous Solaris (le Volume Manager);
- déplacer le système de fichier vers un autre disque ou contrôleur plus rapide.
vmstat
vmstat effectue les rapports statistiques sur la mémoire virtuelle allouée aux processes, sur la mémoire virtuelle en tant que telle et sur le ou les disques et l'activité du processeur. C'est un outil utile pour comprendre comment les uns s'articulent par rapport aux autres au sein d'un même système. Sur les multi-processeurs, vmstat rapporte en général une moyenne.
La syntaxe basique pour vmstat est : la commande suivie par l'option et l'intervale du temps avec le nombre de fois que l'on souhaite répéter la commande (ça rappelle iostat de toute façon, c'est le même principe derrière) :
# vmstatinterval count
- options – on l'utilise pour une activité spécifique (un coup de man vmstat car là encore, les implémentations diffèrent);
- interval – c'est le temps entre deux prises d'instantané; trop peu de temps (< 5 sec) pas une vision exacte de l'état de la mémoire car le résultat serait surchargé par la commande elle-même;
- count – c'est le nombre de répétitions
La première ligne de vmstat donne la moyenne obtenue depuis le reboot du système et peut donc être ignorée pour des résultats que l'on souhaite obtenir pour un moment particulier. Sans l'option "count", la commande produit des résultats continuels jusqu'à ce qu'on la termine avec un Ctrl + C par exemple. On peut laisser ainsi filer pendant deux ou trois minutes en production à dix secondes d'intervalle et voir comment ça tourne.
Sans aucune des options, vmstat affiche une ligne de résumé de la moyenne de l'activité de la mémoire depuis le dernier boot. Voici un exemple avec Solaris, qui affiche des champs spécifiques :
example# vmstat 5 procs memory page disk faults cpu r b w swap free re mf pi p fr de sr s0 s1 s2 s3 in sy cs us sy id 0 0 0 11456 4120 1 41 19 1 3 0 2 0 4 0 0 48 112 130 4 14 82 0 0 1 10132 4280 0 4 44 0 0 0 0 0 23 0 0 211 230 144 3 35 62 0 0 1 10132 4616 0 0 20 0 0 0 0 0 19 0 0 150 172 146 3 33 64
Les champs importants sont : procs r en run queue b bloqués pour des I/O, de la pagination, etc. w swappé page (par seconde) re nombre de pages réclamées mf fautes mineures pi kilo-octets entrés en pagination po kilo-octets sortis en pagination fr kilo-octets libérés de manque de mémoire anticipé à court-terme (en kilo-octets)) sr pages scannées par un algorithme d'horloge cpu – c'est le pourcentage du temps d'utilisation de la CPU, qui affiche une moyenne dans le cas de systèmes multi-processeurs.
Voici un autre exemple avec AIX :
% vmstat 5 3 kthr memory page faults cpu ----- ----------- ------------------------ ------------ ------------ r b avm fre re pi po fr sr cy in sy cs us sy id wa 2 1 504038 3489832 0 0 0 0 0 0 2760 8705 1730 4 3 92 0 1 0 503080 3490975 0 0 0 0 0 0 5676 8619 4277 0 15 85 0 0 0 503073 3490982 0 0 0 0 0 0 1937 2707 232 0 0 99 0 * 1 page = 4096 bytesVoici le détail de l'ensemble :
- r : threads du kernel placés en queue
- b : threads du kernel bloqués
- avm : pages de mémoire virtuelle actives
- fre : pages de mémoire libre
- re : liste d'entrées / sorties en pagination
- wa : % du temps de la CPU en attente pour les entrées / sorties
Pour diagnostiquer les problèmes liés à la CPU, on doit porter notre attention aux colonnes "proc" et "cpu" (procs r). Sous Solaris, ça nous donne :
procs cpu r b w us sy id 0 0 0 4 14 82 0 0 1 3 35 62 0 0 1 3 33 64La sortie nous montre :
- r : c'est le nombre moyen de threads du kernel qui sont prêts et en attente de traitement (ils sont dits "runnable" en anglais);
- b : c'est le nombre moyen de threads du kernel en attente de ressource et d'entrée/sortie durant l'intervalle de l'échantillonnage effectué;
- w : les processes idle et swappés;
- us : le pourcentage de la CPU utilisé en mode utilisateur; cela signifie que le process n'utilise pas de ressources du noyau;
- sy : le pourcentage de temps CPU utilisé pour exécuter un process en mode système, donc avec des appels systèmes pour accéder au kernel;
- id : le pourcentage de temps durant lequel la CPU est inactive, c'est-à-dire qu'il n'y a pas de threads disponibles pour l'exécution ou que la queue de traitement est vide; vmstat ne prend pas en compte iowait lors du calcul de l'inactivité de la CPU, tandis que top et mpstat le font; d'où les différences de sortie entre les commandes;
- wa : le pourcentage de temps durant lequel la CPU est inactive et en attente d'opérations provenant du ou des disques locaux et des disques montés en NFS.
Pour identifier les problèmes, on peut prendre certains repères utiles :
- r : cette valeur devrait être inférieure à 5 sur des systèmes à simple CPU; sur des SMP, elle devrait être inférieure à 5 x (Ntotal - Nbind), où Ntotal est le nombre total de processeurs et Nbind est le nombre de processeurs qui sont attachés à des processes;
- b : cette valeur devrait être proche de zéro; si la valeur de la file d'exécution augmente, celle de la file d'attente aussi; si les threads sont activés en même temps durant un intervalle d'une seconde, la file d'exécution peut être important mais montre une faible utilisation de la CPU si les threads sont remis en sommeil juste après; si les processes sont suspendus en raison d'un manque de mémoire, la colonne indiquant les processes bloqués (b) dans le rapport de la commande indique l'augmentation du nombre de threads plutôt que la file d'exécution;
- wa : une valeur de plus de 25 pourcents indique que les disques concernés sont lourdement chargés.
Voilà quelques esquisses de solutions :
- si le nombre de processes dans la colonne "r" sous procs est constamment supérieure au nombre de CPUs sur le système, alors cela ralentira le système car le nombre de processes dépasse celui de CPUs disponibles;
- si ce nombre est plus de quatre fois supérieures au nombre de CPUs disponibles dans le système, alors on est face à un manque problématique de ressources en processeurs;
- si le temps d'inactivité (cpu id) est constamment à 0 et le temps de CPU-système est (cpu sy) est le double du temps CPU-utilisateur (cpu us), le système fait face à un manque de ressources en processeurs.
En poussant le raisonnement, on gardera en mémoire les aspects suivants (en quelque sorte une liste des choses à faire) :
- l'identification et le réglage des processes gourmands en CPU;
- un meilleur usage de la mémoire dans les pratiques de développement;
- une mise à jour du processeur, plus rapide ou surtout, plus adapté au type de traitement;
- un ajout de mémoire pour soulager la CPU;
- un ajustement des priorités entre les processes de façon à ce que ceux qui ont la priorité la plus basse ne consomment pas toutes les ressources de la CPU;
- contrôler les tranches horaires de manière à ce qu'elles s'ajustent à la cadence de ou des CPUs.
vmstat permet également de collecter des informations sur la mémoire. On les trouve dans les colonnes suivantes :
- pi : il s'agit du nombre de pages depuis la mémoire virtuelle qui se trouve sur le disque;
- po : le nombre de pages renvoyées dans l'espace de pagination; quand un processus se termine normalement, l'espace de pagination qui lui était alloué est libéré;
- fr : le nombre de pages libérées par seconde; il faut toujours un minimum de ressources système pour libérer une page, même si le système d'entrée / sortie n'est pas en jeu;
- sr : le "scan rate" (disons : taux de balayage) est le nombre de pages examinées par seconde par l'algorithm de remplacement de page; sur des systèmes avec de multiples processes utilisant beaucoup de pages différentes, le taux de balayage peut de loin dépasser le taux de libération (fr);
- de : sous Solaris, la colonne "de" représente le manque anticipé de mémoire en Ko qui est utilisé par le système de balayage de pages pour faire face aux besoins.
On en déduit tout naturellement que :
- la mémoire est sur-sollicitée quand le rapport de fr à sr est élevé;
- un rapport fr:sr de 1:4 signifie que pour chaque page libérée, quatre pages ont dû être examinées; cela étant, on ne peut déterminer la contrainte subie par la mémoire basée sur ce ratio car il dépend de la charge applicative;
- les goulots d'étranglement en mémoire sont déterminés par sr; il s'agit du nombre de pages scannées par l'algorithme d'horloge par seconde; si sr est continuellement supérieur à 200 pages par secondes, on en déduit un manque de mémoire;
- si la colonne "de" est non nulle, alors le système anticipe des manques de mémoire et de la mémoire libre va être réclamée pour une utilisation ultérieure; pour la disponibilité d'ensemble de la mémoire, "de" donne une bonne indication pour savoir si le système se trouve confronté à un manque de mémoire;
- si des entrées / sorties sont en attente pour le périphérique de swap, il faudra augmenter la mémoire pour réduire les E/S à ce niveau; parfois, on l'entend tout simplement à l'oreille (cric-cric-cric, enfin... vous voyez);
- attention aux processes zombies, qui ne servent plus à rien mais continuent d'occuper de l'espace.
Pour régler ça, voilà quelques actions simples à mener :
- collecter plus d'informations sur les processes qui utilisent le plus de mémoire et trouver les raisons d'un tel comportement;
- régler l'allocation de mémoire pour les instances du serveur d'applications Java et arrêter les instances inutiles;
- régler les applications et les serveurs pour une meilleure utilisation de la mémoire et des caches;
- augmenter la mémoire du système;
- sous Solaris, on peut activer la pagination prioritaire en ajoutant la ligne "set priority paging=1" dans /etc/system;
- supprimer les processus zombies du système.
netstat
C'est un peu l'incontournable du réseau. En règle générale, on retrouve au moins trois ou quatre options communes aux différents *nix. La syntaxe est la suivante :
#netstatavec les options les plus significatives :
- -a – montre l'état de tous les sockets
- -r – montre les tables de routage du système
- -n – montre les adresses réseaux sous formes d'adresses IP non-résolues; c'est pas mal dans la mesure où ça fatigue moins le système de résolution de nom qui doit à chaque fois envoyer une requête pour résoudre une IP;
- -i – pour sélectionner une interface réseau donnée
- -v – eh oui, comme verbose.
Commençon avec un peu de routage appliqué pour démarrer avec netstat. On utilise pour cela les options r et n. En voici un exemple sous Solaris :
$netstat -rn Routing Table: IPv4 Destination Gateway Flags Ref Use Interface -------------------- -------------------- ----- ----- ------ --------- 192.168.1.0 192.168.1.11 U 1 1444 le0 224.0.0.0 192.168.1.11 U 1 0 le0 default 192.168.1.1 UG 1 68276 127.0.0.1 127.0.0.1 UH 1 10497 lo0On constate que l'adresse de la machine est 192.168.1.11 et la route par défaut 192.168.1.1.
Lorsque le réseau extérieur n'est pas accessible, on vérifie que :
- l'adresse par défaut est correcte
- on peut pinger le router depuis la machine
$route add default 192.168.0.1par exemple à effectuer en mode super-utilisateur bien évidemment. Toujours aussi évidemment, on vérifie sa câblerie (c'est même à effectuer en premier).
Sous OpenBSD ou tout autre *nix du même genre, on peut constater qu'il faut de toute façon ajouter la route "à la main" (comprenez en script) lors d'une connexion PPPoA (Point to Point Protocol over ATM), soit en réalité lors d'une connexion ADSL standard grand public. C'est valable pour n'importe quel FAI. On commence donc avec un :
$ifconfig -a (ou ifconfig tun0 directement)ce qui donne :
tun0: flags=8051et on voit que la dernière ligne de l'interface tun0 (créée par ppp) indique avec une flèche évocatrice une connexion point à point dont le premier terme est l'adresse IP publique et le deuxième est bien évidemment l'IP de la route. On donnera en paramètre cette dernière à la commande de routage mentionnée plus haut et le tour est joué. On notera au passage l'indication précieuse de la MTU (Maximum Transfer Unit) qui est optimisée pour le type de connexion utilisée (et non la taille par défaut : 1500, le plus souvent).mtu 1454 groups: tun egress inet6 fe80::212:3fff:fe76:3164%tun0 -> prefixlen 64 scopeid 0xb3 inet 211.152.74.18 --> 62.114.19.202 netmask 0xffffffff
L'option "i" de netstat donne des indications précieuses sur la transmission des paquets et les collisions de données sur les interfaces réseaux (toutes sont listées par défaut). C'est très utile quand on a par exemple une solution GPRS / 3G et que vous vous apercevez que votre consommation semble élevée. On scripte alors chacune de ses connexions, on fait le total et on voit que SFR (mais les autres doivent adopter la même méthode), calcule les paquets de données non pas octet par octet mais directement par palliers de dix octets. De quoi gratter ici et là du traffic.
Voyons dans le détail :
$ netstat -i Name Mtu Net/Dest Address Ipkts Ierrs Opkts Oerrs Collis Queue lo0 8232 loopback localhost 77814 0 77814 0 0 0 hme0 1500 server1 server1 10658566 3 4832511 0 279257 0Les valeurs importantes à noter sont :
- collisions (Collis)
- les paquets envoyées (Opkts)
- les paquets reçus (Ipkts)
- les paquets erronés (Ierrs)
- (Collis+Ierrs+Oerrs)/(Ipkts+Opkts) > 2% peut indiquer un problème physique dans le réseau;
- (Collis/Opkts) > 10% indique que l'interface réseau est surchargée et qu'il faut redistribuer les charges;
- (Ierrs/Ipkts) > 25% montre un gros nombre de paquets abandonnés en raison d'un hôte ou d'un réseau surchargé;
- s'il y a plus de 120 collisions par secondes, le réseau est surchargé;
- si la somme des paquets entrants et des paquets sortants est supérieure à 600 pour une interface de 10-Mbs et à 6000 pour une interface de 100-Mbs, le segement est trop chargé et une redistribution du réseau s'impose;
- un nombre important d'erreurs dans les colonnes "Ierrs" et "Oerrs" indique un problème de transmission et/ou de réception. Il se peut que la source et la destination aient des réglages différents comme full-duplex d'un côté et half-duplex de l'autre.
Passons à présent aux sockets avec l'option a. Il s'agit d'examiner tout particulièrement les états TCP (et ils sont nombreux et significatifs), ce qui nous donne :
- CLOSED : fermé; le socket n'est pas utilisé
- LISTEN : à l'écoute de connexions entrantes
- SYN_SENT : essai d'établir une connexion
- SYN_RECEIVED : synchronisation initiale de la connexion en cours
- ESTABLISHED : connexion établie
- CLOSE_WAIT : fermeture à distance (côté serveur par exemple); en attente de fermeture du socket
- FIN_WAIT_1 : socket fermé; terminaison de la connexion
- CLOSING : fermé, puis fermeture à distance; attente d'accusé de réception
- LAST_ACK : terminaison à distance puis fermeture; attente d'accusé de réception
- FIN_WAIT_2 : socket fermé; en attente de terminaison de la part du pair distant
- TIME_WAIT : en attente après fermeture pour la retransmission de la terminaison distante
Voyons un exemple :
#netstat -nar -p tcp Local Address Remote Address Swind Send-Q Rwind Recv-Q State *.* *.* 0 0 24576 0 IDLE *.22 *.* 0 0 24576 0 LISTEN *.32775 *.* 0 0 24576 0 LISTEN *.32776 *.* 0 0 24576 0 LISTEN *.* *.* 0 0 24576 0 IDLE 192.168.1.184.22 192.168.1.186.56806 38912 0 24616 0 ESTABLISHED 192.168.1.184.22 192.168.1.183.58672 18048 0 24616 0 ESTABLISHEDJe demande à voir l'ensemble des connexions en demandant d'obtenir les tables de routage (option -r) sans résolution de nom (option -n; ça économise des ressources et du temps, surtout que parfois, les résolutions plantent). Je souhaite aussi qu'il y a uniquement le protocole TCP listé (on peut demander uniquement l'UDP).
Trop de connexions avec un état FIN_WAIT ? Cela signifie généralement qu'il faut modifier le paramétrage TCP/IP car les connexions ne sont pas terminées (en tout cas terminées proprement d'après les séquences prévues) et des connexions inactives s'accumulent. Cela peut conduire à un épuisement des ressources système. Le mieux est de contrôler le TCP "timeout" qui ferme au bout d'un certain nombre de secondes une connexion inutilisée. Le pool peut ainsi être utilisé par de nouvelles connexions.
On peut aussi prendre un autre cas qui montre une connexion en ssh toute simple vue depuis le serveur :
Active Internet connections (including servers) Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp 0 48 212.141.150.80.22 92.34.72.248.29038 ESTABLISHED tcp 0 0 *.80 *.* LISTEN tcp 0 0 *.3306 *.* LISTEN tcp 0 0 *.22 *.* LISTEN tcp 0 0 *.37 *.* LISTEN tcp 0 0 *.13 *.* LISTEN tcp 0 0 *.113 *.* LISTEN tcp 0 0 127.0.0.1.8021 *.* LISTEN tcp 0 0 *.587 *.* LISTEN tcp 0 0 *.25 *.* LISTEN tcp 0 0 127.0.0.1.953 *.* LISTEN tcp 0 0 192.168.1.1.53 *.* LISTENDans la colonne Local Address, le socket (l'adresse IP plus le port) indique bien le port 22 et pour la colonne Foreign Address, le socket indique un port non-privilégié : 29038.
Pour les nomades qui vont capter du signal radio un peu partout sur leur portable, netstat peut être utilisé en conjonction avec nmap par exemple. On aura l'occasion d'en parler dans un prochain article.
tags : administration système, iostat, vmstat, netstat
mis en ligne : Wed Apr 23 16:49:32 CEST 2008