ตรวจสอบ Linux IO ต่อไฟล์?


29

ฉันสนใจในยูทิลิตี้หรือกระบวนการสำหรับการตรวจสอบดิสก์ IO ต่อไฟล์บน CentOS

บน Win2008 โปรแกรมresmonอนุญาตการเจาะลึกประเภทนี้ แต่ไม่มีโปรแกรมอรรถประโยชน์ Linux ใด ๆ ที่ฉันพบทำ (iostat, iotop, dstat, nmon)

ความสนใจของฉันในการตรวจสอบ IO คอขวดบนเซิร์ฟเวอร์ฐานข้อมูล ด้วย MSSQL ฉันพบว่าการวินิจฉัยที่ให้ข้อมูลรู้ว่าไฟล์ / ไฟล์ใดบ้างที่ได้รับผลกระทบมากที่สุด



1
หากเป็นไปได้ให้สังเกตว่าไฟล์ส่วนใหญ่จะถูกแมปไว้ใน pagecache เพื่อให้หมายเลขของคุณมีอยู่ทั่วสถานที่ทั้งนี้ขึ้นอยู่กับว่าไบต์ใดที่อยู่ใน pagecache และสิ่งที่อยู่บนดิสก์
Matthew Ife

@ แมตต์ แต่ด้วยคำตอบที่ทำงาน!
ewwhite

คำตอบ:


18

SystemTapอาจเป็นตัวเลือกที่ดีที่สุดของคุณ

นี่คือลักษณะของเอาต์พุตจากตัวอย่าง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

ข้อเสีย (นอกเหนือจากกราฟการเรียนรู้) คือคุณจะต้องติดตั้งเคอร์เนลดีบักซึ่งอาจไม่สามารถทำได้ในระบบการผลิต อย่างไรก็ตามคุณสามารถใช้เครื่องมือวัดผลที่คุณรวบรวมโมดูลในระบบการพัฒนาและรัน. koบนระบบการผลิต

หรือถ้าคุณใจร้อนให้ดูบทที่ 4 สคริปต์ SystemTap ที่มีประโยชน์จากคู่มือเริ่มต้น


17

สคริปต์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)
}

ผลลัพธ์มีลักษณะดังนี้:

[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

หรือถ้าคุณเลือกที่จะแสดงเฉพาะเส้นทางจากจุดเมานท์:

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

ข้อ จำกัด / ข้อบกพร่อง:

  • I / O ที่ใช้mmapไม่แสดงขึ้นเนื่องจากdevnameเป็น"N/A"
  • ไฟล์ในtmpfsไม่แสดงขึ้นเพราะdevnameเป็น"N/A"
  • ไม่สำคัญว่าการอ่านนั้นมาจากแคชหรือการเขียนไปยังบัฟเฟอร์

ผลลัพธ์สำหรับโปรแกรมของMatthew Ife :

  • สำหรับ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
    
  • สำหรับmmaptest ที่แชร์:

     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
    
  • สำหรับdiotest (direct I / O):

     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
    

*คำแนะนำการตั้งค่าอย่างรวดเร็วสำหรับ RHEL 6 หรือเทียบเท่า: yum install systemtapและdebuginfo-install kernel


มีระบบที่น่าประทับใจอยู่ตรงนั้น การสาธิตที่ยอดเยี่ยมของความเก่งกาจของมัน
Matthew Ife

การวัดนี้กำหนด I / O โดยตรงและ I / O แบบซิงค์หรือไม่? (ใช้ io_submit ไม่ใช่ posix)
Matthew Ife

@Mlfe: ขอบคุณ! เป็นหมายเหตุด้านในขณะที่เขียนสคริปต์ฉันจัดการเพื่อค้นหาข้อบกพร่องเล็ก ๆ ในpvและอีกหนึ่งใน SystemTap ( task_dentry_path) :-) ฉันไม่มีความคิดเกี่ยวกับ I / O ที่ แต่ฉันสามารถทดสอบได้ถ้าคุณให้คำสั่งหรือ โปรแกรมตัวอย่าง ตัวอย่างเช่นฉันใช้Pythonเพื่อทดสอบ mmap dd iflag=direct oflag=directปรากฏตัวขึ้น
Cristian Ciupitu

