天天看點

磁盤的性能監控

測試磁盤的IOPS

IOPS是衡量磁盤性能的主要名額之一,它是指機關時間内系統能處理的I/O請求數量,I/O請求通常為讀寫資料操作請求。磁盤的 IOPS,也就是在一秒内,磁盤進行多少次 I/O 讀寫。另一個重要的名額是資料吞吐量,機關時間内可以成功傳輸的資料量。磁盤的吞吐量,也就是每秒磁盤 I/O 的流量,即磁盤寫入加上讀出的資料的大小。

fio是測試IOPS非常好的工具,用來對硬碟進行壓力測試和驗證,支援13種不同的I/O引擎,包括:sync, mmap, libaio, posixaio, SG v3, splice, null, network, syslet, guasi, solarisaio 等等。

fio工具安裝

wget http://brick.kernel.dk/snaps/fio-..tar.gz
apt-get install libaio-dev
tar -zxvf fio-..tar.gz
cd fi0-.
make
make install
           

磁盤測試方式

選項 說明
-fielname=/dev/sda1 測試檔案名稱,通常選擇需要測試的磁盤分區檔案
-direct=1 表示測試直接繞過系統自帶的buffer,是測試結果更加真實
-ioengine=libaio IO引擎使用libaio方式
-iodepth=1 表示隊列深度,對于單線程iodepth總是小于1
-rw=randread/randwrite/read/write/randrw 測試随機讀/随機寫/讀/寫/随機讀寫
-bs=4K 表示一次IO的塊大小為4K
-size=100G 本次測試檔案大小為100G
-numjobs=10 測試線程數為10
-runtime=120 測試時間為120秒
-rwmixwrite=50 混合模式下寫占50%
-name=test 本次測試名稱

随機讀

fio -rw=randrw -bs=k -runtime= -iodepth= -filename=/dev/sda1 -ioengine=libaio 
-direct= -name=iops_randread
           

IOPS與吞吐量的關系

每秒I/O吞吐量 = IOPS * 平均I/O SIZE

從公式可以看出: I/O SIZE 越大,IOPS 越高,那麼每秒 I/O 的吞吐量就越高。是以,我們會認為 IOPS 和吞吐量的數值越高越好。實際上,對于一個磁盤來講,這兩個參數均有其最大值,而且這兩個參數也存在着一定的關系。混合讀寫和順序随機I/O負載情況下的磁盤IOPS,這個與實際I/O情況最為相符,大多數應用關注此名額。

IOPS計算公式

對于磁盤來說一個完整的IO操作是這樣進行的:當控制器對磁盤發出一個IO操作指令的時候,磁盤的驅動臂(Actuator Arm)帶讀寫磁頭(Head)離開着陸區(Landing Zone,位于内圈沒有資料的區域),移動到要操作的初始資料塊所在的磁道(Track)的正上方,這個過程被稱為尋址(Seeking),對應消耗的時間被稱為尋址時間(Seek Time);但是找到對應磁道還不能馬上讀取資料,這時候磁頭要等到磁盤盤片(Platter)旋轉到初始資料塊所在的扇區(Sector)落在讀寫磁頭正上方的之後才能開始讀取資料,在這個等待盤片旋轉到可操作扇區的過程中消耗的時間稱為旋轉延時(Rotational Delay);接下來就随着盤片的旋轉,磁頭不斷的讀/寫相應的資料塊,直到完成這次IO所需要操作的全部資料,這個過程稱為資料傳送(Data Transfer),對應的時間稱為傳送時間(Transfer Time)。完成這三個步驟之後一次IO操作也就完成了。

在我們看硬碟廠商的宣傳單的時候我們經常能看到3個參數,分别是平均尋址時間、盤片旋轉速度以及最大傳送速度,這三個參數就可以提供給我們計算上述三個步驟的時間。

第一個尋址時間,考慮到被讀寫的資料可能在磁盤的任意一個磁道,既有可能在磁盤的最内圈(尋址時間最短),也可能在磁盤的最外圈(尋址時間最長),是以在計算中我們隻考慮平均尋址時間,也就是磁盤參數中标明的那個平均尋址時間,這裡就采用目前最多的10krmp硬碟的5ms。

