Pemantauan IO Linux per file?


29

Saya tertarik pada utilitas atau proses untuk memonitor IO disk per file di CentOS.

Pada Win2008, utilitas resmon memungkinkan jenis drilldown ini, tetapi tidak ada utilitas Linux yang saya temukan melakukan ini (iostat, iotop, dstat, nmon).

Ketertarikan saya dalam memantau kemacetan IO di server database. Dengan MSSQL, saya menemukan ini sebagai diagnostik informatif untuk mengetahui file / ruang file mana yang paling parah terkena.



1
Jika ini memungkinkan, catat sebagian besar file dipetakan ke dalam pagecache sehingga angka Anda bisa berada di semua tempat tergantung pada byte apa yang ada dalam pagecache dan apa yang ada di disk.
Matthew Ife

@ Matt Tapi dengan jawaban yang berhasil!
ewwhite

Jawaban:


18

SystemTap mungkin merupakan pilihan terbaik Anda.

Berikut adalah bagaimana output dari contoh iotime.stp terlihat seperti:

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

Kerugiannya (selain dari kurva pembelajaran) adalah Anda harus menginstal debug-kernel , yang mungkin tidak dapat dilakukan pada sistem produksi. Namun, Anda dapat menggunakan instrumentasi silang tempat Anda menyusun modul pada sistem pengembangan, dan menjalankan .ko pada sistem produksi.

Atau jika Anda tidak sabar, lihat Bab 4. Script SystemTap yang Berguna dari panduan pemula.


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

Outputnya terlihat seperti ini:

[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

Atau jika Anda memilih untuk hanya menampilkan jalur dari titik mount:

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

Keterbatasan / bug:

  • mmap berbasis I / O tidak muncul karena devnameis"N/A"
  • file pada tmpfs tidak muncul karena devnameitu"N/A"
  • tidak masalah jika bacaan berasal dari cache atau tulis ke buffer

Hasil untuk program Matthew Ife :

  • untuk pribadi mmaptest :

     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
    
  • untuk mmaptest dibagikan:

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

     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
    

* Petunjuk pengaturan cepat untuk RHEL 6 atau yang setara: yum install systemtapdandebuginfo-install kernel


Itulah beberapa systemtap yang cukup mengesankan di sana. Sebuah demonstrasi yang sangat baik dari fleksibilitasnya.
Matthew Ife

Apakah ini mengukur I / O langsung dan I / O asinkron? (menggunakan io_submit, bukan posix)
Matthew Ife

@ Mlfe: terima kasih! Sebagai catatan, saat menulis skrip saya berhasil menemukan bug kecil di pv dan satu lagi di SystemTap ( task_dentry_path) :-) Saya tidak tahu tentang I / O itu, tetapi saya bisa mengujinya jika Anda memberi saya perintah atau sebuah program sampel. Misalnya saya menggunakan Python untuk menguji mmap. dd iflag=direct oflag=directmuncul.
Cristian Ciupitu

2
Coba ini untuk mmap: gist.github.com/anonymous/7014284 Saya bertaruh pemetaan pribadi tidak diukur tetapi yang dibagikan adalah ..
Matthew Ife

2
Inilah tes IO langsung: gist.github.com/anonymous/7014604
Matthew Ife

9

Anda sebenarnya ingin menggunakannya blktraceuntuk ini. Lihat Memvisualisasikan IO Linux dengan Seekwatcher dan blktrace .

Saya akan melihat apakah saya dapat mengirim salah satu contoh saya segera.


Edit:

Anda tidak menyebutkan distribusi Linux, tetapi mungkin ini adalah kasus yang bagus untuk skrip dtrace di Linux atau bahkan System Tap , jika Anda menggunakan sistem seperti RHEL.


2
Terima kasih, hal yang baik dan sangat dekat dengan intinya, tetapi ia memberikan info blok-lapisan yang terperinci, saya memerlukan sesuatu yang berfungsi pada lapisan abstraksi VFS.
GioMac

Saya mulai mencoba beberapa skrip systemtap untuk menjalankan ini. Saya gagal karena server macet. Saya bisa mendapatkan info ini tentang Dtrace di Solaris. Saya akan coba dengan Linux hari ini.
ewwhite

4

Satu-satunya alat yang saya tahu yang dapat memonitor aktivitas I / O berdasarkan file adalah inotifywatch. Itu bagian dari inotify-toolspaket. Sayangnya, itu hanya memberi Anda jumlah operasi.


4

menggunakan iotop untuk mendapatkan PID proses yang berkontribusi IO tinggi

jalankan strace terhadap PID yang Anda buat, Anda akan melihat file mana yang sedang diakses oleh proses tertentu

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

strace akan memberikan informasi tentang syscalls dan file yang diakses, akan sangat sulit untuk mengurai dan mendapatkan statistik tentang penggunaan ...
GioMac

1
Kupikir aku akan mencoba ini. Ini menghasilkan banyak data. Dan bisa crash proses saat Anda ctrl + c. Sepertinya agak berbahaya.
Matt


2

Saya berpendapat Anda mungkin telah mengajukan pertanyaan yang salah. jika Anda mencari bottleneck i / o, mungkin sama pentingnya untuk melihat apa yang terjadi pada disk Anda. db terkenal melakukan random i / o yang secara signifikan dapat mengurangi throughput, terutama jika Anda hanya memiliki beberapa spindle.

yang mungkin lebih menarik adalah melihat apakah Anda memiliki waktu tunggu yang lama pada disk itu sendiri. Anda dapat melakukan ini dengan collectl melalui perintah "collectl -sD", yang akan menampilkan statistik kinerja disk individual. Apakah - rumah untuk mengubahnya menjadi utilitas seperti teratas. Jika ada banyak disk yang terlibat, jalankan melalui colmux: colmux -command "-sD" dan itu akan memungkinkan Anda mengurutkan berdasarkan kolom pilihan Anda, bahkan di beberapa sistem.


