磁盤IO


基本概念:

在數據庫優化和存儲規划過程中,總會提到IO的一些重要概念,在這里就詳細記錄一下,個人認為對這個概念的熟悉程度也決定了對數據庫與存儲優化的理解程度,以下這些概念並非權威文檔,權威程度肯定就不能說了。

 

讀/寫IO:最為常見說法,讀IO,就是發指令,從磁盤讀取某段扇區的內容。指令一般是通知磁盤開始扇區位置,然后給出需要從這個初始扇區往后讀取的連續扇區個數,同時給出動作是讀,還是寫。磁盤收到這條指令,就會按照指令的要求,讀或者寫數據。控制器發出的這種指令+數據,就是一次IO,讀或者寫。

 
大/小塊IO:指控制器的指令中給出的連續讀取扇區數目的多少,如果數目很大,比如128,64等等,就應該算是大塊IO,如果很小,比如1, 4,8等等,就應該算是小塊IO,大塊和小塊之間,沒有明確的界限。
 
連續/隨機IO:連續和隨機,是指本次IO給出的初始扇區地址,和上一次IO的結束扇區地址,是不是完全連續的,或者相隔不多的,如果是,則本次IO應該算是一個連續IO,如果相差太大,則算一次隨機IO。連續IO,因為本次初始扇區和上次結束扇區相隔很近,則磁頭幾乎不用換道或換道時間極短;如果相差太大,則磁頭需要很長的換道時間,如果隨機IO很多,導致磁頭不停換道,效率大大降底。 

順序/並發IO:這個的意思是,磁盤控制器每一次對磁盤組發出的指令套(指完成一個事物所需要的指令或者數據),是一條還是多條。如果是一條,則控制器緩存中的IO隊列,只能一個一個的來,此時是順序IO;如果控制器可以同時對磁盤組中的多塊磁盤,同時發出指令套,則每次就可以執行多個IO,此時就是並發IO模式。並發IO模式提高了效率和速度。
 
IO並發幾率:單盤,IO並發幾率為0,因為一塊磁盤同時只可以進行一次IO。對於raid0,2塊盤情況下,條帶深度比較大的時候(條帶太小不能並發IO,下面會講到),並發2個IO的幾率為1/2。其他情況請自行運算。 

IOPS:即每秒進行讀寫(I/O)操作的次數,一個IO所用的時間=尋道時間+數據傳輸時間。 IOPS=IO並發系數/(尋道時間+數據傳輸時間),由於尋道時間相對傳輸時間,大幾個數量級,所以影響IOPS的關鍵因素,就是降底尋道時間,而在連續IO的情況下,尋道時間很短,僅在換磁道時候需要尋道。在這個前提下,傳輸時間越少,IOPS就越高。
 
每秒IO吞吐量。顯然,每秒IO吞吐量=IOPS乘以平均IO SIZE。 Io size越大,IOPS越高,每秒IO吞吐量就越高。設磁頭每秒讀寫數據速度為V,V為定值。則IOPS=IO並發系數/(尋道時間+IO SIZE/V),代入,得每秒IO吞吐量=IO並發系數乘IO SIZE乘V/(V乘尋道時間+IO SIZE)。我們可以看出影響每秒IO吞吐量的最大因素,就是IO SIZE和尋道時間,IO SIZE越大,尋道時間越小,吞吐量越高。相比能顯著影響IOPS的因素,只有一個,就是尋道時間。
 
重點介紹
 

機械硬盤的連續讀寫性很好, 但隨機讀寫性能很差。這是因為磁頭移動至正確的磁道上需要時間,隨機讀寫時,磁頭不停的移動,時間都花在了磁頭尋道上,所以性能不高。  如下圖:

在存儲小文件(圖片)、OLTP數據庫應用時,隨機讀寫性能(IOPS)是最重要指標。

學習它,有助於我們分析存儲系統的性能互瓶頸。
下面我們來認識隨機讀寫性能指標--IOPS(每秒的輸入輸出次數)。

 


