簡述Linux磁碟IO

人艰不拆_zmc發表於2024-04-18

1、什麼是磁碟

  在講解磁碟IO前,先簡單說下什麼是磁碟。磁碟是可以持久化儲存的裝置,根據儲存介質的不同,常見磁碟可以分為兩類:機械磁碟和固態磁碟。

1.1 機械磁碟

  第一類,機械磁碟,也稱為硬碟驅動器(Hard Disk Driver),通常縮寫為 HDD。機械磁碟主要由碟片和讀寫磁頭組成,資料就儲存在碟片的環狀磁軌中。在讀寫資料前,需要移動讀寫磁頭,定位到資料所在的磁軌,然後才能訪問資料。顯然,如果 I/O 請求剛好連續,那就不需要磁軌定址,自然可以獲得最佳效能。這其實就是我們熟悉的,連續 I/O 的工作原理。與之相對應的,當然就是隨機 I/O,它需要不停地移動磁頭,來定位資料位置,所以讀寫速度就會比較慢。

1.2 固態磁碟

  第二類,固態磁碟(Solid State Disk),通常縮寫為 SSD,由固態電子元器件組成。固態磁碟不需要磁軌定址,所以,不管是連續 I/O,還是隨機 I/O 的效能,都比機械磁碟要好得多。

1.3 機械磁碟和固態磁碟對比

  其實,無論機械磁碟,還是固態磁碟,相同磁碟的隨機 I/O 都要比連續 I/O 慢很多,原因也很明顯。

  • 對機械磁碟來說,剛剛提到過的,由於隨機 I/O 需要更多的磁頭尋道和碟片旋轉,它的效能自然要比連續 I/O 慢。
  • 而對固態磁碟來說,雖然它的隨機效能比機械硬碟好很多,但同樣存在“先擦除再寫入”的限制。隨機讀寫會導致大量的垃圾回收,所以相對應的,隨機 I/O 的效能比起連續 I/O 來,也還是差了很多。
  • 此外,連續 I/O 還可以透過預讀的方式,來減少 I/O 請求的次數,這也是其效能優異的一個原因。很多效能最佳化的方案,也都會從這個角度出發,來最佳化 I/O 效能。

  此外,機械磁碟和固態磁碟還分別有一個最小的讀寫單位。

  • 機械磁碟的最小讀寫單位是扇區,一般大小為 512 位元組。
  • 而固態磁碟的最小讀寫單位是頁,通常大小是 4KB、8KB 等。

  如果每次都讀寫 512 位元組這麼小的單位的話,效率很低。所以,Linux檔案系統會把連續的扇區或頁,組成邏輯塊,然後以邏輯塊作為最小單元來管理資料。常見的邏輯塊的大小是 4KB,也就是說,連續 8 個扇區,或者單獨的一個頁,都可以組成一個邏輯塊。

1.4 按照介面進行磁碟分類

  除了可以按照儲存介質來分類,另一個常見的分類方法,是按照介面來分類,比如可以把硬碟分為 IDE(Integrated Drive Electronics)、SCSI(Small Computer System Interface) 、SAS(Serial Attached SCSI) 、SATA(Serial ATA) 、FC(Fibre Channel) 等。

  不同的介面,往往分配不同的裝置名稱。比如, IDE 裝置會分配一個 hd 字首的裝置名,SCSI 和 SATA 裝置會分配一個 sd 字首的裝置名。如果是多塊同型別的磁碟,就會按照 a、b、c 等的字母順序來編號。

