【IO】IO系統效能之一:衡量效能的幾個指標

xysoul_雲龍發表於2021-12-30

    作為一個資料庫管理員,關注系統的效能是日常最重要的工作之一,而在所關注的各方面的效能中, IO效能卻是最令人頭痛的一塊,面對著各種生澀的引數和令人眼花繚亂的新奇術語,再加上儲存廠商的忽悠,總是讓我們有種雲裡霧裡的感覺。本系列文章試圖從基本概念開始對磁碟儲存相關的各種概念進行綜合歸納,讓大家能夠對IO效能相關的基本概念,IO效能的監控和調整有個比較全面的瞭解。

    在這一部分裡我們先捨棄各種結構複雜的儲存系統,直接研究一個單獨的磁碟的效能問題,藉此瞭解衡量IO系統效能的各個指標以及之間的關係。需要注意的是,本文探討的僅限於磁碟IO效能,網路IO效能不考慮在內

    1. 幾個基本概念

    在研究磁碟效能之前,我們必須先了解磁碟的結構,以及工作原理。不過在這裡就不再重複說明了,關於 磁碟結構工作原理的資訊可以參考維基百科上面的相關詞條————Hard disk drive(英文)和硬碟驅動器(中文)

    1)  讀寫IO(Read/Write IO)操作

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

    2)  單個IO操作

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

    3)  隨機訪問(Random Access)與順序訪問(Sequential Access)

    隨機訪問指的是本次IO所給出的扇區地址和上次IO給出的扇區地址相差比較大,這樣的話磁頭在兩次IO操作之間需要作比較大的移動操作才能重新開始讀/寫資料。相反的,如果當次IO給出的扇區地址與上次IO結束時的扇區地址一致或者是接近的話,那麼磁頭就能很快的開始這次IO操作,這樣的多個IO操作稱為連續訪問。因此,儘管相鄰的兩次IO操作在同一時刻發出,但如果他們請求的扇區地址相差很大的話也只能稱為隨機訪問,而非順序訪問。

    4)  順序IO模式(Queue Mode)與併發IO模式(Burst Mode)

    磁碟控制器可能會一次對磁碟組發出一連串的IO指令,如果磁碟組一次只能執行一個IO指令時稱為順序IO; 當磁碟組能同時執行多個IO指令時,稱為併發IO。併發IO只能發生在由多個磁碟組成的磁碟上,單塊磁碟只能一次處理一個IO命令。

    2. 單個IO的大小(IO Chunk Size)

    熟悉資料庫的人都會有這麼一個概念,那就是資料庫儲存有個基本的塊大小(Block Size),不管是SQL Server還是Oracle,預設的塊大小都是8KB,就是資料庫每次讀寫都是以8KB為單位來進行的。那麼對於資料庫應用發出的固定8KB大小的單次讀寫,到了磁碟這一層面會是怎麼樣的情況呢? 就是對於讀寫磁碟來說,單個IO操作運算元據的大小是多少呢, 是不是也是一個固定的值?

    答案是不確定。首先作業系統為了提高IO的效能而引入了檔案系統快取(File System Cache),系統會根據請求資料的情況將多個來自IO的請求先放在快取裡面,然後再一次性的提交給磁碟,也就是說對於資料庫發出的多個8K資料塊的讀操作,有可能放在一個磁碟讀IO裡就處理了。

    還有對於有些儲存系統也是提供了快取(Cache)的,接收到作業系統的IO請求之後,也是會將多個作業系統的IO請求合併成一個來處理。不管是作業系統層面的快取還是磁碟控制器層面的快取,目的都只有一個,提高資料讀寫的效率。因此,每次單獨的IO操作大小都是不一樣的,它主要取決於系統對於資料讀寫效率的判斷。

    當一次IO操作大小比較小的時候,我們稱為小的IO操作。比如說1K、4K、8K這樣的;當一次IO操作的資料量比較大的時候,我們稱為大IO操作,比如32K、64K甚至更大。

    在我們說到塊大小(Block Size)的時候,通常我們會接觸到多個類似的概念,像我們上面提到的那個在資料庫裡面的資料最小管理單元, Oracle稱之為塊(Block),大小一般為8K, SQL Server稱之為頁(Page),一般大小也為8K。

    在檔案系統裡面,我們也能碰到一個檔案系統的塊(Block)。在現在很多的Linux系統中都是4K,它的作用其實跟資料庫裡面的塊/頁是一樣的,都是為了方面資料管理。但是說道單次IO的大小,跟這些塊的大小都是沒有直接關係的,在英文裡單次IO大小通常被稱為IO Chunk Size,不會說成IO Block Size的。

    3. IOPS(IO per Second)

    IOPS是指IO系統每秒所執行IO操作的次數,是一個重要的用來衡量系統IO能力的一個引數。對於單個磁碟組成的IO系統來說,計算它的IOPS不是一件很難的事情,只要我們知道了系統完成一次IO所需要的時間的話,我們就能推算出系統IOPS來。

    現在我們就來推算一下磁碟的IOPS,假設磁碟的轉速(Rotational Speed)為15K RPM,平均尋道時間為5ms,最大傳輸速率為40MB/s(這裡將讀寫速度視為一樣,實際會差別比較大)。

    對於磁碟來說一個完整的IO操作是這樣進行的: 當控制器對磁碟發出一個IO操作命令的時候,磁碟的驅動臂(Actuator Arm)帶讀寫磁頭(Head)離開著陸區(Landing Zone,位於內圈沒有資料的區域),移動到要操作的初始資料塊所在的磁軌(Track)的正上方,這個過程被稱為尋道(Seeking),對應消耗的時間被稱為 尋道時間(Seek Time); 但是找到對應磁軌還不能馬上讀取資料,這時候磁頭要等到磁碟碟片(Platter)旋轉到初始資料塊所在扇區(Sector)落在讀寫磁頭正上方之後才能開始讀寫資料,在這個等待碟片旋轉到可操作扇區的過程中消耗的時間稱為 旋轉延時(Rotational Delay); 接下來就隨著碟片的旋轉,磁頭不斷的讀/寫相應的資料塊,直到完成這次IO所需要操作的全部資料,這個過程稱為資料傳送(Data Transfer),對應的時間稱為 傳送時間(Transfer Time)。完成這三個步驟之後,一次IO操作也就完成了。

    Total = 尋道時間 + 旋轉延遲 + 傳送時間
    

    在我們看硬碟廠商的宣傳單的時候,我們經常能看到3個引數,分別是平均定址時間、碟片旋轉速度以及最大傳送速度,這三個引數就可以提供給我們計算上述三個步驟的時間。

    1) 第一個定址時間,考慮到被讀寫的資料可能在磁碟的任意一個磁軌,既有可能在磁碟的最內圈(定址時間最短),也可能在磁碟的最外圈(定址時間最長),所以在計算中我們只考慮平均定址時間,也就是磁碟引數中標明的那個平均 定址時間,這裡就採用當前最多的 15K RPM硬碟的5ms。

    2) 第二個旋轉延時,和定址一樣,當磁頭定位到磁軌之後有可能正好在要讀寫扇區之上,這時候是不需要額外延時就可以立刻讀寫到資料,但是最壞的情況卻是要磁碟旋轉整整一圈之後磁頭才能讀取到資料,所以這裡我們也考慮的是平均旋轉延時,對於 15K RPM的磁碟就是(60s/15K)/2 = 2ms。(磁碟轉速單位一般為: 轉/每分鐘)

    3) 第三個傳送時間,磁碟引數提供給我們的最大傳輸速度,當然要達到這種速度是很有難度的,但是這個速度卻是 純讀寫磁碟的速度,因此只要給定了單次IO的大小,我們就知道磁碟需要花費多少時間在資料傳送上,這個時間就是IO Chunk Size /Max Transfer Rate。

    4. IOPS計算公式

    現在我們就可以得出這樣的計算單次IO時間的公式:

    IO Time = Seek Time + 60 sec/Rotational Speed /2 + IO Chunk Size / Transfer Rate
    

    於是我們可以這樣計算出:

    IOPS = 1/IO Time = 1/(Seek Time + 60 sec / Rotational Speed / 2 + IO Chunk Size / Transfer Rate)
    

    注:IOPS全稱為Input/Output Operations Per Second,大意是硬碟每秒的讀寫次數。一個硬碟的隨機讀取IOPS主要由其主控和介面決定。在測試硬碟隨機讀取效能上,大部分軟體會使用4KB大小的資料區塊作為測試基準。以希捷酷魚510系列固態硬碟為例,由於其搭載的主控支援NVMe 1.3協議,所以在4KB隨機讀取上可達到100096 IOPS,寫入上也高達896000 IOPS。

    對於給定不同的IO大小,我們可以得出下面的一系列資料:

    1)  IO大小為4K

    4K (1/7.1 ms = 140 IOPS) 5ms + (60sec/15000RPM/2) + 4K/40MB = 5 + 2 + 0.1 = 7.1

    2)  IO大小為8K

    8k (1/7.2 ms = 139 IOPS) 5ms + (60sec/15000RPM/2) + 8K/40MB = 5 + 2 + 0.2 = 7.2

    3)  IO大小為16K

    16K (1/7.4 ms = 135 IOPS) 5ms + (60sec/15000RPM/2) + 16K/40MB = 5 + 2 + 0.4 = 7.4

    4)  IO大小為32K

    32K (1/7.8 ms = 128 IOPS) 5ms + (60sec/15000RPM/2) + 32K/40MB = 5 + 2 + 0.8 = 7.8

    5)  IO大小為64K

    64K (1/8.6 ms = 116 IOPS) 5ms + (60sec/15000RPM/2) + 64K/40MB = 5 + 2 + 1.6 = 8.6

    從上面的資料可以看出,當單次IO越小的時候,單次IO所耗費的時間也越少,相應的IOPS也就越大。

    上面我們的資料都是在一個比較理想的假設下得出來的,這裡的理想情況就是磁碟要花費平均大小的 定址時間和平均的 旋轉延時,這個假設其實是比較符合我們實際情況中的隨機讀寫。在隨機讀寫中,每次IO操作的定址時間和旋轉延時都不能忽略不計,有了這兩個時間的存在,也就限制了IOPS的大小。現在我們考慮一種相對極端的順序讀寫操作,比如說在讀取一個很大的儲存連續分佈在磁碟上的檔案,因為檔案的儲存分佈是連續的,磁頭在完成一個讀IO操作之後,不需要重新的定址,也不需要旋轉延時,在這種情況下我們能得到一個很大的IOPS值,如下:

    4K (1/0.1 ms = 10000 IOPS) 0ms + 0ms + 4K/40MB = 0.1 8k (1/0.2 ms = 5000 IOPS) 0ms + 0ms + 8K/40MB = 0.2 16K (1/0.4 ms = 2500 IOPS) 0ms + 0ms + 16K/40MB = 0.4 32K (1/0.8 ms = 1250 IOPS) 0ms + 0ms + 32K/40MB = 0.8 64K (1/1.6 ms = 625 IOPS) 0ms + 0ms + 64K/40MB = 1.6

    相比第一組資料來說差距是非常大的,因此當我們要用IOPS來衡量一個IO系統效能的時候,我們一定要說清楚是在什麼情況下的IOPS,也就是要說明讀寫的方式 以及單次IO的大小,當然在實際當中,特別是在OLTP的系統,隨機的小IO讀寫是最有說服力的。

    下面給出一個目前機械硬碟與固態硬碟的讀寫速度的一個參考:

    1)  機械硬碟

    • 5400轉筆記本硬碟平均讀寫速度大致在60-90MB這個區間

    • 7200轉檯式機硬碟大致在130-190MB區間,10000轉的西數黑盤也在這個區間內

    • 10000轉和15000轉檯式機硬碟資料不詳

    2)  固態硬碟

    固態硬碟讀寫速度與容量成正比,目前市售的至少300MB+

    1TB固態硬碟普遍500MB+

    2013新Mac Pro採用PCIE連線方式的SSD可以達到700MB左右

    5. 傳輸速度/吞吐率

    現在我們要說的傳輸速度(另一個常見的說法是吞吐率)不是磁碟上所表明的最大傳輸速度或者說理想傳輸速度,而是磁碟在實際使用的時候從磁碟系統匯流排上流過的資料量。有了IOPS資料之後,我們是很容易就能計算出對應的傳輸速度來的。

    Transfer Rate = IOPS * IO Chunk Size

    還是上面的那一組IOPS資料,我們可以得出相應的傳輸速度如下:

    4K: 140 * 4K = 560K / 40M = 1.36% 8K: 139 * 8K = 1112K / 40M = 2.71% 16K: 135 * 16K = 2160K / 40M = 5.27% 32K: 116 * 32K = 3712K / 40M = 9.06%

    從上面可以看出,實際上的傳輸速度是很小的,對匯流排的利用率也是非常的小。

    這裡一定要明確一個概念,那就是儘管上面我們使用IOPS來計算傳輸速度,但是實際上傳輸速度和IOPS是沒有直接關係的。在沒有快取的情況下,它們共同的決定因素都是對磁碟系統的 訪問方式以及 單個IO大小。對磁碟進行隨機訪問的時候,我們可以利用IOPS來衡量一個磁碟系統的效能,此時的傳輸速度不會太大; 但是當對磁碟進行連續訪問時,此時的IOPS已經沒有了參考的價值,這個時候限制實際傳輸速度卻是磁碟的最大傳輸速度。因此在實際的應用當中,只會用IOPS來衡量小IO的隨機讀寫效能,而當要衡量大IO連續讀寫的效能的時候,就要採用傳輸速度而不能是IOPS了。

    6. IO響應時間

    最後來關注一下能直接描述IO效能的IO響應時間。IO響應時間也被稱為IO延時(IO Latency)。IO響應時間就是從作業系統核心發出的一個 或者 的IO命令到作業系統核心接收到IO回應的時間,注意不要和單個IO時間混淆了。單個IO時間僅僅指的是IO操作在磁碟內部處理的時間,而IO響應時間還要包括IO操作在IO等待佇列中所花費的等待時間。

    計算IO操作在等待佇列裡面消耗的時間有一個衍生於 利托氏定理(Little’s Law)的排隊模型 M/M/1模型可以遵循,由於排隊模型演算法比較複雜,到現在還沒有搞太明白(如果有誰對 M/M/1模型比較精通的話,歡迎給予指導),這裡就羅列一下最後的結果,還是上面計算的IOPS資料來說:

    8K IO Chunk Size (139 IOPS, 7.2 ms)   135 => 240.0 ms   105 => 29.5 ms   75 => 15.7 ms   45 => 10.6 ms 64K IO Chunk Size(116 IOPS, 8.6 ms)   135 => 沒響應了……   105 => 88.6 ms   75 => 24.6 ms   45 => 14.6 ms

    從上面的資料可以看出,隨著系統實際IOPS越接近理論的最大值,IO響應時間會成非線性的增長,越是接近最大值,響應時間就變得越大,而且會比預期超出很多。一般來說,在實際的應用中有一個70%的指導值,也就是說在IO讀寫的佇列中,當佇列大小小於最大IOPS的70%的時候,IO的響應時間增加會很小,相對來說讓人比較能接受,一旦超過70%,響應時間就會戲劇性的暴增,所以當一個系統的IO壓力超出最大可承受壓力的70%的時候就是必須要考慮調整或升級了。

    另外補充說一下這個70%的指導值也適用於CPU響應時間,這也是在實踐中證明過得。一旦CPU超過70%,系統將會變得受不了的慢。很有意思的東西。

    7. 附: Linux核心檔案系統block與硬碟sector關係

    在系統執行過程中,有時會遇到下面列印資訊,報告讀寫某個扇區錯誤

    kernel: end_request: I/O error, dev sdg, sector 2252148039 kernel: end_request: I/O error, dev sdc, sector 3297222879

    1、這個扇區(sector)的含義是什麼?和硬碟上的sector是一回事嗎?

    2、Sector和檔案系統中的Block有什麼關係?

    3、而在我們上層應用讀寫的是檔案內偏移量pos,pos與block/Sector之間有什麼關係?

    linuxops-block-sector

    檔案偏移量pos,是針對檔案本身而言,即檔案內的偏移。

    Block是檔案系統上的概念,一般檔案系統block大小為4K。

    Sector是磁介質硬碟最小單元,一般為512位元組。

    Block值一般與sector值是不相等的.



    [參看]:

    1. IO系統效能之一:衡量效能的幾個指標

    2. 如何讓linux伺服器磁碟io效能翻倍

    3. 磁碟效能評價指標—IOPS和吞吐量

    原文出處不詳,轉自:

    來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29487349/viewspace-2850041/,如需轉載,請註明出處,否則將追究法律責任。

    相關文章