磁盤性能指標--IOPS
----------------------------------------------------------
        IOPS (Input/Output Per Second)即每秒的輸入輸出量(或讀寫次數),是衡量磁盤性能的主要指標之一。IOPS是指單位時間內系統能處理的I/O請求數量,一般以每秒處理的I/O請求數量為單位,I/O請求通常為讀或寫數據操作請求。

    隨機讀寫頻繁的應用,如小文件存儲(圖片)、OLTP數據庫、郵件服務器,關注隨機讀寫性能,IOPS是關鍵衡量指標。

    順序讀寫頻繁的應用,傳輸大量連續數據,如電視台的視頻編輯,視頻點播VOD(Video On Demand),關注連續讀寫性能。數據吞吐量是關鍵衡量指標。

IOPS和數據吞吐量適用於不同的場合:
讀取10000個1KB文件,用時10秒  Throught(吞吐量)=1MB/s ,IOPS=1000  追求IOPS
讀取1個10MB文件,用時0.2秒  Throught(吞吐量)=50MB/s, IOPS=5  追求吞吐量

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

尋道時間 Tseek是指將讀寫磁頭移動至正確的磁道上所需要的時間。尋道時間越短,I/O操作越快,目前磁盤的平均尋道時間一般在3-15ms。
旋轉延遲 Trotation是指盤片旋轉將請求數據所在扇區移至讀寫磁頭下方所需要的時間。旋轉延遲取決於磁盤轉速,通常使用磁盤旋轉一周所需時間的1/2表示。比如,7200 rpm的磁盤平均旋轉延遲大約為60*1000/7200/2 = 4.17ms,而轉速為15000 rpm的磁盤其平均旋轉延遲為2ms。
數據傳輸時間 Ttransfer是指完成傳輸所請求的數據所需要的時間,它取決於數據傳輸率,其值等於數據大小除以數據傳輸率。目前IDE/ATA能達到133MB/s,SATA II可達到300MB/s的接口數據傳輸率,數據傳輸時間通常遠小於前兩部分消耗時間。簡單計算時可忽略。

 

常見磁盤平均物理尋道時間為:
7200轉/分的STAT硬盤平均物理尋道時間是9ms
10000轉/分的STAT硬盤平均物理尋道時間是6ms
15000轉/分的SAS硬盤平均物理尋道時間是4ms

 

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

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 / (9 + 4.17)  = 76 IOPS
10000 rpm的磁盤IOPS = 1000 / (6+ 3) = 111 IOPS
15000 rpm的磁盤IOPS = 1000 / (4 + 2) = 166 IOPS


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


隊列深度說明 
NCQ、SCSI TCQ、PATA TCQ和SATA TCQ技術解析 
----------------------------------------
    是一種命令排序技術,一把喂給設備更多的IO請求,讓電梯算法和設備有機會來安排合並以及內部並行處理,提高總體效率。
SCSI TCQ的隊列深度支持256級
ATA TCQ的隊列深度支持32級 (需要8M以上的緩存)
NCQ最高可以支持命令深度級數為32級,NCQ可以最多對32個命令指令進行排序。
    大多數的軟件都是屬於同步I/O軟件,也就是說程序的一次I/O要等到上次I/O操作的完成后才進行,這樣在硬盤中同時可能僅只有一個命令,也是無法發揮這個技術的優勢,這時隊列深度為1。
    隨着Intel的超線程技術的普及和應用環境的多任務化,以及異步I/O軟件的大量涌現。這項技術可以被應用到了,實際隊列深度的增加代表着性能的提高。
在測試時,隊列深度為1是主要指標,大多數時候都參考1就可以。實際運行時隊列深度也一般不會超過4.


IOPS可細分為如下幾個指標:
-----------------------------------------
數據量為n字節,隊列深度為k時,隨機讀取的IOPS
數據量為n字節,隊列深度為k時,隨機寫入的IOPS


IOPS的測試benchmark工具
------------------------------------------
         IOPS的測試benchmark工具主要有Iometer, IoZone, FIO等,可以綜合用於測試磁盤在不同情形下的IOPS。對於應用系統,需要首先確定數據的負載特征,然后選擇合理的IOPS指標進行測量和對比分析,據此選擇合適的存儲介質和軟件系統

 
 
IO調度策略

一)I/O調度程序的總結:

1)當向設備寫入數據塊或是從設備讀出數據塊時,請求都被安置在一個隊列中等待完成.
2)每個塊設備都有它自己的隊列.
3)I/O調度程序負責維護這些隊列的順序,以更有效地利用介質.I/O調度程序將無序的I/O操作變為有序的I/O操作.
4)內核必須首先確定隊列中一共有多少個請求,然后才開始進行調度.

 

