Surveillance des E / S Linux par fichier?


29

Je suis intéressé par un utilitaire ou un processus de surveillance des E / S disque par fichier sur CentOS.

Sur Win2008, l' utilitaire resmon autorise ce type de drilldown, mais aucun des utilitaires Linux que j'ai trouvés ne le fait (iostat, iotop, dstat, nmon).

Mon intérêt pour la surveillance des goulots d'étranglement d'E / S sur les serveurs de base de données. Avec MSSQL, je l'ai trouvé un diagnostic informatif pour savoir quels fichiers / espaces de fichiers sont les plus touchés.



1
Si cela est possible, notez que la plupart des fichiers sont mappés dans pagecache afin que vos numéros puissent être partout, en fonction des octets qui se trouvent dans pagecache et de ceux qui sont sur le disque.
Matthew Ife

@Matt Mais avec une réponse qui fonctionne!
ewwhite

Réponses:


18

SystemTap est probablement votre meilleure option.

Voici à quoi ressemble la sortie de l' exemple iotime.stp :

825946 3364 (NetworkManager) access /sys/class/net/eth0/carrier read: 8190 write: 0
825955 3364 (NetworkManager) iotime /sys/class/net/eth0/carrier time: 9
[...]
117061 2460 (pcscd) access /dev/bus/usb/003/001 read: 43 write: 0
117065 2460 (pcscd) iotime /dev/bus/usb/003/001 time: 7
[...]
3973737 2886 (sendmail) access /proc/loadavg read: 4096 write: 0
3973744 2886 (sendmail) iotime /proc/loadavg time: 11

L'inconvénient (en dehors de la courbe d'apprentissage) est que vous devrez installer le débogage du noyau , ce qui peut ne pas être possible sur un système de production. Cependant, vous pouvez recourir à une instrumentation croisée où vous compilez un module sur un système de développement et exécutez ce .ko sur le système de production.

Ou si vous êtes impatient, consultez le chapitre 4. Scripts SystemTap utiles du guide du débutant.


17

Script SystemTap * :

#!/usr/bin/env stap
#
# Monitor the I/O of a program.
#
# Usage:
#   ./monitor-io.stp name-of-the-program

global program_name = @1

probe begin {
  printf("%5s %1s %6s %7s %s\n",
         "PID", "D", "BYTES", "us", "FILE")
}

probe vfs.read.return, vfs.write.return {
  # skip other programs
  if (execname() != program_name)
    next

  if (devname=="N/A")
    next

  time_delta = gettimeofday_us() - @entry(gettimeofday_us())
  direction = name == "vfs.read" ? "R" : "W"

  # If you want only the filename, use
  // filename = kernel_string($file->f_path->dentry->d_name->name)
  # If you want only the path from the mountpoint, use
  // filename = devname . "," . reverse_path_walk($file->f_path->dentry)
  # If you want the full path, use
  filename = task_dentry_path(task_current(),
                              $file->f_path->dentry,
                              $file->f_path->mnt)

  printf("%5d %1s %6d %7d %s\n",
         pid(), direction, $return, time_delta, filename)
}

La sortie ressemble à ceci:

[root@sl6 ~]# ./monitor-io.stp cat
PID D  BYTES      us FILE
3117 R    224       2 /lib/ld-2.12.so
3117 R    512       3 /lib/libc-2.12.so
3117 R  17989     700 /usr/share/doc/grub-0.97/COPYING
3117 R      0       3 /usr/share/doc/grub-0.97/COPYING

Ou si vous choisissez d'afficher uniquement le chemin à partir du point de montage:

[root@f19 ~]# ./monitor-io.stp cat
  PID D  BYTES      us FILE
26207 R    392       4 vda3,usr/lib64/ld-2.17.so
26207 R    832       3 vda3,usr/lib64/libc-2.17.so
26207 R   1758       4 vda3,etc/passwd
26207 R      0       1 vda3,etc/passwd
26208 R    392       3 vda3,usr/lib64/ld-2.17.so
26208 R    832       3 vda3,usr/lib64/libc-2.17.so
26208 R  35147      16 vdb7,ciupicri/doc/grub2-2.00/COPYING
26208 R      0       2 vdb7,ciupicri/doc/grub2-2.00/COPYING

[root@f19 ~]# mount | grep -E '(vda3|vdb7)'
/dev/vda3 on / type ext4 (rw,relatime,seclabel,data=ordered)
/dev/vdb7 on /mnt/mnt1/mnt11/data type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

Limitations / bugs:

  • MMap à base d' E / S ne se présente pas , car devnameest -"N/A"
  • fichiers sur tmpfs ne se présentent pas à cause devnameest"N/A"
  • peu importe si les lectures proviennent du cache ou les écritures sont vers le tampon