2
ลองใช้ดูสิสำหรับ mmap: gist.github.com/anonymous/7014284ฉันเดิมพันว่าการแมปส่วนตัวไม่ได้วัด แต่มีการแชร์กัน ..
แมทธิว Ife

2
นี่คือการทดสอบโดยตรงของ IO: gist.github.com/anonymous/7014604
Matthew Ife

9

คุณต้องการใช้blktraceสำหรับสิ่งนี้จริงๆ ดูแสดงผล Linux IO กับ Seekwatcher และ blktrace

ฉันจะดูว่าฉันสามารถโพสต์หนึ่งในตัวอย่างของฉันในไม่ช้า


แก้ไข:

คุณไม่ได้กล่าวถึงการแจกจ่าย Linux แต่อาจเป็นกรณีที่ดีสำหรับสคริปต์ dtraceบน Linux หรือแม้แต่System Tapหากคุณใช้ระบบเหมือน RHEL


2
ขอบคุณสิ่งที่ดีและใกล้กับจุดมาก แต่ให้รายละเอียดข้อมูลเลเยอร์บล็อกฉันต้องการสิ่งที่ทำงานบน VFS นามธรรมเลเยอร์
GioMac

ฉันเริ่มพยายามสคริปต์ systemtap เพื่อให้ทำงานนี้ ฉันล้มเหลวเพราะเซิร์ฟเวอร์ขัดข้อง ฉันสามารถรับข้อมูลนี้ได้ที่ Dtrace บน Solaris ฉันจะลองกับ Linux วันนี้
ewwhite

4

เครื่องมือเดียวที่ฉันรู้ที่สามารถตรวจสอบ I / O inotifywatchกิจกรรมโดยไฟล์ มันเป็นส่วนหนึ่งของinotify-toolsแพ็คเกจ น่าเสียดายที่มันให้คุณนับการดำเนินการเท่านั้น


4

ใช้ไอโซโทปเพื่อรับ PID ของกระบวนการที่ให้ค่า IO สูง

เรียกใช้ strace เทียบกับ PID ที่คุณสร้างขึ้นคุณจะเห็นว่าไฟล์ใดที่ถูกเข้าถึงโดยกระบวนการเฉพาะ

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

strace จะให้ข้อมูลเกี่ยวกับ syscalls และไฟล์ที่เข้าถึงมันจะยากมากในการแยกวิเคราะห์และรับสถิติการใช้ ...
GioMac

1
คิดว่าฉันจะลองสิ่งนี้ มันสร้างข้อมูลจำนวนมาก และสามารถผิดพลาดกระบวนการเมื่อคุณ ctrl + c ดูเหมือนว่าจะค่อนข้างอันตราย
แมตต์

4

ในที่สุดฉันก็ใช้Sysdigสำหรับสิ่งนี้


วิธีการ: ติดตั้ง sysdig , รันcsysdig, กด F2 และเลือกFilesมุมมอง คุณจะเห็นด้านบนของไฟล์ที่เข้าถึงได้โดยคอลัมน์ OPS (สามารถเปลี่ยนได้กด F9)
catpnosis

csysdig -v filesไปที่มุมมอง "ไฟล์" โดยตรง
Gert van den Berg

2

ฉันขอโต้แย้งว่าคุณอาจถามคำถามผิด หากคุณกำลังมองหาคอขวดของฉัน / มันอาจเป็นสิ่งสำคัญเช่นกันที่จะเห็นสิ่งที่เกิดขึ้นบนดิสก์ของคุณ db นั้นมีชื่อเสียงในการทำ i / o แบบสุ่มซึ่งสามารถลดปริมาณงานได้อย่างมากโดยเฉพาะถ้าคุณมีสปินเดิลไม่กี่ตัว

สิ่งที่น่าสนใจกว่าคือดูว่าคุณมีเวลารอนานในดิสก์ด้วยตนเองหรือไม่ คุณสามารถทำได้ด้วยการรวบรวมผ่านคำสั่ง "collectl -sD" ซึ่งจะแสดงสถิติประสิทธิภาพของดิสก์แต่ละรายการ Are - home เพื่อเปลี่ยนเป็นยูทิลิตี้ที่เหมือนด้านบน หากมีดิสก์จำนวนมากที่เกี่ยวข้องให้รันผ่าน colmux: colmux -command "-sD" และจะช่วยให้คุณเรียงลำดับตามคอลัมน์ที่คุณเลือกแม้ในหลายระบบ