1.5 磁碟架構

  除了磁碟本身的分類外,當你把磁碟接入伺服器後,按照不同的使用方式,又可以把它們劃分為多種不同的架構。

  最簡單的,就是直接作為獨立磁碟裝置來使用。這些磁碟,往往還會根據需要,劃分為不同的邏輯分割槽,每個分割槽再用數字編號。比如我們前面多次用到的 /dev/sda ,還可以分成兩個分割槽 /dev/sda1 和 /dev/sda2。

  另一個比較常用的架構,是把多塊磁碟組合成一個邏輯磁碟,構成冗餘獨立磁碟陣列,也就是 RAID(Redundant Array of Independent Disks),從而可以提高資料訪問的效能,並且增強資料儲存的可靠性。

  根據容量、效能和可靠性需求的不同,RAID 一般可以劃分為多個級別,如 RAID0、RAID1、RAID5、RAID10 等。

  • RAID0 有最優的讀寫效能,但不提供資料冗餘的功能。
  • 而其他級別的 RAID,在提供資料冗餘的基礎上,對讀寫效能也有一定程度的最佳化。

  最後一種架構,是把這些磁碟組合成一個網路儲存叢集,再透過 NFS、SMB、iSCSI 等網路儲存協議,暴露給伺服器使用。(雲伺服器基本都是這種架構)

  其實在 Linux 中,磁碟實際上是作為一個塊裝置來管理的,也就是以塊為單位讀寫資料,並且支援隨機讀寫。每個塊裝置都會被賦予兩個裝置號,分別是主、次裝置號。主裝置號用在驅動程式中,用來區分裝置型別;而次裝置號則是用來給多個同類裝置編號。

2、什麼是磁碟IO 

  磁碟 I/O(Input/Output)是指計算機系統中涉及到磁碟的資料讀取和寫入操作。磁碟 I/O 是計算機與儲存裝置之間進行資料交換的一種重要方式。當計算機需要從磁碟讀取資料時,它會發起一個讀取請求,磁碟會尋找並將資料傳輸到計算機的記憶體中;當計算機需要將資料寫入磁碟時,它會發起一個寫入請求,將資料從記憶體寫入到磁碟中。

  我們都知道磁碟中儲存的程式,必須要載入到記憶體後才能執行,在磁碟中儲存的原始程式是無法直接執行的。這是因為,負責解析和執行程式內容的CPU,需要透過內部程式計數器來指定記憶體地址,然後才能讀出程式。即使CPU可以直接讀出並執行磁碟中儲存的程式,由於磁碟讀取速度慢,程式的執行速度還是會降低。總之,儲存在磁碟中的程式需要讀入到記憶體後才能執行。

  當程式在記憶體中執行時,如果需要載入一些文件資料或其他檔案,它會透過作業系統提供的檔案操作功能來實現。作業系統會提供一些函式或系統呼叫,允許程式訪問磁碟上的檔案並將其載入到記憶體中。程式可以使用檔案路徑指定要載入的檔案,然後透過作業系統提供的函式來開啟這些檔案。一旦檔案被開啟,程式就可以讀取其中的資料,並將其載入到記憶體中,以便後續處理。這就好像你在讀一本書,首先需要開啟書本,然後才能閱讀其中的內容。 當程式執行 I/O 操作時,CPU 將會暫時停止執行程式指令,而是會等待作業系統完成讀取檔案的工作。

  一旦CPU下發了讀取檔案的指令,它會等待作業系統通知檔案已經準備好,並將資料載入到記憶體中。CPU會繼續執行其他的指令,而不是空閒等待。一旦檔案資料載入到記憶體中,CPU 就會繼續執行程式的後續邏輯。在這個過程中,CPU 可能會執行其他指令,例如處理記憶體中的其他資料,執行其他執行緒的操作,或者執行程式的其他部分邏輯。 CPU 不會在等待期間完全停止執行。

注意 1:當CPU需要等待磁碟操作完成才能繼續處理資料時,它可能會進入空閒狀態,這時,CPU的使用率下降,因為它正在等待IO操作,而不是執行計算任務,這種現象說明了IO操作對CPU效能的重要影響。

注意 2:記憶體相當於CPU和硬碟之間的橋樑,當需要執行一個程式時,先將程式載入到記憶體中,然後CPU取記憶體中的指令和資料進行處理運算,處理完後將結果寫回記憶體,如果需要的話再將結果從記憶體寫入硬碟。

3、磁碟效能指標

