Monitoramento de E / S do Linux por arquivo?


29

Estou interessado em um utilitário ou processo para monitorar E / S de disco por arquivo no CentOS.

No Win2008, o utilitário resmon permite esse tipo de detalhamento, mas nenhum dos utilitários Linux que eu encontrei faz isso (iostat, iotop, dstat, nmon).

Meu interesse em monitorar gargalos de E / S em servidores de banco de dados. Com o MSSQL, achei um diagnóstico informativo saber quais arquivos / espaços de arquivos são os mais atingidos.



1
Se isso for possível, observe que a maioria dos arquivos é mapeada no pagecache, para que seus números estejam em todo o lugar, dependendo de quais bytes estão no pagecache e do disco.
Matthew Ife

@ Matt Mas com uma resposta de trabalho!
ewwhite

Respostas:


18

SystemTap é provavelmente a sua melhor opção.

Aqui está como a saída do exemplo iotime.stp se parece:

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

A desvantagem (além da curva de aprendizado) é que você precisará instalar o kernel-debug , o que pode não ser possível em um sistema de produção. No entanto, você pode recorrer à instrumentação cruzada em que compila um módulo em um sistema de desenvolvimento e executa esse .ko no sistema de produção.

Ou, se estiver impaciente, consulte o Capítulo 4. Scripts úteis do SystemTap do guia para iniciantes.


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

A saída é assim:

[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 se você optar por exibir apenas o caminho do ponto de montagem:

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

Limitações / bugs:

  • E / S baseada em mmap não aparece porque devnameé"N/A"
  • arquivos no tmpfs não aparecem porque devnameé"N/A"
  • não importa se as leituras são do cache ou as gravações são no buffer

Os resultados para os programas de Matthew Ife :

  • para mmaptest private:

     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 compartilhado:

     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 dioteste (E / S direta):

     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
    

* Instruções de configuração rápida para RHEL 6 ou equivalente: yum install systemtapedebuginfo-install kernel


Isso é um sistematap impressionante aqui. Uma excelente demonstração de sua versatilidade.
Matthew Ife

Essa medida direciona E / S e E / S assíncrona? (usando io_submit, não posix)
Matthew Ife

@ Malfe: obrigado! Como observação lateral, enquanto escrevia o script, consegui descobrir um pequeno bug no pv e outro no SystemTap ( task_dentry_path) :-) Não faço ideia sobre a E / S, mas posso testá-lo se você me der um comando ou um programa de amostra. Por exemplo, usei o Python para testar o mmap. dd iflag=direct oflag=directAparece.
Cristian Ciupitu 16/10

2
Tente isto para mmap: gist.github.com/anonymous/7014284 que eu estou apostando mapeamentos privados não são medidos mas compartilhados são ..
Matthew Ife

2
Heres um teste de IO direto: gist.github.com/anonymous/7014604
Matthew Ife

9

Você realmente gostaria de usar blktracepara isso. Consulte Visualizando o Linux IO com Seekwatcher e blktrace .

Vou ver se posso postar um dos meus exemplos em breve.


Editar:

Você não menciona a distribuição do Linux, mas talvez esse seja um bom argumento para um script dtrace no Linux ou mesmo no System Tap , se você estiver usando um sistema semelhante ao RHEL.


2
Obrigado, coisa boa e muito próximo ao ponto, mas fornece informações detalhadas da camada de bloco, preciso de algo que funcione na camada de abstração do VFS.
GioMac

Comecei a tentar alguns scripts systemtap para fazer isso funcionar. Eu falhei porque o servidor travou. Eu posso obter essas informações sobre o Dtrace no Solaris. Vou tentar com o Linux hoje.
ewwhite

4

A única ferramenta que conheço que pode monitorar a atividade de E / S por arquivo é inotifywatch. Faz parte do inotify-toolspacote. Infelizmente, ele apenas fornece contagens de operação.


4

use iotop para obter os PIDs de processos que contribuem com alta IO

executar strace no PID gerado, você verá quais arquivos estão sendo acessados ​​por um processo específico

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

strace irá fornecer informações sobre syscalls e arquivos acessados, será muito difícil de analisar e obter estatísticas sobre o uso ...
GioMac

1
Pensei em tentar isso. Ele gera muitos dados. E pode travar o processo quando você pressionar Ctrl + c. Parece ser bastante perigoso.
Matt


2

Eu diria que você pode ter feito a pergunta errada. se você estiver procurando por gargalos de E / S, pode ser igualmente importante ver o que está acontecendo no seu disco. Os db's são notórios por fazerem E / S aleatórias, o que pode reduzir significativamente a taxa de transferência, especialmente se você tiver apenas alguns eixos.

o que pode ser mais interessante é ver se você está tendo longos tempos de espera nos próprios discos. você pode fazer isso com collectl através do comando "collectl -sD", que mostrará estatísticas de desempenho de disco individuais. São --home para transformá-lo em um utilitário top-like. Se houver muitos discos envolvidos, execute-o via colmux: colmux -comand "-sD" e ele permitirá que você classifique por uma coluna de sua escolha, mesmo em vários sistemas.


