Monitoreo de Linux IO por archivo?

29

Estoy interesado en una utilidad o proceso para monitorear disco IO por archivo en CentOS.

En Win2008, la utilidad resmon permite este tipo de desglose, pero ninguna de las utilidades de Linux que he encontrado hace esto (iostat, iotop, dstat, nmon).

Mi interés en monitorear cuellos de botella de E / S en servidores de bases de datos. Con MSSQL, he encontrado un diagnóstico informativo para saber qué archivos / espacios de archivos están siendo los más afectados.

Kermatt
fuente
2
Quizás Análisis y herramientas de rendimiento de Linux: la charla de Brendan Gregg en SCaLE 11x puede ayudarlo; ver diapositiva 72/115.
Cristian Ciupitu
1
Si esto es posible, tenga en cuenta que la mayoría de los archivos se asignan a la memoria caché de página, por lo que sus números podrían estar por todas partes dependiendo de qué bytes estén en la memoria caché de página y qué hay en el disco.
Matthew Ife
@ Matt Pero con una respuesta que funciona!
ewwhite

Respuestas:

18

SystemTap es probablemente su mejor opción.

Así es como se ve la salida del ejemplo 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

La desventaja (aparte de la curva de aprendizaje) es que necesitará instalar kernel-debug , que puede no ser posible en un sistema de producción. Sin embargo, puede recurrir a la instrumentación cruzada donde compila un módulo en un sistema de desarrollo y ejecuta ese .ko en el sistema de producción.

O, si es impaciente, consulte el Capítulo 4. Scripts útiles de SystemTap de la guía para principiantes.

Rilindo
fuente
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 salida se ve así:

[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

O si elige mostrar solo la ruta desde el punto de montaje:

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

Limitaciones / errores:

  • La E / S basada en mmap no aparece porque devnamees"N/A"
  • los archivos en tmpfs no aparecen porque devnamees"N/A"
  • no importa si las lecturas son del caché o las escrituras son en el búfer

Los resultados de los programas de Matthew Ife :

  • para mmaptest privado:

     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
    
  • para mmaptest compartido:

     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
    
  • para diotest (E / S directa):

     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
    

* Instrucciones de configuración rápida para RHEL 6 o equivalente: yum install systemtapydebuginfo-install kernel

Cristian Ciupitu
fuente
Eso es un toque de sistema bastante impresionante allí mismo. Una excelente demostración de su versatilidad.
Matthew Ife
¿Mide esto E / S directa y E / S asíncrona? (usando io_submit, no posix)
Matthew Ife
@Mlfe: gracias! Como nota al margen, mientras escribía el script logré descubrir un pequeño error en pv y otro en SystemTap ( task_dentry_path) :-) No tengo idea de esa E / S, pero puedo probarlo si me das un comando o Un programa de muestra. Por ejemplo, usé Python para probar mmap. dd iflag=direct oflag=directaparece.
Cristian Ciupitu
2
Pruebe esto para mmap: gist.github.com/anonymous/7014284 los que estoy de apuestas asignaciones privadas no se miden, pero son compartidos ..
Mateo Ife
2
Heres una prueba directa de IO: gist.github.com/anonymous/7014604
Matthew Ife
9

Realmente querrás usar blktracepara esto. Consulte Visualizar Linux IO con Seekwatcher y blktrace .

Veré si puedo publicar uno de mis ejemplos pronto.


Editar:

No menciona la distribución de Linux, pero quizás este sea un buen caso para un script dtrace en Linux o incluso System Tap , si está utilizando un sistema similar a RHEL.

ewwhite
fuente
2
Gracias, algo bueno y muy cercano al punto, pero proporciona información detallada de la capa de bloque, necesito algo que funcione en la capa de abstracción VFS.
GioMac
Comencé a intentar algunos scripts de systemtap para ejecutar esto. Fallé porque el servidor se bloqueó. Puedo obtener esta información en Dtrace en Solaris. Intentaré con Linux hoy.
ewwhite
4

La única herramienta que conozco que puede monitorear la actividad de E / S por archivo es inotifywatch. Es parte del inotify-toolspaquete. Desafortunadamente, solo te da recuentos de operaciones.

David Schwartz
fuente
4

use iotop para obtener los PID de los procesos que contribuyen con un alto IO

ejecute strace contra el PID que generó, verá a qué archivos está accediendo un proceso en particular

strace -f -p $PID -e trace=open,read,write
rayo
fuente
strace proporcionará información sobre llamadas al sistema y archivos a los que se accede, será muy difícil de analizar y obtener estadísticas sobre el uso ...
GioMac
1
Pensé en probar esto. Genera MUCHOS datos. Y puede bloquear el proceso cuando ctrl + c. Parece ser bastante peligroso.
Matt
4

Finalmente usé Sysdig para esto

omribahumi
fuente
Cómo hacerlo: Instale sysdig , ejecute csysdig, presione F2 y seleccione Filesver. Verá la parte superior de los archivos accedidos por columna OPS (se puede cambiar presionando F9).
catpnosis
csysdig -v filesva directamente a la vista "Archivos"
Gert van den Berg
2

Yo diría que podrías haber hecho la pregunta equivocada. Si está buscando cuellos de botella de E / S, puede ser tan importante ver lo que sucede en su disco. Los db son conocidos por hacer E / S aleatorias que pueden reducir significativamente el rendimiento, especialmente si solo tiene unos pocos cabezales.