說到磁碟效能的衡量標準,必須要提到五個常見指標,也就是我們經常用到的,使用率、飽和度、IOPS、吞吐量以及響應時間等。這五個指標,是衡量磁碟效能的基本指標:

  • IOPS(Input/Output Per Second),是指每秒磁碟處理的I/O請求數量。衡量儲存效能一般看吞吐量(傳輸速度)和IOPS兩個指標。
  • 吞吐量,是指每秒磁碟處理的 I/O 請求大小,吞吐量主要指大檔案的連續讀寫速度,在大檔案的複製、備份等場景適用,用“HD Tune專業版”中的“基準”測試功能即可測試出磁碟的吞吐量,一般傳統機械sata硬碟的順序讀寫速度為 :80~150M/s,SAS硬碟為150~200M/s,SSD固態硬碟為400~600M/s。
  • 響應時間,是指 I/O 請求從發出到收到響應的間隔時間。
  • 使用率,是指磁碟處理 I/O 的時間百分比。過高的使用率(比如超過 80%),通常意味著磁碟 I/O 存在效能瓶頸,這裡要注意的是,使用率只考慮有沒有 I/O,而不考慮 I/O 的大小。換句話說,當使用率是 100% 的時候,磁碟依然有可能接受新的 I/O 請求,比如磁碟一直讀寫小檔案,雖然使用率是100%,但是磁碟壓力可能並不大。
  • 飽和度,是指磁碟處理 I/O 的繁忙程度。過高的飽和度,意味著磁碟存在嚴重的效能瓶頸。當飽和度為 100% 時,磁碟無法接受新的 I/O 請求。

  這些指標,很可能是你經常掛在嘴邊的,一討論磁碟效能必定提起的物件。不過我還是要強調一點,不要孤立地去比較某一指標,而要結合讀寫比例、I/O 型別(隨機還是連續)以及 I/O 的大小,綜合來分析。舉個例子,在資料庫、大量小檔案等這類隨機讀寫比較多的場景中,IOPS 更能反映系統的整體效能;而在多媒體等順序讀寫較多的場景中,吞吐量才更能反映系統的整體效能

  一般來說,我們在為應用程式的伺服器選型時,要先對磁碟的 I/O 效能進行基準測試,以便可以準確評估,磁碟效能是否可以滿足應用程式的需求。但還是那句話,因地制宜,靈活選取。在基準測試時,一定要注意根據應用程式 I/O 的特點,來具體評估指標。當然,這就需要你測試出,不同 I/O 大小(一般是 512B 至 1MB 中間的若干值)分別在隨機讀、順序讀、隨機寫、順序寫等各種場景下的效能情況。用效能工具得到的這些指標,可以作為後續分析應用程式效能的依據。一旦發生效能問題,你就可以把它們作為磁碟效能的極限值,進而評估磁碟 I/O 的使用情況。

4、磁碟 I/O 觀測

  瞭解磁碟的效能指標,只是我們 I/O 效能測試的第一步。接下來,又該用什麼方法來觀測它們呢?這裡,介紹幾個常用的 I/O 效能觀測方法。

4.1 觀察每塊磁碟的使用情況

  iostat是I/O statistics(輸入/輸出統計)的縮寫,iostat工具將對系統的磁碟操作活動進行監視。它的特點是彙報磁碟活動統計情況,同時也會彙報出CPU使用情況。iostat也有一個弱點,就是它不能對某個程序進行深入分析,僅對系統的整體情況進行分析。

# iostat屬於sysstat軟體包。可以直接安裝。
yum install sysstat -y

  選項說明:

-c: 僅顯示CPU利用率相關資訊;
-d: 僅顯示磁碟I/O相關資訊;
-k: 顯示輸出的資料單位為KB/s而不是預設的位元組/s;
-t: 在輸出中顯示時間戳(時間戳格式YYYY-MM-DD HH:MM:SS)。
-m:顯示狀態以兆位元組每秒為單位;
-p:僅顯示塊裝置和所有被使用的其他分割槽的狀態;
-V:顯示版號並退出;
-x:顯示擴充套件狀態。

  iostat 的詳細使用本文不再贅餘,詳情見《Linux iowait詳解》這篇博文。

  在iostat輸出的這些指標中,需要注意:

  • %util ,就是我們前面提到的磁碟 I/O 使用率;
  • r/s+ w/s ,就是 IOPS;
  • rkB/s+wkB/s ,就是吞吐量;
  • r_await 或 w_await ,就是響應時間。

  在觀測指標時,也別忘了結合請求的大小( rareq-sz 和 wareq-sz)一起分析。你可能注意到,從 iostat 並不能直接得到磁碟飽和度。事實上,飽和度通常也沒有其他簡單的觀測方法,不過,你可以把觀測到的平均請求佇列長度或者讀寫請求完成的等待時間,跟基準測試的結果(比如透過 fio)進行對比,綜合評估磁碟的飽和情況。