Saya tidak setuju dengan Anda dari perspektif disk. Di mana saya bisa mendapatkan beberapa wawasan adalah ketika ruang file database digunakan untuk mempartisi data, indeks, log, dll, tetapi dipasang pada disk bersama ketika sumber daya terbatas - server pengembangan misalnya. Idealnya, masing-masing ruang file ini akan berada pada volume yang terpisah, sehingga melihat IO dari perspektif disk akan memadai - yang mungkin mengapa semua utilitas pemantauan adalah disk, bukan berbasis file.
kermatt

Itu pertanyaan yang tepat; tujuannya adalah mencoba untuk mencari tahu "tabel mana semua I / O ini terjadi?", dan dalam kebanyakan database tabel adalah satu atau lebih file. Disk apa pun akan berakhir dengan banyak file di dalamnya, dan menentukan yang mana dari hotspot tersebut merupakan input penyetelan basis data yang berguna.
Greg Smith

2

Anda dapat memonitor i / o per blok perangkat (via / proc / diskstats) dan per proses (io akuntansi via /proc/$PID/ioatau taskstats ), tapi saya tidak tahu cara melakukannya per-file.


0

Mungkin baris tidak valid akan menyelesaikan memecahkan ini.

Inotify API menyediakan mekanisme untuk memantau acara-acara filesystem. Memberitahu dapat digunakan untuk memonitor file individu, atau untuk memantau direktori. Ketika direktori dimonitor, inotify akan mengembalikan peristiwa untuk direktori itu sendiri, dan untuk file di dalam direktori.

Monitor Aktivitas Sistem File dengan inotify

inotify Reference


Ini mungkin memberikan panggilan yang dilakukan pada file, tetapi menawarkan sedikit untuk membantu menemukan apa yang dilakukan pid, seberapa besar penulisan itu, di mana dan berapa lama waktu yang dibutuhkan.
Matthew Ife

Pertanyaannya tidak bertanya tentang prosesnya (yang mungkin dapat ditemukan dengan cara lain, seperti lsof)
Gert van den Berg

0

Meskipun ada banyak info bagus di jawaban di sini, saya ingin tahu apakah itu benar-benar berlaku?

Jika Anda berbicara tentang file dalam 10-an gigabyte, terus-menerus ditulis untuk, maka kecuali mereka adalah file log atau serupa yang terus-menerus ditambahkan ke (dalam hal ini hanya memantau ukuran file), kemungkinan besar file-file tersebut adalah mmap . Jika itu masalahnya, maka jawaban terbaik mungkin Anda harus berhenti melihat sebagian besar solusi. Hal pertama yang harus Anda tanyakan dari solusi lain yang diusulkan adalah "apakah itu bekerja dengan mmap", karena sebagian besar mereka tidak mau. Namun, Anda mungkin dapat mengubah masalah menjadi pemantauan perangkat blok daripada memantau file.

Ketika sebuah program meminta halaman dari file mmap'd, itu hanya merujuk lokasi dalam memori virtual. Halaman itu mungkin atau mungkin belum ada dalam memori. JIKA itu tidak, maka itu menghasilkan kesalahan halaman, yang memicu halaman dimuat dari disk, tetapi itu terjadi dalam sistem memori virtual, yang tidak mudah terikat pada proses aplikasi tertentu atau ke file tertentu. Demikian pula, ketika aplikasi Anda memperbarui halaman mmap'd, tergantung pada flags, yang mungkin tidak memicu penulisan langsung ke disk, dan dalam beberapa kasus mungkin tidak masuk ke disk sama sekali (meskipun mungkin yang terakhir bukan kasus yang Anda minati di).

Yang terbaik yang dapat saya pikirkan untuk file mmap'd, jika itu layak untuk Anda, adalah menempatkan setiap file yang menarik ke perangkat yang terpisah, dan menggunakan statistik perangkat untuk mengumpulkan informasi penggunaan Anda. Anda dapat menggunakan partisi lvm untuk ini. Bind mount tidak akan berfungsi karena tidak membuat perangkat blok baru.

Setelah Anda memiliki file di perangkat blok terpisah, Anda bisa mendapatkan statistik dari / sys / block / *, atau / proc / diskstats

Mungkin terlalu mengganggu untuk memperkenalkan ini ke server produksi, tetapi mungkin Anda bisa memanfaatkannya.

JIKA file tidak dalam format mm, maka ya, Anda dapat memilih salah satu solusi lain di sini.


Baca dengan baik, tolong, saya tidak perlu statistik tingkat blok :)
GioMac

Benar, tetapi jenis statistik yang Anda minta tidak mungkin untuk file yang di-mmapped, jadi jika Anda menghadapi hal itu, maka ini memberi Anda cara yang memungkinkan untuk mendapatkan statistik tentang file dengan menggunakan satu file per perangkat, dan membaca statistik perangkat.
mc0e

-1

Saya baru-baru ini mengutak-atik collectl , itu terlihat alat yang hebat, dan cukup teguh untuk menginstal. Yang paling menarik adalah Anda bisa mengetahui mana yang merupakan proses yang bertanggung jawab atas kemacetan IO. Saya sarankan Anda membaca Menggunakan Collectl , mungkin bermanfaat.


1
collectl tidak memonitor per file, ia berfungsi per proses
Greg Smith


-2

Saya pikir iotop adalah salah satu alat terbaik di Linux untuk mengidentifikasi kemacetan di IO.


3
-1 iotoptidak memonitor per file, ia bekerja per proses
dyasny
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.