1. 程式人生 > 其它 >磁碟io效能分析

磁碟io效能分析

 

一,概念

磁碟io,顧名思義就是磁碟的輸入輸出。即向磁碟寫入資料和從磁碟讀取資料。

I/O 讀寫的型別,大體上講,I/O 的型別可以分為:

讀 / 寫 I/O、大 / 小塊 I/O、連續 / 隨機 I/O, 順序 / 併發 I/O。在這幾種型別中,我們主要討論一下:大 / 小塊 I/O、連續 / 隨機 I/O, 順序 / 併發 I/O。

1,讀 / 寫 I/O

磁碟是用來給我們存取資料用的,因此當說到IO操作的時候,就會存在兩種相對應的操作,存資料時候對應的是寫IO操作,取資料的時候對應的是是讀IO操作。

當控制磁碟的控制器接到作業系統的讀IO操作指令的時候,控制器就會給磁碟發出一個讀資料的指令,並同時將要讀取的資料塊的地址傳遞給磁碟,然後磁碟會將讀取到的資料傳給控制器,並由控制器返回給作業系統,完成一個讀IO的操作;同樣的,一個寫IO的操作也類似,控制器接到寫的IO操作的指令和要寫入的資料,並將其傳遞給磁碟,磁碟在資料寫入完成之後將操作結果傳遞迴控制器,再由控制器返回給作業系統,完成一個寫IO的操作。單個IO操作指的就是完成一個寫IO或者是讀IO的操作。

2,大 / 小塊 I/O

這個數值指的是控制器指令中給出的連續讀出扇區數目的多少。如果數目較多,如 64,128 等,我們可以認為是大塊 I/O;反之,如果很小,比如 4,8,我們就會認為是小塊 I/O,實際上,在大塊和小塊 I/O 之間,沒有明確的界限。

3,連續 / 隨機 I/O

連續 I/O 指的是本次 I/O 給出的初始扇區地址和上一次 I/O 的結束扇區地址是完全連續或者相隔不多的。反之,如果相差很大,則算作一次隨機 I/O

連續 I/O 比隨機 I/O 效率高的原因是:在做連續 I/O 的時候,磁頭幾乎不用換道,或者換道的時間很短;而對於隨機 I/O,如果這個 I/O 很多的話,會導致磁頭不停地換道,造成效率的極大降低。

4,順序 / 併發 I/O

從概念上講,併發 I/O 就是指向一塊磁碟發出一條 I/O 指令後,不必等待它迴應,接著向另外一塊磁碟發 I/O 指令。對於具有條帶性的 RAID(LUN),對其進行的 I/O 操作是併發的,例如:raid 0+1(1+0),raid5 等。反之則為順序 I/O。

二,影響磁碟效能的因素

    傳統磁碟本質上一種機械裝置,如FC, SAS, SATA磁碟,轉速通常為5400/7200/10K/15K rpm不等。影響磁碟的關鍵因素是磁碟服務時間,即磁碟完成一個I/O請求所花費的時間,它由尋道時間、旋轉延遲和資料傳輸時間三部分構成。

1,尋道時間

Tseek是指將讀寫磁頭移動至正確的磁軌上所需要的時間。尋道時間越短,I/O操作越快,目前磁碟的平均尋道時間一般在3-15ms。

2,旋轉延遲

Trotation是指碟片旋轉將請求資料所在扇區移至讀寫磁頭下方所需要的時間。旋轉延遲取決於磁碟轉速,通常使用磁碟旋轉一週所需時間的1/2表示。比如,7200 rpm的磁碟平均旋轉延遲大約為60*1000/7200/2 = 4.17ms,而轉速為15000 rpm的磁碟其平均旋轉延遲為2ms。

3,資料傳輸時間

Ttransfer是指完成傳輸所請求的資料所需要的時間,它取決於資料傳輸率,其值等於資料大小除以資料傳輸率。目前IDE/ATA能達到133MB/s,SATA II可達到300MB/s的介面資料傳輸率,資料傳輸時間通常遠小於前兩部分消耗時間。簡單計算時可忽略。

 常見磁碟平均物理尋道時間為:

7200轉/分的STAT硬碟平均物理尋道時間是10.5ms

10000轉/分的STAT硬碟平均物理尋道時間是7ms

15000轉/分的SAS硬碟平均物理尋道時間是5ms

 常見硬碟的旋轉延遲時間為:

7200   rpm的磁碟平均旋轉延遲大約為60*1000/7200/2 = 4.17ms

10000 rpm的磁碟平均旋轉延遲大約為60*1000/10000/2 = 3ms,

15000 rpm的磁碟其平均旋轉延遲約為60*1000/15000/2 = 2ms。

最大IOPS的理論計算方法:

IOPS = 1000 ms/ (尋道時間 + 旋轉延遲)。可以忽略資料傳輸時間。

7200   rpm的磁碟 IOPS = 1000 / (10.5 + 4.17)  = 68 IOPS

10000 rpm的磁碟IOPS = 1000 / (7 + 3) = 100 IOPS

15000 rpm的磁碟IOPS = 1000 / (5 + 2) = 142 IOPS

影響測試的因素:

實際測量中,IOPS數值會受到很多因素的影響,包括I/O負載特徵(讀寫比例,順序和隨機,工作執行緒數,佇列深度,資料記錄大小)、系統配置、作業系統、磁碟驅動等等。因此對比測量磁碟IOPS時,必須在同樣的測試基準下進行,即便如此也會產生一定的隨機不確定性。

三,衡量效能的重要指標

    我們常見的磁碟型別有 ATA、SATA、FC、SCSI、SAS。這幾種磁碟中,伺服器常用的是 SAS 和 FC 磁碟,一些高階儲存也使用 SSD 盤。每一種磁碟的效能是不一樣的,機械硬碟的連續讀寫行都很好,但隨機讀寫效能很差,這主要是因為磁頭移動到正確的磁軌上需要時間,隨機讀寫時,磁頭需要不停的移動,時間都浪費在了磁頭定址上,所以效能不高。當儲存小檔案時,隨機讀寫的IOPS將是重要指標;當儲存像視訊大檔案時,順序讀寫IOPS將是重要指標。

主要有兩個指標:

1,IOPS

就是在一秒內,磁碟進行多少次 I/O 讀寫。決定IOPS的主要取決與陣列的演算法,cache命中率,以及磁碟個數。陣列的演算法因為不同的陣列不同而不同,如我們最近遇到在hds usp上面,可能因為ldev(lun)存在佇列或者資源限制,而單個ldev的iops就上不去。cache的命中率取決於資料的分佈,cache size的大小,資料訪問的規則,以及cache的演算法。我這裡只強調一個cache的命中率,如果一個陣列,讀cache的命中率越高越好,一般表示它可以支援更多的IOPS。硬碟的限制,每個物理硬碟能處理的IOPS是有限制的,如果一個陣列有120塊15K rpm的光纖硬碟,那麼,它能撐的最大IOPS為120*150=18000,這個為硬體限制的理論值,如果超過這個值,硬碟的響應可能會變的非常緩慢而不能正常提供業務。

2,吞度量

也叫磁碟頻寬,每秒磁碟 I/O 的流量,即磁碟寫入和讀出的資料的總大小。他主要取決於磁碟陣列的構架,通道的大小以及磁碟的個數。不同的磁碟陣列存在不同的構架,但他們都有自己的內部頻寬(如主線型或星型),不過一般情況下,內部頻寬都設計足夠充足,不會存在瓶頸。磁碟陣列與伺服器之間的資料通道便對吞吐量的影響很大。一般情況下,因為磁碟實際使用的吞吐率一旦超過磁碟吞吐量的85%,就會出現I/O瓶頸。下面是常用通道的頻寬:

2Gbps 光纖通道,(250MB/s), 4Gbps 光纖通道(500MB/S),SCSI最高速度是320MB/s,SATA是150MB/s,IED 133MB/s。最後說一下是硬碟的限制,目前SCSI硬碟資料傳輸率最高在80MB/s,SAS硬碟資料為傳輸率最高在80-100MB/S。對於資料庫小資料的離散寫入,其傳輸率快快達不到這個值,主要原因是因為磁碟定址等浪費太多時間。

下面舉例來說明:

如果寫一個10M的檔案需要0.1S,則磁碟計算出磁碟頻寬為100M/s,如果寫10000個大小為1KB的檔案需要10S,則磁碟頻寬只有1M/s。

IOPS 與吞吐量的關係:

每秒 I/O 吞吐量= IOPS* 平均 I/O SIZE。從公式可以看出: I/O SIZE 越大,IOPS 越高,那麼每秒 I/O 的吞吐量就越高。因此,我們會認為 IOPS 和吞吐量的數值越高越好。實際上,對於一個磁碟來講,這兩個引數均有其最大值,而且這兩個引數也存在著一定的關係。

四,測試磁碟效能的工具

1,下載並安裝fio工具:

# git clone git://git.kernel.dk/fio.git

# yum install libaio-devel
# cd fio

# ./configure
# make
# make install

2,非同步io效能測試:

不同的應用會使用不同的io型別進行io讀寫,故不同的應用應該使用不同的io engine做測試。

非同步的話就是用類似libaio這樣的linux native aio一次提交一批,然後等待一批的完成,減少互動的次數,會更有效率。

# cat nvdisk-test
[global]
bs=512
ioengine=libaio
userspace_reap
rw=randrw
rwmixwrite=20
time_based
runtime=180
direct=1
group_reporting
randrepeat=0
norandommap
ramp_time=6
iodepth=16
iodepth_batch=8
iodepth_low=8
iodepth_batch_complete=8
exitall

size=5G
[test]
filename=/data/test.data
numjobs=1

使用的引數和選項如下,更多的說明請參考man fio:

bs=16k 單次io的塊檔案大小為16k
ioengine io引擎使用非同步libaio方式
userspace_reap libaio特有選項,預設fio使用io_getevents系統呼叫收割新返回的時間,開啟這個選項後直接在使用者空間完成收割。
rw=randwrite 測試隨機寫的I/O
rwmixwrite 在混合讀寫的模式下,寫佔的百分百
time_based 沒有到指定的runtime時間,但測試任務已經完成,程式仍然不停止,繼續重複測試,直到到指定runtime時間。
runtime 執行多少s
direct=1 測試過程繞過機器自帶的buffer。使測試結果更真實。非同步io模型測試,必須開啟
group_reporting 關於顯示結果的,彙總每個程序或這執行緒的資訊。
randrepeat  對於隨機IO負載,配置生成器,使得路徑是可以預估的,使得每次重複執行生成的序列是一樣的
norandommap 一般情況下,fio在做隨機IO時,將會覆蓋檔案的每一個block。如果這個選項設定的話,fio將只是獲取一個新的隨機offset,而不會查詢過去的歷史。這意味著一些塊可能沒有讀或寫,一些塊可能要讀/寫很多次。
ramp_time 設定在記錄任何效能資訊之前要執行特定負載的時間。這個用來等效能穩定後,再記錄日誌結果
iodepth=16
iodepth_batch=8
iodepth_low=8
iodepth_batch_complete=8
libaio非同步引擎會用這個iodepth值來呼叫io_setup準備個可以一次提交iodepth個IO的上下文,同時申請個io請求佇列用於保持IO。 在壓測進行的時候,系統會生成特定的IO請求,往io請求佇列裡面扔,當佇列裡面的IO個數達到iodepth_batch值的時候,就呼叫io_submit批次提交請求,然後開始呼叫io_getevents開始收割已經完成的IO。 每次收割多少呢?由於收割的時候,超時時間設定為0,所以有多少已完成就算多少,最多可以收割iodepth_batch_complete值個。隨著收割,IO佇列裡面的IO數就少了,那麼需要補充新的IO。 什麼時候補充呢?當IO數目降到iodepth_low值的時候,就重新填充,保證OS可以看到至少iodepth_low數目的io在電梯口排隊著。
size 指定本次測試資料檔案的大小,預設情況下單個磁碟塊為4k。
exitall 當一個job完成,就退出
filename  一般情況下,fio會根據job名,執行緒號,檔案號來產生一個檔名。如果,想在多個job之間共享同一個檔案的話,可以通過這個引數設定一個檔名字來代替預設的名字。這個檔案必須是在要測試的磁碟整列上。
numjobs 本次的測試程序數

fio任務配置裡面有幾個點需要非常注意:
1. libaio工作的時候需要檔案direct方式開啟。
2. 塊大小必須是扇區(512位元組)的倍數。
3. userspace_reap提高非同步IO收割的速度。
4. ramp_time的作用是減少日誌對高速IO的影響。
5. 只要開了direct,fsync就不會發生。

3,同步io效能測試案例:

順序讀:
fio -filename=/data/test.data -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=16k -size=5G -numjobs=30 -runtime=1000 -group_reporting -name=mytest

隨機寫:
fio -filename=/data/test.data -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=16k -size=5G -numjobs=30 -runtime=1000 -group_reporting -name=mytest

順序寫:
fio -filename=/data/test.data -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=16k -size=5G -numjobs=30 -runtime=1000 -group_reporting -name=mytest

混合隨機讀寫:
fio -filename=/data/test.data -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=16k -size=5G -numjobs=30 -runtime=100 -group_reporting -name=mytest -ioscheduler=noop

轉載於:https://blog.51cto.com/leejia/1552807

  相關資源:工作經驗:windows伺服器下磁碟IO效能監控和分析報告