ฉันไม่เห็นด้วยกับคุณจากมุมมองดิสก์ ที่ฉันสามารถรับข้อมูลเชิงลึกบางอย่างคือเมื่อมีการใช้ตัวกรองฐานข้อมูลเพื่อแบ่งพาร์ติชันข้อมูลดัชนีบันทึก ฯลฯ แต่ติดตั้งบนดิสก์ที่ใช้ร่วมกันเมื่อทรัพยากรมี จำกัด - เซิร์ฟเวอร์การพัฒนาเช่น ตามหลักการแล้วแต่ละไฟล์เหล่านี้จะแยกกันในโวลุ่มแยกดังนั้นการดู IO จากมุมมองดิสก์จะเพียงพอ - ซึ่งเป็นไปได้ว่าทำไมยูทิลิตี้การตรวจสอบทั้งหมดเป็นดิสก์ไม่ใช่ไฟล์
kermatt

มันเป็นคำถามที่ถูกต้อง เป้าหมายกำลังพยายามหาว่า "ตารางใดที่ I / O ทั้งหมดนี้เกิดขึ้น?" และในฐานข้อมูลส่วนใหญ่ตารางนั้นเป็นหนึ่งหรือหลายไฟล์ ดิสก์ใด ๆ จะถูกปิดท้ายด้วยไฟล์จำนวนมากที่อยู่ในนั้นและการพิจารณาว่าไฟล์ใดที่เป็นฮอตสปอตนั้นเป็นอินพุตการปรับแต่งฐานข้อมูลที่มีประโยชน์
Greg Smith

2

คุณสามารถตรวจสอบ i / o ต่ออุปกรณ์บล็อก (ผ่าน / proc / diskstats) และต่อกระบวนการ (บัญชี io ผ่าน/proc/$PID/ioหรือtaskstats ) แต่ฉันไม่รู้วิธีที่จะทำต่อไฟล์


0

อาจจะinotifyจะแก้ปัญหานี้

API inotify จัดเตรียมกลไกสำหรับการมอนิเตอร์เหตุการณ์ระบบไฟล์การแจ้งเตือนสามารถใช้เพื่อมอนิเตอร์แต่ละไฟล์หรือเพื่อมอนิเตอร์ไดเร็กทอรี เมื่อไดเร็กทอรีถูกมอนิเตอร์ inotify จะส่งคืนเหตุการณ์สำหรับไดเร็กทอรีเองและสำหรับไฟล์ภายในไดเร็กทอรี

มอนิเตอร์กิจกรรมระบบไฟล์ด้วย inotify

inotify Reference


สิ่งนี้อาจจัดเตรียมการเรียกบนไฟล์ แต่มีข้อเสนอเล็กน้อยเพื่อช่วยในการค้นหาว่า pid ทำอะไรได้บ้างการเขียนขนาดใหญ่ที่ไหนและนานเท่าใด
Matthew Ife

คำถามที่ไม่ถามเกี่ยวกับกระบวนการ (ที่อาจจะได้รับการค้นพบโดยวิธีการอื่นเช่นlsof)
Gert van den Berg

0

ในขณะที่มีข้อมูลที่ดีมากมายในคำตอบที่นี่ฉันสงสัยว่ามันใช้งานได้จริง?

หากคุณกำลังพูดถึงไฟล์ในช่วง 10s ของกิกะไบต์ซึ่งถูกเขียนไปเรื่อย ๆ เว้นแต่ว่าเป็นไฟล์บันทึกหรือไฟล์ที่คล้ายกันซึ่งต่อท้ายอยู่ตลอดเวลา . หากเป็นเช่นนั้นคำตอบที่ดีที่สุดอาจเป็นได้ว่าคุณควรหยุดดูวิธีแก้ปัญหาส่วนใหญ่ สิ่งแรกที่คุณควรถามถึงวิธีแก้ปัญหาอื่น ๆ ที่เสนอคือ "ทำงานกับ mmap" เพราะส่วนใหญ่พวกเขาจะไม่ทำงานอย่างไรก็ตามคุณอาจเปลี่ยนปัญหาให้เป็นการตรวจสอบอุปกรณ์บล็อกมากกว่าการตรวจสอบไฟล์