第二個旋轉延時,和尋址一樣,當磁頭定位到磁道之後有可能正好在要讀寫扇區之上,這時候是不需要額外額延時就可以立刻讀寫到資料,但是最壞的情況确實要磁盤旋轉整整一圈之後磁頭才能讀取到資料,是以這裡我們也考慮的是平均旋轉延時,對于10krpm的磁盤就是(60s/10k)*(1/2) = 2ms。

第三個傳送時間,磁盤參數提供我們的最大的傳輸速度,當然要達到這種速度是很有難度的,但是這個速度卻是磁盤純讀寫磁盤的速度,是以隻要給定了單次 IO的大小,我們就知道磁盤需要花費多少時間在資料傳送上,這個時間就是IO Chunk Size / Max Transfer Rate。

現在我們就可以得出這樣的計算單次IO時間的公式。

IO Time = Seek Time + 60 sec/Rotational Speed/2 + IO Chunk Size/Transfer Rate

于是我們可以這樣計算出IOPS。

  IOPS = 1/IO Time = 1/(Seek Time + 60 sec/Rotational Speed/2 + IO Chunk Size/Transfer Rate)

對于給定不同的IO大小我們可以得出下面的一系列的資料

  4K (1/7.1 ms = 140 IOPS)

  5ms + (60sec/15000RPM/2) + 4K/40MB = 5 + 2 + 0.1 = 7.1

  8k (1/7.2 ms = 139 IOPS)

  5ms + (60sec/15000RPM/2) + 8K/40MB = 5 + 2 + 0.2 = 7.2

  16K (1/7.4 ms = 135 IOPS)

  5ms + (60sec/15000RPM/2) + 16K/40MB = 5 + 2 + 0.4 = 7.4

  32K (1/7.8 ms = 128 IOPS)

  5ms + (60sec/15000RPM/2) + 32K/40MB = 5 + 2 + 0.8 = 7.8

  64K (1/8.6 ms = 116 IOPS)

  5ms + (60sec/15000RPM/2) + 64K/40MB = 5 + 2 + 1.6 = 8.6

  

從上面的資料可以看出,當單次IO越小的時候,單次IO所耗費的時間也越少,相應的IOPS也就越大。

上面我們的資料都是在一個比較理想的假設下得出來的,這裡的理想的情況就是磁盤要花費平均大小的尋址時間和平均的旋轉延時,這個假設其實是比較符合我們實際情況中的随機讀寫,在随機讀寫中,每次IO操作的尋址時間和旋轉延時都不能忽略不計,有了這兩個時間的存在也就限制了IOPS的大小。現在我們考慮一種相對極端的順序讀寫操作,比如說在讀取一個很大的存儲連續分布在磁盤的的檔案,因為檔案的存儲的分布是連續的,磁頭在完成一個讀IO操作之後,不需要從新的尋址,也不需要旋轉延時,在這種情況下我們能到一個很大的IOPS值,如下:

  4K (1/0.1 ms = 10000 IOPS)

  0ms + 0ms + 4K/40MB = 0.1

  8k (1/0.2 ms = 5000 IOPS)

  0ms + 0ms + 8K/40MB = 0.2

  16K (1/0.4 ms = 2500 IOPS)

  0ms + 0ms + 16K/40MB = 0.4

  32K (1/0.8 ms = 1250 IOPS)

  0ms + 0ms + 32K/40MB = 0.8

  64K (1/1.6 ms = 625 IOPS)

  0ms + 0ms + 64K/40MB = 1.6

  

另外,對于同一個磁盤(或者 LUN),随着每次 I/O 讀寫資料的大小不通,IOPS 的數值也不是固定不變的。例如,每次 I/O 寫入或者讀出的都是連續的大資料塊,此時 IOPS 相對會低一些;在不頻繁換道的情況下,每次寫入或者讀出的資料塊小,相對來講 IOPS 就會高一些。也就是說,IOPS 也取決與I/O塊的大小,采用不同I/O塊的大小測出的IOPS值是不同的。 對一個具體的IOPS, 可以了解它當時測試的I/O塊的尺寸。

繼續閱讀