機械硬碟隨機IO慢的超乎你的想象

2022-07-12 03:12:13 字數 3428 閱讀 8663

大家都知道硬碟的隨機io很慢,但是比順序io慢多少呢,不知道你是否有過數字上的直接對比。今天我來實際壓測對比一下磁碟在順序io和隨機io不同場景下的效能資料表現。通過今天的實驗資料,你將能深刻理解資料庫事務中為什麼要用日誌的方式來實現,為什麼索引中要用節點更大的b+樹。

對於任何儲存系統,效能指標無非就是頻寬、延遲或iops。我的測試機器的硬碟配置是乙個由7塊300g萬轉機械磁碟組成的raid5,壓測工具使用的fio,壓測過程中,我們固定幾個引數:

然後再對另外的引數進行動態調整,然後進行多次對比測試

我們先來看一下順序讀取情況下,在該磁碟陣列的頻寬表現,見圖1:

可以看到,當io size比較小的時候,即使是順序發起連續io請求,頻寬表現也不算給力,只有不到20mb/s。隨著io size增加的時候,頻寬也上來了,最大能夠達到1.2gb多。

大家注意看下在nora情況下,在128k增加到256k的時候,頻寬突然增加了很多,這是為啥呢?秘密在於我的raid陣列裡的條帶大小是128k,當io size為256k的時候,磁碟陣列才開始真正並行工作了。io size小的時候,並不能發揮多盤優勢。

/opt/megaraid/megacli/megacli64 -ldinfo -lall -aall

......

strip size : 128 kb

另外就是對於順序io的情況,ra預取也能起到一些作用,在io size在64k的時候就能夠達到1.2gb的頻寬。

我們再來看延遲,見圖2:

我們圖中的單位是微秒-us,在《簡單聊聊磁碟分割槽》中,我對磁碟耗時進行過理論上的估算,磁碟耗時主要在兩個地方:

旋轉延遲:萬轉磁碟這個延遲大概0-6ms

為什麼在圖2實驗結果裡,延時卻都很低,在io size為512的時候,平均竟然只有30us左右?其實順序io的情況下,raid卡快取命中率很高,其實絕大部分的讀請求並沒有穿透到讓磁碟的機械軸來工作。

我們再來看iops,見圖3:

在io請求size正好為1個扇區大小的時候,磁碟陣列的iops表現最高,達到了3w多次每秒。當io size增加的時候,iops在逐步下降,但這時候,其實磁碟的吞吐是在增加的。

彙總一下,磁碟陣列在順序io的情況下表現還是很不錯的,原因有三個:

我們作為開發者使用磁碟的時候,可能不一定能保證永遠都能讓它工作在最舒服的狀態,有些時候可能也必須得讓它進行隨機訪問。所以我們今天也試一下我的磁碟陣列在隨機情況下的表現,對於fio工具來說只需要設定rw引數為randread既可。不過io size我只測試到了128就停了,因為再大了就越像順序io了。

我們還是先來看頻寬,見圖4:

機械硬碟即使是組成了raid陣列,而且還有快取,貌似對隨機io也無可奈何。在隨機io的情況下,頻寬吞吐糟糕透了,在io size比較小的時候,竟然只有零點幾兆每秒。

我們再來看延時,見圖5:

隨機情況下延時基本都5ms左右,這就和我們前面理論上的計算結果對上了。隨機訪問導致更多的請求真正穿透到了機械軸上。

再來看iops,這個指標也很差,也就是200左右吧。這個資料和圖5的延遲形成了呼應,處理一次請求5ms左右,那麼1秒可不就是只能處理200次左右麼。所以硬碟廠家們天天給你吹風,說他家磁碟iops能達到幾萬幾萬。但是他們從來閉口不提隨機io情況下,其實特麼的只有200。

大家看到了我的萬轉機械硬碟組成raid5陣列,在順序條件最好的情況下,頻寬可以達到1gb/s以上,平均延時也非常低,最低只有20多us。但是在隨機io的情況下,機械硬碟的短板就充分暴露了,零點幾兆的頻寬,將近5ms的延遲,iops只有200左右。其原因是因為