เมื่อโปรแกรมขอหน้าจากไฟล์ mmap'd เพียงแค่อ้างอิงตำแหน่งในหน่วยความจำเสมือน หน้านั้นอาจอยู่ในหน่วยความจำหรือไม่ก็ได้ ถ้าไม่ใช่นั่นก็จะสร้างความผิดพลาดของหน้าซึ่งเป็นสาเหตุที่ทำให้หน้าโหลดจากดิสก์ แต่เกิดขึ้นภายในระบบหน่วยความจำเสมือนซึ่งไม่ได้ผูกติดอยู่กับกระบวนการสมัครเฉพาะหรือไฟล์เฉพาะ ในทำนองเดียวกันเมื่อแอพของคุณอัปเดตหน้า mmap'd ขึ้นอยู่กับแฟล็กซึ่งอาจไม่ทำให้เกิดการเขียนลงดิสก์ทันทีและในบางกรณีอาจไม่ได้ไปที่ดิสก์เลย ใน).

สิ่งที่ดีที่สุดที่ฉันสามารถนึกได้สำหรับไฟล์ mmap'd หากเป็นไปได้สำหรับคุณคือการใส่ไฟล์แต่ละไฟล์ที่สนใจลงในอุปกรณ์แยกต่างหากและใช้สถิติอุปกรณ์เพื่อรวบรวมข้อมูลการใช้งานของคุณ คุณสามารถใช้พาร์ทิชัน lvm สำหรับสิ่งนี้ การเชื่อมโยงจะไม่ทำงานแม้ว่าจะไม่ได้สร้างอุปกรณ์บล็อกใหม่

เมื่อคุณมีไฟล์ของคุณในอุปกรณ์บล็อกแยกต่างหากคุณสามารถรับสถิติจาก / sys / block / * หรือหรือ / proc / diskstats

อาจก่อกวนเกินไปที่จะแนะนำสิ่งนี้กับเซิร์ฟเวอร์ที่ใช้งานจริง แต่บางทีคุณอาจใช้มันได้

หากไฟล์นั้นไม่ได้ถูก mmapped ดังนั้นคุณสามารถเลือกวิธีการแก้ปัญหาอื่นที่นี่


โปรดอ่านอย่างระมัดระวังฉันไม่ต้องการสถิติระดับบล็อก :)
GioMac

ถูกต้อง แต่ประเภทของสถิติที่คุณกำลังร้องขอนั้นเป็นไปไม่ได้สำหรับไฟล์ที่ถูกแมปดังนั้นหากคุณใช้งานกับสิ่งนั้นสิ่งนี้จะเป็นวิธีที่เป็นไปได้ในการรับสถิติเกี่ยวกับไฟล์โดยใช้หนึ่งไฟล์ต่ออุปกรณ์และอ่าน สถิติอุปกรณ์
mc0e

-1

เมื่อเร็ว ๆ นี้ฉันกำลังซ่อมแซมด้วยcollectlมันดูเป็นเครื่องมือที่ยอดเยี่ยมและค่อนข้างติดตั้ง สิ่งที่น่าสนใจที่สุดคือคุณสามารถทราบได้ว่ากระบวนการใดบ้างที่ทำให้คอขวด IO ต้องรับผิดชอบ ฉันอยากจะแนะนำให้คุณอ่าน โดยใช้ Collectlมันอาจจะมีประโยชน์


1
collectl ไม่ได้ตรวจสอบต่อไฟล์มันทำงานได้ตามกระบวนการ
Greg Smith

-1

ฉันจะแนะนำให้คุณตรวจสอบhttp://dag.wieers.com/home-made/dstat/ เครื่องมือที่ยอดเยี่ยมนี้ช่วยให้สามารถตรวจสอบสถานะได้มากมาย


1
dstat ไม่ได้ตรวจสอบต่อไฟล์มันสรุปต่อกระบวนการ
Greg Smith

-2

ฉันคิดว่าไอโซโทปเป็นหนึ่งในเครื่องมือที่ดีที่สุดบน Linux สำหรับระบุปัญหาคอขวดใน IO


3
-1 iotopไม่ได้ตรวจสอบต่อไฟล์มันทำงานได้ตามกระบวนการ
dyasny
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.