前段時間,發生了一個問題引起了我對IO隊列深度的研究。
存儲服務器中linux kernel的mpt2sas驅動模塊,將max_queue_depth設置為1024時,引起系統加載驅動時卡死,而調整為512則沒問題。
后來看了很多這方面的資料,終於弄明白了。
我們為了追求系統的性能,往往將max_queue_depth設置的很大。但是並不是越大對性能越有幫助。
以下內容全部出自轉載,我偷下懶!
(1)
探秘I/O隊列對磁盤性能的影響
轉載請在文首保留原文出處:EMC中文支持論壇https://community.emc.com/go/chinese
介紹
信息傳輸過程中數據通常暫存於磁盤隊列。實驗表明,隨着服務器性能的不斷提高,磁盤I/O隊列常常成為影響磁盤響應速度的首要瓶頸。本文以AIX系統為例,描述了I/O隊列在磁盤中的工作原理、監測命令,以及如何對其進行優化以提升磁盤性能。
使用I/O隊列的意義:
為何要對磁盤I/O進行並行處理呢?主要目的是提升應用程序的性能。這一點對於多物理磁盤組成的虛擬磁盤(或LUN)顯得尤為重要。如果一次提交一個I/O,雖然響應時間較短,但系統的吞吐量很小。相比較而言,一次提交多個I/O既縮短了磁頭移動距離(通過電梯算法),同時也能夠提升IOPS。假如一部電梯一次只能搭乘一人,那么每個人一但乘上電梯,就能快速達到目的地(響應時間),但需要耗費較長的等待時間(隊列長度)。因此一次向磁盤系統提交多個I/O能夠平衡吞吐量和整體響應時間。
理論上,磁盤的IOPS取決於隊列長度÷平均IO響應時間。假設隊列長度為3,平均IO響應時間是10ms,則最大吞吐量是300 IOPS。
IO隊列位於何處:
以AIX系統為例,從應用層到磁盤物理層的IO堆棧如下所示,IO按照從上至下的順序遍歷堆棧:
- 應用程序層
- 文件系統層(可選)
- LVM設備驅動層(可選)
- SDD或SDDPCM或其他多路徑驅動層(如果使用)
- hdisk設備驅動層
- adapter設備驅動層
- 磁盤接口層
- 磁盤子系統層
- 磁盤層
AIX在每一層堆棧都會監測IO,因此堆棧的每一層都有IO隊列。通常,如果當前各層執行的IO 超過了隊列長度所限制的最大數量,這些IO將暫存於等待隊列中,直至獲取申請資源。在文件系統層,文件系統緩存限制了各文件系統的最大可執行IO數量。 LVM設備驅動層,可執行的最大IO數量受hdisk緩存的限制。在SDD層,如果dpo設備的qdepth_enable屬性設置成yes,則會建立 IO隊列,但也有些版本無法設置隊列。SDDPCM在將IO發送至磁盤設備驅動層之前沒有進行隊列處理。hdisk通過queue_depth參數設置最大響應IO數量, 而FC適配層的參數為num_cmd_elems。磁盤子系統層有IO隊列,單塊物理磁盤可接收多個IO請求但一次只能處理一個IO。
IO隊列監測命令:
以AIX為例,AIX 5.3及以上版本,可用iostat和sar –d命令監測hdisk隊列,iostat -D命令輸出如下:
hdisk6 xfer: %tm_act bps tps bread bwrtn
4.7 2.2M 19.0 0.0 2.2M
read: rps avgserv minserv maxserv timeouts fails
0.0 0.0 0.0 0.0 0 0
write: wps avgserv minserv maxserv timeouts fails
19.0 38.9 1.1 190.2 0 0
queue: avgtime mintime maxtime avgwqsz avgsqsz sqfull
15.0 0.0 83.7 0.0 0.0 136
這里,avgwqsz是平均等待隊列長度,avgsqsz是平均響應隊列長度。在等待隊列中花費的平均等待時間是avgtime。sqfull值代表每秒鍾向已滿隊列提交的IO數。對於有cache的磁盤子系統,IO響應時間會有所不同。iostat –D命令顯示的是系統從啟動后的統計數據。
從應用程序的角度來看,處理IO的總時間是響應時間加上在hdisk等待隊列中的時間。
sar –d命令輸出如下:
16:50:59 device %busy avque r+w/s Kbs/s avwait avserv
16:51:00 hdisk1 0 0.0 0 0 0.0 0.0
hdisk0 0 0.0 0 0 0.0 0.0
avwait和avserv分別是花費在等待隊列和響應隊列的時間,avque在AIX 5.3以上版本中,代表等待隊列中的平均IO數量。
優化方法:
首先,不應盲目增加以上隊列參數值。這樣有可能造成磁盤子系統過載或在啟動時引起設備配置報錯。因此,僅增加hdisk 的queue_depths值並不是最好的方法,而應該同時調整可提交最大IO數量。當queue_depths和發送至磁盤子系統的IO數量同時增加 時,IO響應時間可能會增加,但同時吞吐量也得到了提升。當IO響應時間接近磁盤超時時間,則說明所提交IO超過了磁盤能夠處理的界限。如果看到IO超時 並在錯誤日志中報出IO無法完成,說明可能有硬件問題,或需要縮短隊列。
調整queue_depths的一條法則是:對於隨機讀寫或隊列未滿的情況,如果IO響應時間超過15ms,就不能再增加queue_depths值。一旦IO響應時間增加,瓶頸就從磁盤和adapter隊列轉移至磁盤子系統。調整隊列長度應依據:1)實際應用程序產生的IO請求數,2)使用測試工具以觀察磁盤子系統的處理能力。其中,1)為主要依據。
IO隊列有以下四種狀態:
- 隊列已滿,IO等在hdisk或adapter驅動層
- 隊列未滿,IO響應時間短
- 隊列未滿,IO響應時間長
- 隊列未滿,IO提交速度快於存儲處理速度並導致IO丟失
我們需要把隊列調整為2或3的狀態。情況3表明瓶頸不在hdisk驅動層,而很有可能在磁盤子系統自身,也有可能位於adapter驅動層或SAN。
第4種情況是應該避免的。受限於存儲IO請求和數據的內存大小,所有磁盤和磁盤子系統都有IO執行數量的限制。當存儲丟失IO時,主機端超時,IO將被重新提交,同時等待該IO的事件將被暫停。CPU為了處理IO多做了很多事情,這種情況應該避免。如果IO最終失敗,將會導致應用程序崩潰或更嚴重的結果。所以必須仔細確認存儲的處理極限。
合理的平均IO響應時間:
假設隊列中沒有IO,一次讀操作將會占據0至15ms,取決於尋址時間,磁盤轉速,以及數據傳輸時間。之后數據從存儲移動至主機。有時數據位於磁盤讀緩存,這種情況下IO響應時間約為1ms。對於大型磁盤系統在正常工作狀態下,平均IO響應時間約為5-10ms。當隨機讀取小數據耗時超過15ms時,表明存儲較為繁忙。
寫操作通常將數據寫入cache中,平均耗時不到2.5ms。但是也有例外:如果存儲同步將數據鏡像至遠端,寫操作將耗費更長時間。如果寫入數據量較大(多於64KB)則數據傳輸時間會顯著增加。沒有cache的情況下,寫時間的讀時間差不多。
如果IO是大塊順序讀寫,除了傳輸時間較長,IO會暫存於磁盤物理層隊列,IO響應時間遠高於平均值。例如:應用提交50個IO(50個64KB順序讀),最初幾個IO會獲得較快的響應時間,而最后一個IO必須等待其他49個完成,從而耗費很長的響應時間。
(2)
queue_depth參數大小 | |||
|
下面物理磁盤hdisk2是基於IBM存儲上的,做的raid 5,此盤屬於vg datavg中。
一,首先備份datavg.在生產環境作任何調整,一定要切記安全第一,備份是必不可少的。
#smit savevg
二,查看所需修改的hdisk2上queue_depth的值。
#lsattr -El hdisk2|grep queue_depth
三,首先umount datavg上的文件系統。
#umount /u2
四,vary off vg。
#varyoffvg datavg
五,刪除磁盤hdisk2.
#rmdev -l hdisk2
六,修改磁盤hdisk2 queue_depth參數.
#chdev -l hdisk2 -a queue_depth=16(此值為所需修改的具體queue_depth值) -P
七,增加磁盤hdisk2.
#mkdev -l hdisk2
八,vary on vg.
#varyonvg datavg
九,mount datavg上文件系統
#mount /u2
十,最后查看一下queue_depth參數是否修改成功。
#lsattr -El hdisk2|grep queue_depth
如上面查看queue_depth值已變成所需值,則整個過程完成。如有條件,最好能重?一下機器。應注意的是此值如設置不合理,可能會導致系統hang住,或死機現象。