lo que puede ser más interesante es ver si tiene largos tiempos de espera en los discos mismos. puede hacer esto con collectl mediante el comando "collectl -sD", que mostrará estadísticas de rendimiento de disco individuales. Are --home para convertirlo en una utilidad superior. Si hay muchos discos involucrados, ejecútelo a través de colmux: colmux -command "-sD" y le permitirá ordenar por una columna de su elección, incluso a través de múltiples sistemas.

Mark Seger
fuente
No estoy en desacuerdo con usted desde la perspectiva del disco. Donde puedo obtener información es cuando los espacios de archivos de una base de datos se usan para particionar datos, índices, registros, etc., pero se montan en discos compartidos cuando los recursos son limitados, por ejemplo, servidores de desarrollo. Idealmente, cada uno de estos espacios de archivos estaría en volúmenes separados, por lo tanto, mirar el IO desde la perspectiva del disco sería adecuado, por lo que es probable que todas las utilidades de monitoreo estén basadas en disco, no en archivos.
kermatt
Es la pregunta correcta. el objetivo es tratar de averiguar "¿en qué tabla está pasando toda esta E / S?", y en la mayoría de las bases de datos, una tabla es uno o más archivos. Cualquier disco terminará con muchos archivos, y determinar cuáles son los puntos de acceso es una entrada útil para el ajuste de la base de datos.
Greg Smith
2

Puede monitorear la E / S por dispositivo de bloque (a través de / proc / diskstats) y por proceso (io contabilidad a través de /proc/$PID/ioo estadísticas de tareas ), pero no conozco una manera de hacerlo por archivo.

Sciurus
fuente
0

Puede ser inotify resolverá resolver esto.

La API de inotify proporciona un mecanismo para monitorear eventos del sistema de archivos. Notify se puede usar para monitorear archivos individuales o para monitorear directorios. Cuando se supervisa un directorio, inotify devolverá eventos para el directorio en sí y para los archivos dentro del directorio.

Monitorear la actividad del sistema de archivos con inotify

Referencia de inotify

Zain
fuente
Esto puede proporcionar las llamadas realizadas en el archivo, pero ofrece poco para ayudar a descubrir qué hizo, qué tan grande fue la escritura, dónde y cuánto tiempo tardó.
Matthew Ife
La pregunta no se refiere al proceso (que posiblemente se puede descubrir por otros medios, como lsof)
Gert van den Berg
0

Si bien hay mucha buena información en las respuestas aquí, me pregunto si es realmente aplicable.

Si está hablando de archivos en los 10s de gigabytes, en los que se escribe constantemente, a menos que sean archivos de registro o similares a los que se agregue constantemente (en cuyo caso solo supervise el tamaño de los archivos), es muy probable que los archivos sean mmap'd . Si ese es el caso, entonces la mejor respuesta puede ser que debe dejar de buscar la mayoría de las soluciones. Lo primero que debe preguntar sobre cualquier otra solución propuesta es "funciona con mmap", porque en su mayoría no funcionará. Sin embargo, es posible que pueda convertir el problema en un dispositivo de bloqueo en lugar de un archivo.

Cuando un programa solicita una página de un archivo mmap'd, solo hace referencia a una ubicación en la memoria virtual. Esa página podría o no estar ya en la memoria. Si no es así, eso genera un error de página, que desencadena la carga de la página desde el disco, pero eso ocurre dentro del sistema de memoria virtual, que no está fácilmente vinculado a un proceso de aplicación específico o a un archivo específico. De manera similar, cuando su aplicación actualiza una página mmap'd, dependiendo de los indicadores, es posible que no desencadene una escritura inmediata en el disco y, en algunos casos, no vaya al disco en absoluto (aunque presumiblemente esos últimos no son los casos que le interesan en).

Lo mejor que puedo pensar para los archivos mmap'd, si es viable para usted, es colocar cada uno de los archivos de interés en un dispositivo separado y usar las estadísticas del dispositivo para recopilar su información de uso. Podrías usar particiones lvm para esto. Sin embargo, un montaje de enlace no funcionará, ya que no crea un nuevo dispositivo de bloque.

Una vez que tenga sus archivos en dispositivos de bloque separados, puede obtener estadísticas de / sys / block / * o / proc / diskstats

Puede ser demasiado perjudicial presentar esto a un servidor de producción, pero tal vez pueda usarlo.

SI los archivos no están mapeados, entonces sí, puede elegir una de las otras soluciones aquí.

mc0e
fuente
Lea atentamente por favor, no necesito estadísticas a nivel de bloque :)
GioMac
Correcto, pero el tipo de estadísticas que está solicitando no es posible para los archivos mmapped, por lo que si se encuentra con eso, esto le brinda una forma posible de obtener estadísticas sobre los archivos utilizando un archivo por dispositivo y leyendo el estadísticas del dispositivo.
mc0e
-1

Recientemente estuve jugando con collectl , parece una gran herramienta y bastante sencilla de instalar. Lo más interesante es que puede averiguar cuál es el proceso responsable de los cuellos de botella de E / S. Te recomendaría que leas Usando Collectl , podría ser útil.

Sergio Galván
fuente
1
collectl no supervisa por archivo, funciona por proceso
Greg Smith
-2

Creo que iotop es una de las mejores herramientas en Linux para identificar cuellos de botella en IO.

aleroot
fuente
3
-1 iotopno supervisa por archivo, funciona por proceso
dyasny