Les résultats des programmes de Matthew Ife :

  • pour mmaptest privé:

     PID D  BYTES      us FILE
    3140 R    392       5 vda3,usr/lib64/ld-2.17.so
    3140 R    832       5 vda3,usr/lib64/libc-2.17.so
    3140 W     23       9 N/A,3
    3140 W     23       4 N/A,3
    3140 W     17       3 N/A,3
    3140 W     17     118 N/A,3
    3140 W     17     125 N/A,3
    
  • pour mmaptest partagé:

     PID D  BYTES      us FILE
    3168 R    392       3 vda3,usr/lib64/ld-2.17.so
    3168 R    832       3 vda3,usr/lib64/libc-2.17.so
    3168 W     23       7 N/A,3
    3168 W     23       2 N/A,3
    3168 W     17       2 N/A,3
    3168 W     17      98 N/A,3
    
  • pour le diotest (E / S directes):

     PID D  BYTES      us FILE
    3178 R    392       2 vda3,usr/lib64/ld-2.17.so
    3178 R    832       3 vda3,usr/lib64/libc-2.17.so
    3178 W     16       6 N/A,3
    3178 W 1048576     509 vda3,var/tmp/test_dio.dat
    3178 R 1048576     244 vda3,var/tmp/test_dio.dat
    3178 W     16      25 N/A,3
    

* Instructions d'installation rapide pour RHEL 6 ou équivalent: yum install systemtapetdebuginfo-install kernel


C'est une capture système assez impressionnante ici. Une excellente démonstration de sa polyvalence.
Matthew Ife

Cette mesure mesure-t-elle les E / S directes et les E / S asynchrones? (en utilisant io_submit, pas posix)
Matthew Ife

@Mlfe: merci! En remarque, en écrivant le script, j'ai réussi à découvrir un petit bug en pv et un autre dans SystemTap ( task_dentry_path) :-) Je n'ai aucune idée de cette E / S, mais je peux le tester si vous me donnez une commande ou un exemple de programme. Par exemple, j'ai utilisé Python pour tester mmap. dd iflag=direct oflag=directrévéler.
Cristian Ciupitu

2
Essayez ceci pour mmap: gist.github.com/anonymous/7014284 Je parie que les mappings privés ne sont pas mesurés, mais ceux partagés le sont ..
Matthew Ife

2
Voici un test IO direct: gist.github.com/anonymous/7014604
Matthew Ife

9

Vous voudriez réellement l'utiliser blktracepour cela. Voir Visualiser Linux IO avec Seekwatcher et blktrace .

Je verrai si je peux bientôt publier un de mes exemples.


Modifier:

Vous ne mentionnez pas la distribution de Linux, mais c'est peut-être un bon cas pour un script dtrace sur Linux ou même System Tap , si vous utilisez un système de type RHEL.


2
Merci, bonne chose et très proche du point, mais il fournit des informations détaillées sur la couche de bloc, j'ai besoin de quelque chose qui fonctionne sur la couche d'abstraction VFS.
GioMac

J'ai commencé à essayer quelques scripts SystemTap pour le faire fonctionner. J'ai échoué car le serveur est tombé en panne. Je peux obtenir ces informations sur Dtrace sur Solaris. Je vais essayer avec Linux aujourd'hui.
ewwhite

4

Le seul outil que je connaisse qui puisse surveiller l'activité d'E / S par fichier est inotifywatch. Cela fait partie du inotify-toolspackage. Malheureusement, cela ne vous donne que le nombre d'opérations.


4

utiliser iotop pour obtenir les PID des processus qui contribuent à un haut niveau d'E / S

exécuter strace contre le PID que vous avez généré, vous verrez quels fichiers sont accédés par un processus particulier

strace -f -p $PID -e trace=open,read,write

strace fournira des informations sur les appels système et les fichiers consultés, il sera très difficile d'analyser et d'obtenir des statistiques sur l'utilisation ...
GioMac

1
Je pensais que j'essaierais ça. Il génère BEAUCOUP de données. Et peut bloquer le processus lorsque vous ctrl + c. Cela semble plutôt dangereux.
Matt


2

Je dirais que vous avez peut-être posé la mauvaise question. si vous recherchez des goulots d'étranglement d'E / S, il peut être tout aussi important de voir ce qui se passe sur votre disque. Les db sont connus pour faire des E / S aléatoires, ce qui peut réduire considérablement le débit, surtout si vous n'avez que quelques broches.

ce qui peut être plus intéressant, c'est de voir si vous avez de longs temps d'attente sur les disques eux-mêmes. vous pouvez le faire avec collectl via la commande "collectl -sD", qui affichera les statistiques de performances des disques individuels. Sont --home pour le transformer en un utilitaire de haut niveau. S'il y a beaucoup de disques impliqués, exécutez-le via colmux: colmux -command "-sD" et il vous permettra de trier par une colonne de votre choix, même sur plusieurs systèmes.


Je ne suis pas en désaccord avec vous du point de vue du disque. Là où je peux obtenir un aperçu, c'est quand une base de données d'espaces de fichiers est utilisée pour partitionner des données, des index, des journaux, etc., mais montée sur des disques partagés lorsque les ressources sont limitées - des serveurs de développement par exemple. Idéalement, chacun de ces espaces de fichiers se trouverait sur des volumes séparés, donc regarder les entrées-sorties du point de vue du disque serait adéquat - ce qui explique probablement pourquoi tous les utilitaires de surveillance sont basés sur le disque et non sur des fichiers.
kermatt