4.2 觀察程序io的使用情況

  除了每塊磁碟的 I/O 情況,每個程序的 I/O 情況也是我們需要關注的重點。上面提到的 iostat 只提供磁碟整體的 I/O 效能資料,缺點在於,並不能知道具體是哪些程序在進行磁碟讀寫。要觀察程序的 I/O 情況,還可以使用iotop這個工具。iotop。它是一個類似於 top 的工具,你可以按照 I/O 大小對程序排序,然後找到 I/O 較大的那些程序。

#安裝
yum -y install iotop

  選項說明:

• --version #顯示版本號
• -h, --help #顯示幫助資訊
• -o, --only #顯示程序或者執行緒實際上正在做的I/O,而不是全部的,可以隨時切換按o
• -b, --batch #執行在非互動式的模式
• -n NUM, --iter=NUM #在非互動式模式下,設定顯示的次數,
• -d SEC, --delay=SEC #設定顯示的間隔秒數,支援非整數值
• -p PID, --pid=PID #只顯示指定PID的資訊
• -u USER, --user=USER #顯示指定的使用者的程序的資訊
• -P, --processes #只顯示程序,一般為顯示所有的執行緒
• -a, --accumulated #顯示從iotop啟動後每個執行緒完成了的IO總數
• -k, --kilobytes #以千位元組顯示
• -t, --time #在每一行前新增一個當前的時間
• -q, --quiet #suppress some lines of header (implies --batch). This option can be specified up to three times to remove header lines.
• -q column names are only printed on the first iteration,
• -qq column names are never printed,
• -qqq the I/O summary is never printed.

iotop 快捷鍵
• 左右箭頭  #改變排序方式,預設是按IO排序
• r  #改變排序順序
• o  #只顯示有IO輸出的程序
• p  #程序/執行緒的顯示方式的切換
• a  #顯示累積使用量
• q  #退出

  iotop 的輸出如下所示:

$ iotop
Total DISK READ :       0.00 B/s | Total DISK WRITE :       7.85 K/s 
Actual DISK READ:       0.00 B/s | Actual DISK WRITE:       0.00 B/s 
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND 
15055 be/3 root        0.00 B/s    7.85 K/s  0.00 %  0.00 % systemd-journald 

  從這個輸出,可以看到,前兩行分別表示,程序的磁碟讀寫大小總數和磁碟真實的讀寫大小總數。因為快取、緩衝區、I/O 合併等因素的影響,它們可能並不相等。剩下的部分,則是從各個角度來分別表示程序的 I/O 情況,包括執行緒 ID、I/O 優先順序、每秒讀磁碟的大小、每秒寫磁碟的大小、換入和每個程序的 I/O 利用率(即程序正在進行的 I/O 操作所佔用的時間比例)。

4.3 磁碟效能觀測命令補充

(1)sar命令

  iostat 和 iotop 命令都主要用於實時監控系統的 I/O 情況,通常不會記錄歷史的 I/O 資訊。如果你需要檢視歷史的 I/O 資訊,可以考慮使用sar命令。

  sar 命令是分析系統瓶頸的神器,可以用來檢視 CPU 、記憶體、磁碟、網路等效能,sar 命令檢視當前磁碟效能的命令為:

[root@106 sa]# sar -d -p 1 2
Linux 3.10.0-1160.59.1.el7.x86_64 (106) 	2024年04月18日 	_x86_64_	(8 CPU)

17時33分33秒       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
17時33分34秒       sdc      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
17時33分34秒       sdd      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
17時33分34秒       sdb      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
17時33分34秒       sda     25.00      0.00    276.00     11.04      0.00      0.16      0.16      0.40
17時33分34秒 centos-root     25.00      0.00    276.00     11.04      0.00      0.16      0.16      0.40
17時33分34秒 centos-swap      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

