Monitoraggio IO Linux per file?


29

Sono interessato a un'utilità o un processo per il monitoraggio dell'IO del disco per file su CentOS.

Su Win2008, l' utilità resmon consente questo tipo di drilldown, ma nessuna delle utility Linux che ho trovato lo fa (iostat, iotop, dstat, nmon).

Il mio interesse per il monitoraggio dei colli di bottiglia nei server di database. Con MSSQL, ho trovato una diagnostica informativa sapere quali file / spazi file sono i più colpiti.



1
Se questo è possibile, nota che la maggior parte dei file sono mappati in pagecache in modo che i tuoi numeri possano trovarsi ovunque a seconda di quali byte sono in pagecache e quali sono sul disco.
Matthew Ife,

@Matt Ma con una risposta funzionante!
ewwhite,

Risposte:


18

SystemTap è probabilmente l'opzione migliore.

Ecco come appare l'output dell'esempio 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

Lo svantaggio (a parte la curva di apprendimento) è che dovrai installare kernel-debug , che potrebbe non essere possibile su un sistema di produzione. Tuttavia, puoi ricorrere alla strumentazione incrociata in cui compili un modulo su un sistema di sviluppo ed esegui quel .ko sul sistema di produzione.

O se sei impaziente, guarda il Capitolo 4. Utili Script SystemTap dalla guida per principianti.


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)
}

L'output è simile al seguente:

[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

Oppure se scegli di visualizzare solo il percorso dal mountpoint:

[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)

Limitazioni / bug:

  • mmap a base di I / O non si presenta a causa devnameIS"N/A"
  • file su tmpfs non si presentano perché devnameè"N/A"
  • non importa se le letture provengono dalla cache o le scritture sono nel buffer

I risultati per i programmi di Matthew Ife :

  • per mmaptest privato:

     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
    
  • per mmaptest condiviso:

     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
    
  • per diotest (I / O diretto):

     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
    

* Istruzioni di installazione rapida per RHEL 6 o equivalente: yum install systemtapedebuginfo-install kernel


Ecco qualche systemtap piuttosto impressionante proprio lì. Un'eccellente dimostrazione della sua versatilità.
Matthew Ife,

Questa misura dirige l'I / O e gli I / O asincroni? (usando io_submit, non posix)
Matthew Ife,

@Mlfe: grazie! Come nota a margine , mentre scrivevo lo script sono riuscito a scoprire un piccolo bug in pv e un altro in SystemTap ( task_dentry_path) :-) Non ho idea di quell'I / O, ma posso provarlo se mi dai un comando o un programma di esempio. Ad esempio ho usato Python per testare mmap. dd iflag=direct oflag=directsi presenta.
Cristian Ciupitu,

2
Prova questo per mmap: gist.github.com/anonymous/7014284 Scommetto che le mappature private non sono misurate ma quelle condivise sono ..
Matthew Ife,

2
Ecco un test IO diretto: gist.github.com/anonymous/7014604
Matthew Ife

9

In realtà vorresti usarlo blktraceper questo. Vedi Visualizzazione di Linux IO con Seekwatcher e blktrace .

Vedrò se posso pubblicare presto uno dei miei esempi.


Modificare:

Non menzioni la distribuzione di Linux, ma forse questo è un buon caso per uno script dtrace su Linux o persino su System Tap , se stai usando un sistema simile a RHEL.


2
Grazie, buona cosa e molto vicino al punto, ma fornisce informazioni dettagliate a livello di blocco, ho bisogno di qualcosa che funzioni sul livello di astrazione VFS.
GioMac,

Ho iniziato a provare alcuni script systemtap per farlo funzionare. Ho fallito perché il server si è bloccato. Posso ottenere queste informazioni su Dtrace su Solaris. Proverò con Linux oggi.
ewwhite,

4

L'unico strumento che conosco in grado di monitorare l'attività di I / O per file è inotifywatch. Fa parte del inotify-toolspacchetto. Sfortunatamente, ti dà solo conteggi delle operazioni.


4

utilizzare iotop per ottenere i PID dei processi che contribuiscono con un elevato IO

esegui strace contro il PID che hai generato, vedrai quali file accedono a un determinato processo

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

strace fornirà informazioni su syscalls e sui file accessibili, sarà molto difficile analizzare e ottenere statistiche sull'uso ...
GioMac,

1
Ho pensato di provare questo. Genera MOLTI dati. E puoi interrompere il processo quando premi Ctrl + C. Sembra essere piuttosto pericoloso.
Matt,


2

Direi che potresti aver fatto la domanda sbagliata. se stai cercando colli di bottiglia, potrebbe essere altrettanto importante vedere cosa sta succedendo sul tuo disco. I db sono noti per eseguire operazioni di I / O casuali che possono ridurre in modo significativo il throughput, specialmente se si hanno solo pochi mandrini.

ciò che potrebbe essere più interessante è vedere se si hanno lunghi tempi di attesa sui dischi stessi. puoi farlo con collectl tramite il comando "collectl -sD", che mostrerà le statistiche delle prestazioni del singolo disco. Sono --home per trasformarlo in un'utilità di livello superiore. Se sono coinvolti molti dischi, eseguilo tramite colmux: colmux -command "-sD" e ti permetterà di ordinare in base a una colonna di tua scelta, anche su più sistemi.