C'est la bonne question; l'objectif est d'essayer de comprendre "à quelle table toutes ces E / S arrivent-elles?", et dans la plupart des bases de données, une table est un ou plusieurs fichiers. Tout disque va se retrouver avec de nombreux fichiers dessus, et déterminer lesquels sont les hotspots est une entrée de réglage de base de données utile.
Greg Smith

2

Vous pouvez surveiller les E / S par périphérique de bloc (via / proc / diskstats) et par processus (io comptabilité via /proc/$PID/ioou taskstats ), mais je ne connais pas de moyen de le faire par fichier.


0

Peut être inotify résoudra cela.

L'API inotify fournit un mécanisme de surveillance des événements du système de fichiers. Inotify peut être utilisé pour surveiller des fichiers individuels ou pour surveiller des répertoires. Lorsqu'un répertoire est surveillé, inotify renvoie des événements pour le répertoire lui-même et pour les fichiers à l'intérieur du répertoire.

Surveiller l'activité du système de fichiers avec inotify

Référence inotify


Cela peut fournir les appels effectués sur le fichier, mais offre peu pour aider à découvrir quel pid l'a fait, la taille de l'écriture, où et combien de temps cela a pris.
Matthew Ife

La question ne pose pas sur le processus (qui peut éventuellement être découvert par d'autres moyens, comme lsof)
Gert van den Berg

0

Bien qu'il y ait beaucoup de bonnes informations dans les réponses ici, je me demande si elles sont réellement applicables?

Si vous parlez de fichiers dans les 10s de gigaoctets, constamment écrits, alors à moins qu'il ne s'agisse de fichiers journaux ou similaires qui sont constamment ajoutés (dans ce cas, surveillez simplement la taille des fichiers), il est très probable que les fichiers soient mmapés . Si tel est le cas, la meilleure réponse pourrait être que vous devriez cesser de chercher la plupart des solutions. La première chose que vous devriez alors demander à toute autre solution proposée est "cela fonctionne-t-il avec mmap", parce que la plupart du temps ils ne le feront pas. Cependant, vous pouvez peut-être transformer le problème en surveillance d'un périphérique bloc plutôt qu'en surveillance d'un fichier.

Lorsqu'un programme demande une page à partir d'un fichier mmap, il fait simplement référence à un emplacement dans la mémoire virtuelle. Cette page peut ou peut ne pas être déjà en mémoire. SI ce n'est pas le cas, cela génère une erreur de page, ce qui déclenche le chargement de la page à partir du disque, mais cela se produit dans le système de mémoire virtuelle, qui n'est pas facilement lié à un processus d'application spécifique ou à un fichier spécifique. De même, lorsque votre application met à jour une page mmap'd, en fonction des indicateurs, cela peut ne pas déclencher une écriture immédiate sur le disque, et dans certains cas, ne pas aller du tout sur le disque (bien que ces derniers ne soient probablement pas les cas qui vous intéressent dans).

Le mieux que je puisse penser pour les fichiers mmap, si cela est viable pour vous, est de placer chacun des fichiers d'intérêt sur un appareil distinct et d'utiliser les statistiques de l'appareil pour collecter vos informations d'utilisation. Vous pouvez utiliser des partitions lvm pour cela. Un montage de liaison ne fonctionnera pas car il ne crée pas de nouveau périphérique de bloc.

Une fois que vous avez vos fichiers sur des périphériques de bloc distincts, vous pouvez obtenir des statistiques à partir de / sys / block / * ou de / proc / diskstats

Il peut être trop perturbateur d'introduire cela sur un serveur de production, mais vous pouvez peut-être l'utiliser.

SI les fichiers ne sont pas mappés, alors oui, vous pouvez choisir l'une des autres solutions ici.


Lisez attentivement s'il vous plaît, je n'ai pas besoin de statistiques au niveau du bloc :)
GioMac

D'accord, mais le type de statistiques que vous demandez n'est pas possible pour les fichiers mmappés, donc si vous êtes confronté à cela, cela vous donne un moyen possible d'obtenir des statistiques sur les fichiers en utilisant un fichier par appareil et en lisant le statistiques de l'appareil.
mc0e

-1

Récemment, je bricolais avec collectl , il semble être un excellent outil et assez simple à installer. Le plus intéressant est que vous pouvez découvrir quel est le processus responsable des goulots d'étranglement d'E / S. Je vous recommanderais de lire Utilisation de Collectl , cela pourrait être utile.


1
collectl ne surveille pas par fichier, il fonctionne par processus
Greg Smith


-2

Je pense que iotop est l'un des meilleurs outils sous Linux pour identifier les goulots d'étranglement sur IO.


3
-1 iotopne surveille pas par fichier, il fonctionne par processus
dyasny
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.