17時33分34秒       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
17時33分35秒       sdc      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
17時33分35秒       sdd      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
17時33分35秒       sdb      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
17時33分35秒       sda    153.00      0.00   1444.00      9.44      0.85      5.55      0.29      4.40
17時33分35秒 centos-root    153.00      0.00   1444.00      9.44      0.85      5.54      0.29      4.40
17時33分35秒 centos-swap      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

平均時間:       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
平均時間:       sdc      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
平均時間:       sdd      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
平均時間:       sdb      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
平均時間:       sda     89.00      0.00    860.00      9.66      0.43      4.79      0.27      2.40
平均時間: centos-root     89.00      0.00    860.00      9.66      0.43      4.79      0.27      2.40
平均時間: centos-swap      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
[root@106 sa]# 

其中, “-d”引數代表檢視磁碟效能,“-p”引數代表將 dev 裝置按照 sda,sdb……名稱顯示,“1”代表每隔1s採取一次數值,“2”代表總共採取2次數值。輸出項除了tps,其他指標和iostat一致,這裡就不再贅餘(tps:每秒鐘物理裝置的 I/O 傳輸總量)。

預設情況下,sar顯示當前資料;如果想繼續檢視一天前的報告;可以檢視儲存在/var/log/sa/下的sar日誌(預設儲存三天資料):

[root@106 sa]# sar -d -p -f /var/log/sa/sa16 
Linux 3.10.0-1160.59.1.el7.x86_64 (106) 	2024年04月16日 	_x86_64_	(8 CPU)

14時10分01秒       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
14時20分01秒       sdc      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
14時20分01秒       sdd      0.04      0.00      0.36      9.00      0.00      2.12      2.12      0.01
14時20分01秒       sdb      0.01      0.00      0.12      9.00      0.00      0.38      0.38      0.00
14時20分01秒       sda     49.17      0.00    888.31     18.07      0.07      1.41      0.58      2.85
14時20分01秒 centos-root     49.42      0.00    888.30     17.97      0.07      1.43      0.58      2.85
......
23時40分01秒       sdc      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
23時40分01秒       sdd      0.04      0.00      0.36      9.00      0.00      0.79      0.79      0.00
23時40分01秒       sdb      0.01      0.00      0.12      9.00      0.00      1.62      1.62      0.00
23時40分01秒       sda     48.50      0.00    892.42     18.40      0.08      1.57      0.63      3.07
23時40分01秒 centos-root     48.71      0.00    892.42     18.32      0.08      1.58      0.63      3.07
23時40分01秒 centos-swap      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
23時50分01秒       sdc      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
23時50分01秒       sdd      0.04      0.00      0.36      9.00      0.00      0.25      0.25      0.00
23時50分01秒       sdb      0.01      0.00      0.12      9.00      0.00      0.25      0.25      0.00
23時50分01秒       sda     49.29      0.00    824.63     16.73      0.07      1.52      0.64      3.18
23時50分01秒 centos-root     49.50      0.00    824.63     16.66      0.08      1.53      0.64      3.18
23時50分01秒 centos-swap      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
平均時間:       sdc      0.00      0.47      0.01    208.69      0.00      4.06      2.78      0.00
平均時間:       sdd      0.04      0.00      0.37      9.08      0.00      0.49      0.48      0.00
平均時間:       sdb      0.02      0.00      0.14      9.31      0.00      0.53      0.50      0.00
平均時間:       sda     48.53      0.00    863.51     17.79      0.07      1.46      0.61      2.97
平均時間: centos-root     48.74      0.00    863.51     17.71      0.07      1.47      0.61      2.97
平均時間: centos-swap      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

 (2)其他IO相關的常用命令

5、小結

  本文梳理了磁碟、 Linux IO、IO效能指標和效能工具。我們通常用 IOPS、吞吐量、使用率、飽和度以及響應時間等幾個指標,來評估磁碟的 I/O 效能。可以用 iostat 獲得磁碟的 I/O 情況,也可以用iotop 觀察程序的 I/O 情況。不過在分析這些效能指標時,要注意結合讀寫比例、I/O 型別以及 I/O 大小等,進行綜合分析。

參考:《Linux效能最佳化實戰 基礎篇:Linux 磁碟I/O是怎麼工作的(上)

參考:《Linux效能最佳化實戰 基礎篇:Linux 磁碟I/O是怎麼工作的(下)

參考:《檢視IO程序

相關文章