Non sono in disaccordo con te dal punto di vista del disco. Dove posso ottenere alcune informazioni è quando gli spazi file di un database vengono utilizzati per partizionare dati, indici, registri, ecc., Ma montati su dischi condivisi quando le risorse sono limitate, ad esempio i server di sviluppo. Idealmente, ciascuno di questi spazi file dovrebbe trovarsi su volumi separati, quindi osservare l'IO dalla prospettiva del disco sarebbe adeguato, motivo per cui tutte le utilità di monitoraggio sono basate su disco, non basate su file.
kermatt,

È la domanda giusta; l'obiettivo sta cercando di capire "a quale tabella sta succedendo tutto questo I / O?" e nella maggior parte dei database una tabella contiene uno o più file. Qualsiasi disco finirà con molti file su di esso e determinare quali di questi sono gli hotspot è un utile input per l'ottimizzazione del database.
Greg Smith,

2

Puoi monitorare l'I / O per dispositivo a blocchi (tramite / proc / diskstats) e per processo (io account via /proc/$PID/ioo taskstats ), ma non conosco un modo per farlo per file.


0

Può essere inotify risolverà risolvere questo.

L'API inotify fornisce un meccanismo per il monitoraggio degli eventi del file system. Inotify può essere utilizzato per monitorare singoli file o per monitorare le directory. Quando viene monitorata una directory, inotify restituirà eventi per la directory stessa e per i file all'interno della directory.

Monitora l'attività del file system con inotify

riferimento inotify


Questo può fornire le chiamate fatte sul file, ma offre poco per aiutare a scoprire quale pid ha fatto, quanto è stata grande la scrittura, dove e quanto tempo ha impiegato.
Matthew Ife,

La domanda non si pone sul processo (che può essere eventualmente scoperto con altri mezzi, come lsof)
Gert van den Berg,

0

Mentre ci sono molte buone informazioni nelle risposte qui, mi chiedo se sia effettivamente applicabile?

Se stai parlando di file in decimi di gigabyte, in costante scrittura, a meno che non siano file di registro o simili a cui vengono costantemente aggiunti (nel qual caso basta monitorare le dimensioni dei file), è molto probabile che i file siano mmap'd . In tal caso, la risposta migliore potrebbe essere che dovresti smettere di cercare la maggior parte delle soluzioni. La prima cosa che dovresti chiedere a qualsiasi altra soluzione proposta è "funziona con mmap", perché per lo più non lo faranno. Tuttavia, potresti essere in grado di trasformare il problema nel monitoraggio di un dispositivo a blocchi piuttosto che nel monitoraggio di un file.

Quando un programma richiede una pagina da un file mmap'd, fa semplicemente riferimento a una posizione nella memoria virtuale. Quella pagina potrebbe essere o non essere già in memoria. Se non lo è, ciò genera un errore di pagina, che attiva la pagina caricata dal disco, ma ciò accade all'interno del sistema di memoria virtuale, che non è facilmente legato a un processo dell'applicazione specifico o a un file specifico. Allo stesso modo, quando l'app aggiorna una pagina mmap'd, a seconda dei flag, ciò potrebbe non innescare una scrittura immediata su disco e in alcuni casi potrebbe non andare affatto sul disco (anche se presumibilmente questi ultimi non sono i casi che ti interessano nel).

Il meglio che mi viene in mente per i file mmap'd, se è fattibile per te, è mettere ciascuno dei file di interesse su un dispositivo separato e utilizzare le statistiche del dispositivo per raccogliere le informazioni di utilizzo. Per questo puoi usare le partizioni LVM. Un attacco bind non funzionerà, poiché non crea un nuovo dispositivo a blocchi.

Una volta che hai i tuoi file su dispositivi a blocchi separati puoi ottenere statistiche da / sys / block / * o / proc / diskstats

Potrebbe essere troppo distruttivo introdurlo a un server di produzione, ma forse puoi farne uso.

SE i file non sono combinati, quindi sì, puoi scegliere una delle altre soluzioni qui.


Leggi attentamente per favore, non ho bisogno di statistiche a livello di blocco :)
GioMac,

Giusto, ma il tipo di statistiche che stai chiedendo non è possibile per i file mmapped, quindi se stai andando contro quello, allora questo ti dà un modo possibile per ottenere statistiche sui file usando un file per dispositivo e leggendo il statistiche del dispositivo.
mc0e

-1

Recentemente stavo armeggiando con collectl , sembra un ottimo strumento e abbastanza semplice da installare. Il più interessante è che puoi scoprire qual è il processo responsabile per i colli di bottiglia di IO. Ti consiglio di leggere Usando Collectl , potrebbe essere utile.


1
collectl non controlla per file, funziona per processo
Greg Smith


-2

Penso che iotop sia uno dei migliori strumenti su Linux per identificare i colli di bottiglia su IO.


3
-1 iotopnon monitora per file, funziona per processo
dyasny
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.