二)I/O調度的4種算法

1)CFQ(完全公平排隊I/O調度程序)

特點:
在最新的內核版本和發行版中,都選擇CFQ做為默認的I/O調度器,對於通用的服務器也是最好的選擇.
CFQ試圖均勻地分布對I/O帶寬的訪問,避免進程被餓死並實現較低的延遲,是deadline和as調度器的折中.
CFQ對於多媒體應用(video,audio)和桌面系統是最好的選擇.
CFQ賦予I/O請求一個優先級,而I/O優先級請求獨立於進程優先級,高優先級的進程的讀寫不能自動地繼承高的I/O優先級.


工作原理:
CFQ為每個進程/線程,單獨創建一個隊列來管理該進程所產生的請求,也就是說每個進程一個隊列,各隊列之間的調度使用時間片來調度,
以此來保證每個進程都能被很好的分配到I/O帶寬.I/O調度器每次執行一個進程的4次請求.


2)NOOP(電梯式調度程序)

特點:
在Linux2.4或更早的版本的調度程序,那時只有這一種I/O調度算法.
NOOP實現了一個簡單的FIFO隊列,它像電梯的工作主法一樣對I/O請求進行組織,當有一個新的請求到來時,它將請求合並到最近的請求之后,以此來保證請求同一介質.
NOOP傾向餓死讀而利於寫.
NOOP對於閃存設備,RAM,嵌入式系統是最好的選擇.

電梯算法餓死讀請求的解釋:
因為寫請求比讀請求更容易.
寫請求通過文件系統cache,不需要等一次寫完成,就可以開始下一次寫操作,寫請求通過合並,堆積到I/O隊列中.
讀請求需要等到它前面所有的讀操作完成,才能進行下一次讀操作.在讀操作之間有幾毫秒時間,而寫請求在這之間就到來,餓死了后面的讀請求.

 

3)Deadline(截止時間調度程序)

特點:
通過時間以及硬盤區域進行分類,這個分類和合並要求類似於noop的調度程序.
Deadline確保了在一個截止時間內服務請求,這個截止時間是可調整的,而默認讀期限短於寫期限.這樣就防止了寫操作因為不能被讀取而餓死的現象.
Deadline對數據庫環境(ORACLE RAC,MySQL等)是最好的選擇.


4)AS(預料I/O調度程序)

特點:
本質上與Deadline一樣,但在最后一次讀操作后,要等待6ms,才能繼續進行對其它I/O請求進行調度.
可以從應用程序中預訂一個新的讀請求,改進讀操作的執行,但以一些寫操作為代價.
它會在每個6ms中插入新的I/O操作,而會將一些小寫入流合並成一個大寫入流,用寫入延時換取最大的寫入吞吐量.
AS適合於寫入較多的環境,比如文件服務器
AS對數據庫環境表現很差.

 

三)I/O調度方法的查看與設置

1)查看當前系統的I/O調度方法:

[root@test1 tmp]# cat /sys/block/sda/queue/scheduler 
noop anticipatory deadline [cfq]

2)臨地更改I/O調度方法:
例如:想更改到noop電梯調度算法:
echo noop > /sys/block/sda/queue/scheduler

3)想永久的更改I/O調度方法:
修改內核引導參數,加入elevator=調度程序名
[root@test1 tmp]# vi /boot/grub/menu.lst
更改到如下內容:
kernel /boot/vmlinuz-2.6.18-8.el5 ro root=LABEL=/ elevator=deadline rhgb quiet

重啟之后,查看調度方法:
[root@test1 ~]# cat /sys/block/sda/queue/scheduler 
noop anticipatory [deadline] cfq 
已經是deadline了



四)ionice

ionice可以更改任務的類型和優先級,不過只有cfq調度程序可以用ionice.
有三個例子說明ionice的功能:
采用cfq的實時調度,優先級為7
ionice -c1 -n7  -ptime dd if=/dev/sda1 f=/tmp/test bs=2M count=300&
采用缺省的磁盤I/O調度,優先級為3
ionice -c2 -n3  -ptime dd if=/dev/sda1 f=/tmp/test bs=2M count=300&
采用空閑的磁盤調度,優先級為0
ionice -c3 -n0  -ptime dd if=/dev/sda1 f=/tmp/test bs=2M count=300&

