如何找出當前佔用磁盤IO最多的進程

linux系統上可以使用(centos 2.6.18-144開始支持),dstat版本至少是:dstat-0.6.7-1.rf.noarch.rpm
安裝
wget -c http://linux.web.psi.ch/dist/scientific/5/gfa/all/dstat-0.6.7-1.rf.noarch.rpm
rpm -Uvh dstat-0.6.7-1.rf.noarch.rpm


使用
# dstat -M topio -d -M topbio
 

 

Linux Kernel 2.6.20 以上的內核支持進程 IO 統計,可以用類似 iotop 這樣的工具來監測每個進程對 IO 操作的情況,就像用 top 來實時查看進程內存、CPU 等佔用情況那樣。但是對於 2.6.20 以下的 Linux 內核版本就沒那麼幸運了,根據 Stack Overflow 的這篇回帖 給出的方法,VPSee 寫了一個簡單的 Python 腳本用來在 linux kernel < 2.6.20 下打印進程 IO 狀況。

Kernel < 2.6.20

這個腳本的想法很簡單,把 dmesg 的結果重定向到一個文件後再解析出來,每隔1秒鐘打印一次進程 IO 讀寫的統計信息,執行這個腳本需要 root:

#!/usr/bin/python # Monitoring per-process disk I/O activity # written by http://www.vpsee.com  import sys, os, time, signal, re class DiskIO:     def __init__(self, pname=None, pid=None, reads=0, writes=0):         self.pname = pname         self.pid = pid         self.reads = 0         self.writes = 0 def main():     argc = len(sys.argv)     if argc != 1:         print "usage: ./iotop"         sys.exit(0)     if os.getuid() != 0:         print "must be run as root"         sys.exit(0)     signal.signal(signal.SIGINT, signal_handler)     os.system('echo 1 > /proc/sys/vm/block_dump')     print "TASK              PID       READ      WRITE"     while True:         os.system('dmesg -c > /tmp/diskio.log')         l = []         f = open('/tmp/diskio.log', 'r')         line = f.readline()         while line:             m = re.match(\                 '^(\S+)\((\d+)\): (READ|WRITE) block (\d+) on (\S+)', line)             if m != None:                 if not l:                     l.append(DiskIO(m.group(1), m.group(2)))                     line = f.readline()                     continue                 found = False                 for item in l:                     if item.pid == m.group(2):                         found = True                         if m.group(3) == "READ":                             item.reads = item.reads + 1                         elif m.group(3) == "WRITE":                             item.writes = item.writes + 1                 if not found:                     l.append(DiskIO(m.group(1), m.group(2)))             line = f.readline()         time.sleep(1)         for item in l:             print "%-10s %10s %10d %10d" % \                 (item.pname, item.pid, item.reads, item.writes) def signal_handler(signal, frame):     os.system('echo 0 > /proc/sys/vm/block_dump')     sys.exit(0) if __name__=="__main__":     main() 

Kernel >= 2.6.20

如果想用 iotop 來實時查看進程 IO 活動狀況的話,需要下載和升級新內核(2.6.20 或以上版本)。編譯新內核時需要打開 TASK_DELAY_ACCT 和 TASK_IO_ACCOUNTING 選項。解壓內核後進入配置界面:

# tar jxvf linux-2.6.30.5.tar.bz2 # mv linux-2.6.30.5 /usr/src/ # cd /usr/src/linux-2.6.30.5 # make menuconfig 

選擇 Kernel hacking –> Collect scheduler debugging info 和 Collect scheduler statistics,保存內核後編譯內核:

# make; make modules; make modules_install; make install 

修改 grub,確認能正確啓動新內核:

# vi /boot/grub/menu.lst 

出了新內核外,iotop 還需要 Python 2.5 或以上才能運行,所以如果當前 Python 是 2.4 的話需要下載和安裝最新的 Python 包。這裏使用源代碼編譯安裝:

# tar jxvf Python-2.6.2.tar.bz2 # cd Python-2.6.2 # ./configure # make; make install 

別忘了下載 setuptools:

# mv setuptools-0.6c9-py2.6.egg.sh setuptools-0.6c9-py2.6.egg # sh setuptools-0.6c9-py2.6.egg 

更多信息

如果想知道更多關於 block_dump 的信息,可以看看這篇 監測 Linux 進程的實時 IO 情況。使用 block_dump 的時候,最好能關掉 klogd 進程。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章