理解了磁碟順序io時候的幾十m甚至乙個gb的頻寬,隨機io這個真的是太可憐了。

從上面的測試資料中我們看到了機械硬碟在順序io和隨機io下的巨大效能差異。在順序io情況下,磁碟是最擅長的順序io,再加上raid卡快取命中率也高。這時頻寬表現有幾

十、幾百m,最好條件下甚至能達到1gb。iops這時候能有2-3w左右。 到了隨機io的情形下,機械軸也被逼的跳來跳去尋道,raid卡快取也失效了。頻寬跌到了1mb以下,最低只有100k,iops也只有可憐巴巴的200左右。

如果你真正理解了以上實驗中的資料,就能理解很多任務程實踐中的許多的事情。

複製資料夾:我們都知道,在複製乙個資料夾的時候,如果這個資料夾裡面包含了許多堆碎檔案,這時候複製起來非常慢。原因就是這時候機械硬碟大概率都是在隨機io。怎麼提高複製速度呢?很簡單,就是把它們先打乙個包。打包之後這個資料夾就變成乙個大檔案了,這時候再複製的話,磁碟就是執行的最擅長的順序io了,所以會快很多。

資料庫事務:所有的資料庫在實現事務的時候,都要保證寫資料落盤成功才能返回。但為什麼他們幾乎都是落盤到自己的事務日誌檔案裡去就返回成功的,而不是直接寫入到資料表檔案裡。這背後的原因還是磁碟讀寫效能問題,事務只需要保證資料落地成功就可以,至於寫到**並不重要。寫到資料檔案中的話大概率就變成隨機io了。如果寫到乙個日誌檔案中,就是地地道道的順序io,效能就發揮到極致。

mysql的b+樹:在上面的資料中大家還可以看到,無論是順序io還是隨機io,只要增加每次io的單位,效能都會**。理解了這個,你就能真正理解為什麼mysql是採用b+樹當索引,而不是用其它的樹了(比如二叉樹)。因為b+樹的節點更大,io起來會讓磁碟工作更舒服一些。

最後結尾我想分享乙個5年前我在工程中實際效能優化的案例。當時接手了乙個系統,要用數以百萬級的使用者imei,到mysql中去查詢使用者的另乙個字串id(clientid)資料。前開發的實現方式是傳統的分批進行mysql語句查詢。這種實現下,且不說多次的網路rtt耗時,單說mysql查詢,即使是有索引這時候也得需要進行大量的隨機io,因為使用者imei是隨機分布的。我採用的優化方式也非常簡單,直接把mysql使用者整張使用者表一次性通過順序io的方式讀出來,load到記憶體中。在記憶體中用hashtable組織好,通過hash的方式進行快速查詢。最終耗時優化掉了90%以上。

開發內功修煉之硬碟篇**:

為什麼硬碟隨機讀寫超慢,而順序讀寫超快

我們都知道硬碟順序讀寫很快,像hdd硬碟都能達到20萬每秒的iops,而隨機讀寫按照7200轉的hdd的iops在100左右,為什麼那?要搞清楚這個問題需要我們先來對磁碟有乙個基本的認識 一 磁碟的基本了解 基本的基本組成部分,磁碟主要有盤面 磁頭 懸臂組成如下圖 柱面 有上下大小相等的盤面的扇面組...

機械硬碟的延時

硬碟一次讀寫的時間由兩個部分組成 time latency data size bandwidth latency主要由平均硬碟尋道時間和平均硬碟轉動延遲組成。硬碟有多個磁碟片組成,每個磁碟又由n個同心的track構成,每個track又分成m個sector。磁頭移動到目標track,就是尋道的時間 ...

固態硬碟和機械硬碟的區別

1.固態硬碟和機械硬碟的區別 1 固態硬碟solid state disk 固態硬碟是由控制單元和固態儲存單元組成的硬碟。儲存單元負責儲存資料,控制單元負責讀取 寫入資料 固態硬碟的介質分為兩種,一種是採用快閃儲存器 flash memory 作為介質,另外一種是採用dram作為儲存介質,目前絕大多...