Não discordo de você da perspectiva do disco. Onde posso obter algumas dicas é quando os espaços de arquivo do banco de dados são usados ​​para particionar dados, índices, logs etc., mas montados em discos compartilhados quando os recursos são limitados - servidores de desenvolvimento, por exemplo. Idealmente, cada um desses espaços de arquivos estaria em volumes separados, portanto, analisar o IO da perspectiva do disco seria adequado - o que é provavelmente o motivo pelo qual todos os utilitários de monitoramento são disco, não baseados em arquivo.
Kermatt #

É a pergunta certa; o objetivo é tentar descobrir "em qual tabela está acontecendo toda essa E / S?" e, na maioria dos bancos de dados, uma tabela possui um ou mais arquivos. Qualquer disco vai acabar com muitos arquivos, e determinar qual desses são os pontos ativos é uma entrada útil de ajuste de banco de dados.
9788 Greg Smith1 de

2

Você pode monitorar a E / S por dispositivo de bloco (via / proc / diskstats) e por processo (io contabilizando via /proc/$PID/ioou taskstats ), mas não conheço uma maneira de fazê-lo por arquivo.


0

Pode ser inotify resolverá resolver isso.

A API inotify fornece um mecanismo para monitorar eventos do sistema de arquivos. O Inotify pode ser usado para monitorar arquivos individuais ou para monitorar diretórios. Quando um diretório é monitorado, o inotify retornará eventos para o próprio diretório e para arquivos dentro do diretório.

Monitorar a atividade do sistema de arquivos com o inotify

Referência inotify


Isso pode fornecer as chamadas feitas no arquivo, mas oferece pouco para ajudar a descobrir o que foi feito, o tamanho da gravação, onde e quanto tempo levou.
Matthew Ife

A pergunta não pergunta sobre o processo (que pode ser descoberto por outros meios, como lsof)
Gert van den Berg

0

Embora haja muitas informações boas nas respostas aqui, estou me perguntando se é realmente aplicável.

Se você está falando sobre arquivos nos 10s de gigabytes, sendo constantemente gravados, a menos que sejam arquivos de log ou similares que são constantemente anexados (nesse caso, apenas monitore o tamanho dos arquivos), é mais provável que os arquivos sejam mmap'd . Se for esse o caso, a melhor resposta pode ser que você deve parar de procurar a maioria das soluções. A primeira coisa que você deve perguntar a qualquer outra solução proposta é "funciona com mmap", porque na maioria das vezes eles não funcionam? Entretanto, você pode transformar o problema em monitorar um dispositivo de bloco em vez de monitorar um arquivo.

Quando um programa solicita uma página de um arquivo mmap'd, está apenas referenciando um local na memória virtual. Essa página pode ou não já estar na memória. Se não for, isso gera uma falha de página, que aciona a página que está sendo carregada do disco, mas isso acontece no sistema de memória virtual, que não é facilmente vinculado a um processo de aplicativo específico ou a um arquivo específico. Da mesma forma, quando seu aplicativo atualiza uma página mmap'd, dependendo dos sinalizadores, isso pode não acionar uma gravação imediata no disco e, em alguns casos, pode não ir ao disco (embora, presumivelmente, esses últimos não sejam os casos de seu interesse) em).

O melhor que posso pensar em arquivos mmap'd, se for viável para você, é colocar cada um dos arquivos de interesse em um dispositivo separado e usar as estatísticas do dispositivo para coletar suas informações de uso. Você pode usar partições lvm para isso. Uma montagem de ligação não funcionará, pois não cria um novo dispositivo de bloco.

Depois de ter seus arquivos em dispositivos de bloco separados, você pode obter estatísticas de / sys / block / * ou / proc / diskstats

Pode ser muito perturbador introduzir isso em um servidor de produção, mas talvez você possa usá-lo.

Se os arquivos não estiverem mapeados, sim, você pode escolher uma das outras soluções aqui.


Leia com atenção por favor, eu não preciso de estatísticas em nível de bloco :)
GioMac

Certo, mas o tipo de estatísticas que você está solicitando não é possível para arquivos mmapped, por isso, se você está enfrentando isso, isso oferece uma maneira possível de obter estatísticas sobre arquivos usando um arquivo por dispositivo e lendo o estatísticas do dispositivo.
Mc0e 23/10

-1

Recentemente, eu estava mexendo com collectl , parece uma ótima ferramenta e bastante simples de instalar. O mais interessante é que você pode descobrir qual é o processo responsável pelos gargalos de IO. Eu recomendo que você leia Usando o Collectl , pode ser útil.


1
não collectl não monitora por arquivo, ele funciona por processo
Greg Smith


-2

Eu acho que o iotop é uma das melhores ferramentas no Linux para identificar gargalos no IO.


3
-1 iotopnão monitora por arquivo, ele funciona por processo
dyasny
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.