天天看點

隊列深度對IO性能的影響

原文:https://www.modb.pro/db/43710

幾年前一個客戶的Oracle資料庫經常HANG,老白幫他分析了一下,結論是存儲老化,性能不足以支撐現有業務了。正好使用者手頭有個華為S5600T正好從核心系統中換下來放着沒用,就把這個存儲換上去了。換了新存儲後,系統總體确實有所改善。資料庫不會動不動就HANG住,不會出現系統HANG的問題了,但是還是覺得比較慢。出問題時候的AWR報告的片段如下:

隊列深度對IO性能的影響

從負載上看,每秒的REDO SIZE 37M,還是很高的。邏輯讀的數量不大,不過BLOCK CHANGES很高,實體寫高達1萬+,超過80M/秒,系統的寫壓力比較大。從這個系統上看,應該是存在大批量的資料寫入操作。接下來看看命中率的情況:

隊列深度對IO性能的影響

命中率情況還是不錯的,因為主要是寫操作,是以DB CACHE的命中率也不高,從上面的LOAD PROFILE看,實體讀實際上也不大,每秒不到20M。再來看看TOP EVENT:  

隊列深度對IO性能的影響

可以看出,讀寫操作的平均延時超過50毫秒,肯定是存在性能問題的。從AWR資料上看,很明顯,本系統是一個寫IO很大的系統,每秒REDO的量達到了 36M/秒以上,每秒的實體寫超過1萬,這在普通的Oracle資料庫系統中是比較少見的。從主要等待事件上看,也主要集中在IO上,從WAIT CLASS分類看,USER I/O也排在第一位,平均等待時間為59MS,SYSTEMI/O的平均等待也達到40MS,從這些名額上看IO是明顯存在問題的。 

既然IO存在明顯的問題,那麼我們就需要馬上采集下作業系統IO的情況:

APE:/ # sar -d 3 2AIX APE 3 5 00CD36454C00
System configuration: lcpu=32 drives=111 mode=Capped
14:52:11 device %busy avque r+w/s Kbs/s avwait avserv
14:52:14
hdisk44    49 0.0     85   4096  10.0   6.0
hdisk43    65 0.1    138   7329  15.2   4.6
hdisk39    99 0.2    149   8589  40.6   6.7
hdisk38    30 0.8    303   3081  86.5  1.0
hdisk40    99 0.5    210  11196 60.9   4.7
hdisk42    99 0.9    346  13998  76.2    2.9      

從上述名額上看,IOPS和吞吐量都不算太高,但是平均響應時間(avwait+avserv)确實很高,達到幾十毫秒。這和AWR報告看到的資料是吻合的。于是找存儲工程師參與分析。存儲管理者認為存儲沒問題,負載很輕,從存儲監控上看到的響應時間也很正常,在幾個毫秒。這恐怕是DBA經常遇到的問題了,到底是存儲工程師在推诿呢還是實際情況就是這樣的,存儲沒問題,但是OS層面表現出慢呢?對于sar的資料,很多DBA總是先去看busy%這個名額,一看很多盤都已經是99% busy了,那可不得了了,存儲出現瓶頸了。實際上對于現在的系統而言,busy%這個名額的可參考性并不大,後面的名額更能看出問題。Avque指的是平均隊列的長度,有多少IO在隊列中等待。再後面一列是IOPS,再後面是吞吐量,最後兩列一列是平均等待時間,也就是在隊列中等待IO的時間,和平均服務時間,也就是IO請求發出後,從後端傳回的時間。我們通過這些名額實際上是可以區分IO等待是在前端系統端還是後端存儲端的。AVSERV是存儲到OS之間的端到端服務時間,從上面的名額上看,确實也不大,隻有幾個毫秒,是以說存儲工程師的說法可能是對的,存儲端并不慢。而avwait是IO在前端的等待時間,這個名額是相當高的,這說明很可能IO并沒有下到存儲上,而是在前端OS層面出現了等待。對于AIX系統而言,這個等待很大可能是和QUEUE_DEPTH參數設定不當有關的。為了進一步确認是否QUEUE_DEPTH不足引起了問題,在AIX系統上,可以用iostat–D去分析:

APE:/ # iostat -D
System configuration: lcpu=32 drives=111 paths=4 vdisks=0
hdisk44 xfer: %tm_act  bps   tps  bread bwrtn
21.9  4.1M 160.3   2.1M  2.0M
read:  rps  avgserv  minserv maxserv timeouts fails
28.8   5.6         0.1   1.2S       0    0
write: wps avgserv minserv maxserv timeouts fails
131.5   0.4     0.2    1.7S     0      0
queue: avgtime mintime maxtime avgwqsz avgsqsz sqfull
68.1    0.0    9.2S    12.0     0.0 160.3      

AIX系統的iostat -D是一個十分強大的IO性能分析工具。我們從read這行開始看,平均每秒28.8次讀,平均存儲上傳回的服務時間是5.6毫秒,最小是0.1毫秒,最大1.2秒,沒有逾時和錯誤(如果這兩列有值,就要十分關注了)。再來看write,平均每秒131.5,平均存儲的服務響應時間是0.4毫秒,這個值為什麼比讀的平均值小這麼多呢?大家印象裡的寫的成本要遠大于讀。實際上這是存儲系統的特點,因為讀資料的時候有可能命中在CACHE裡,也有可能需要從實體磁盤上去讀,是以根據命中率不同以及實體盤的性能不同,肯定都會比直接從CACHE中讀要慢一些,而寫入操作,隻要寫緩存沒有滿,那麼些IO的延時基本上等同于CACHE的寫IO延時,這是十分快的。大家可以關注最後一行的名額,是IO在隊列裡的延時情況,平均是68.1毫秒!!!最小是0毫秒,這個應該是不需要排隊直接從後端存儲擷取資料或者寫入資料了,最大高達9.2秒,平均隊列的深度12。大家關注下最後一個名額:sqfull的名額值,這是裝置的緩沖隊列滿的次數(累計值),如果這個名額大于0,說明QUEUE_DEPTH參數的設定是不足的,出現了大量IO隊列滿的情況。從上述資料我們可以比較肯定隊列等待可能是問題的主要原因了。下面我們來看看實際上HDISK的設定是什麼樣的:

APE:/ # lsattr -El hdisk44
clr_q no Device CLEARS its Queue on error True
location Location Label True
lun_id 0x4000000000000 Logical Unit Number ID
False
max_transfer 0x40000 Maximum TRANSFER Size
True
node_name 0x2100f84abf591cca FC Node Name
False
pvid 00cd36456aecb23e0000000000000000 Physical volume identifier
False
q_err yes Use QERR bit
True
q_type simple Queuing TYPE
True
queue_depth 1 Queue DEPTH
True
reassign_to 120 REASSIGN time out value
True
rw_timeout 30 READ/WRITE time out value
True
scsi_id 0xe0 SCSI ID
False
start_timeout 60 START unit time out valueTrue
ww_name 0x2008f84abf591cca FC World Wide Name
False      

什麼?QUEUE_DEPTH居然是1?其實也沒啥大驚小怪的,在AIX系統下,華為存儲的預設QUEUE_DEPTH就是1,HDS存儲的預設值是2,而IBM自己的存儲的預設值是8,也不知道是不是IBM在故意惡心友商。存儲工程師并沒有幫助使用者設定合理的值。那麼這個參數設定為多少合适呢?根據老白的經驗,如果跑Oracle這個參數至少設定為8,高負載的系統可以設定為更大的值,甚至32或者更高(LINUX上預設是128),不過也不是越高越好,要看你的存儲的能力,如果這個參數很大,存儲沒那麼強的能力,也是沒用的,需要一個比對。既然發現了問題,那麼果斷的将參數調整為24,我們來看看優化後的效果,将QUEUE_DEPTH加大到24,再看AWR資料:

隊列深度對IO性能的影響

看上去IO的性能是不是好了很多,REDO量也上去了,從每秒37M提高到57M左右。其實這時候IO還是有問題,現在壓力下放到存儲上,存儲上看到明顯的性能問題了。下面可以進一步優化,比如QUEUE DEPTH是不是還可以再加大。另外資料能否存放到更多的盤上。給客戶的建議是再多配置設定2-3個RAID 組,把部分資料分散到多個RAID 組上。實際上隊列深度以前一直是困擾小型機上IO性能的一個問題。這個參數設定太小會有排隊問題,設定太大也并不一定好,如果你的後端存儲能力不足,而設定的隊列深度太大,最終整體IO性能也不見得好。LINUX上,隊列深度預設是128,通過LINUX的排程政策來智能化排程,是以這個問題在LINUX上不多見。不過如果後端存儲是高端的全閃存陣列,那麼128的隊列深度還是不能發揮出後端存儲的能力的,這時候我們還是需要調整隊列深度的。

繼續閱讀