ionice的三種調度方法,實時調度最高,其次是缺省的I/O調度,最后是空閑的磁盤調度.
ionice的磁盤調度優先級有8種,最高是0,最低是7.
注意,磁盤調度的優先級與進程nice的優先級沒有關系.
一個是針對進程I/O的優先級,一個是針對進程CPU的優先級.

 
磁盤讀寫能力測試
 
Linux服務器裝好系統之后,想要知道硬盤的讀寫是否能滿足服務的需要,如果不滿足硬盤的IO就是服務的一個瓶頸。所以我們需要測試硬盤的讀寫速度,測試的方法很多,下面是使用Linux 自帶的dd命令測試硬盤的讀寫速度。
 
time有計時作用,dd用於復制,從if讀出,寫到of。if=/dev/zero不產生IO,因此可以用來測試純寫速度。同理of=/dev/null不產生IO,可以用來測試純讀速度。bs是每次讀或寫的大小,即一個塊的大小,count是讀寫塊的數量。
 
測/data目錄所在磁盤的純寫速度:
 
[root@nagios ~]# time dd if=/dev/zero of=/var/test bs=8k count=1000000
 1000000+0 records in
 1000000+0 records out
 8192000000 bytes (8.2 GB) copied, 52.5749 seconds, 156 MB/s
 
real    0m55.841s
 user    0m0.507s
 sys    0m15.706s
 
##紅色部分是因為使用了time命令才顯示的,因此需要time命令來計算復制的時間。
 
測/data目錄所在磁盤的純讀速度:
 
[root@nagios ~]# time dd if=/var/test of=/dev/null bs=8k count=1000000
 1000000+0 records in
 1000000+0 records out
 8192000000 bytes (8.2 GB) copied, 49.0088 seconds, 167 MB/s
 
real    0m49.025s
 user    0m0.559s
 sys    0m6.383s
 
測讀寫速度:
 
[root@nagios ~]# time dd if=/var/test of=/tmp/test bs=8k count=1000000
 125000+0 records in
 125000+0 records out
 8192000000 bytes (8.2 GB) copied, 129.239 seconds, 63.4 MB/s
 
real    2m9.251s
 user    0m0.114s
 sys    0m21.494s
 

備注:理論上測試復制量越大測試結果越准確。
 
正常測試的時候可能不止測試一邊,可能會需要很多遍求取平均值,這個測試結果在普通的重定向是沒有效果的 之后 google 了一下 用下面的方式重定向到一個文件
 
dd if=/dev/zero of=/var/test bs=8k count=1000000  2>> info
 
這樣測試的結果就到info文件里面了

 

hdparm 測試硬盤讀寫速度

 


安裝:yum install hdparm

語  法:hdparm [-CfghiIqtTvyYZ][-a <快取分區>][-A <0或1>][-c <I/O模式>][-d <0或1>][-k <0或1>][-K <0或1>][-m <分區數>][-n <0或1>][-p <PIO模式>][-P <分區數>][-r <0或1>][-S <時間>][-u <0或1>][-W <0或1>][-X <傳輸模式>][設備]

補充說明:hdparm可檢測,顯示與設定IDE或SCSI硬盤的參數。

參  數:
-a<快取分區> 設定讀取文件時,預先存入塊區的分區數,若不加上<快取分區>選項,則顯示目前的設定。
-A<0或1> 啟動或關閉讀取文件時的快取功能。
-c<I/O模式> 設定IDE32位I/O模式。
-C 檢測IDE硬盤的電源管理模式。
-d<0或1> 設定磁盤的DMA模式。
-f 將內存緩沖區的數據寫入硬盤,並清楚緩沖區。
-g 顯示硬盤的磁軌,磁頭,磁區等參數。
-h 顯示幫助。
-i 顯示硬盤的硬件規格信息,這些信息是在開機時由硬盤本身所提供。
-I 直接讀取硬盤所提供的硬件規格信息。
-k<0或1> 重設硬盤時,保留-dmu參數的設定。
-K<0或1> 重設硬盤時,保留-APSWXZ參數的設定。
-m<磁區數> 設定硬盤多重分區存取的分區數。
-n<0或1> 忽略硬盤寫入時所發生的錯誤。
-p<PIO模式> 設定硬盤的PIO模式。
-P<磁區數> 設定硬盤內部快取的分區數。
-q 在執行后續的參數時,不在屏幕上顯示任何信息。
-r<0或1> 設定硬盤的讀寫模式。
-S<時間> 設定硬盤進入省電模式前的等待時間。
-t 評估硬盤的讀取效率。
-T 評估硬盤快取的讀取效率。
-u<0或1> 在硬盤存取時,允許其他中斷要求同時執行。
-v 顯示硬盤的相關設定。
-W<0或1> 設定硬盤的寫入快取。
-X<傳輸模式> 設定硬盤的傳輸模式。
-y 使IDE硬盤進入省電模式。
-Y 使IDE硬盤進入睡眠模式。
-Z 關閉某些Seagate硬盤的自動省電功能。
測試硬盤的讀取速度:

普通磁盤測試:

# hdparm -t /dev/sda
/dev/sda:
Timing buffered disk reads: 316 MB in 3.02 seconds = 104.71 MB/sec

# hdparm -T /dev/sda
/dev/sda:
Timing cached reads: 19328 MB in 1.99 seconds = 9691.24 MB/sec
RAID0測試(兩塊盤):

# hdparm -t /dev/sdb
/dev/sdb:
Timing buffered disk reads: 622 MB in 3.01 seconds = 206.89 MB/sec

# hdparm -T /dev/sdb1
/dev/sdb1:
Timing cached reads: 19632 MB in 1.99 seconds = 9844.20 MB/sec
RAID0測試(三塊盤):

# hdparm -t /dev/sdb
/dev/sdb:
Timing buffered disk reads: 846 MB in 3.00 seconds = 281.54 MB/sec


# hdparm -T /dev/sdb
/dev/sdb:
Timing cached reads: 18412 MB in 1.99 seconds = 9229.67 MB/sec
RAID0測試(四塊盤)

/dev/sdb:
Timing cached reads: 19608 MB in 1.99 seconds = 9832.76 MB/sec

Timing buffered disk reads: 860 MB in 3.00 seconds = 286.35 MB/sec
另外ARID卡測試速度后,每次會警告:

HDIO_DRIVE_CMD(null) (wait for flush complete) failed: Inappropriate ioctl for device
參考測試速度方法:time cp -a data2 data2

 
 
如何判斷IO達到瓶頸了
 
  如果磁盤IO確實比較大的話,是數據庫,可以進行讀寫分離或者分庫操作,減小磁盤壓力,文件的話,可以利用raid來減輕壓力

查看linux服務器硬盤IO訪問負荷的方法:

首先 、用top命令查看

top - 16:15:05 up 6 days, 6:25, 2 users, load average: 1.45, 1.77, 2.14
Tasks: 147 total, 1 running, 146 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.2% us, 0.2% sy, 0.0% ni, 86.9% id, 12.6% wa, 0.0% hi, 0.0% si
Mem: 4037872k total, 4003648k used, 34224k free, 5512k buffers
Swap: 7164948k total, 629192k used, 6535756k free, 3511184k cached

查看12.6% wa

IO等待所占用的CPU時間的百分比,高過30%時IO壓力高

其次、 用iostat -x 1 10

avg-cpu: %user %nice %sys %iowait %idle
0.00 0.00 0.25 33.46 66.29

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdb 0.00 1122 17.00 9.00 192.00 9216.00 96.00 4608.00 123.79 137.23 1033.43 13.17 100.10
sdc 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

查看%util 100.10 %idle 66.29

如果 %util 接近 100%,說明產生的I/O請求太多,I/O系統已經滿負荷,該磁盤可能存在瓶頸。

idle小於70% IO壓力就較大了,一般讀取速度有較多的wait.

同時可以結合vmstat 查看查看b參數( 等待資源的進程數 )

vmstat -1


硬盤操作查看工具 iotop

如果你知道有程序在磨你的硬盤,但是你又不能確定是哪一個程序在磨你的硬盤,那么就用 iotop來幫助你吧。

在Ubuntu里安裝命令是: sudo apt-get install iotop

安裝好之后在終端輸入:iotop就可以了

 

 

下面來說一具體運用:

可以用左右箭頭操作,按 r 是相反方向,按 o 是動態切換

用法 iotop -參數

–version 查看版本信息的

-h, –help 查看幫助信息的

-o, –only 只顯示在划硬盤的程序
-b, –batch 批量處理 用來記錄日志的

-n NUM 設定循環幾次

-d SEC, –delay=SEC 設定顯示時間間隔

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM