同前面講述的CPU、內(nèi)存一樣,文件系統(tǒng)和磁盤(pán)I/O,也是Linux操作系統(tǒng)最核心的功能。
- 磁盤(pán)為系統(tǒng)提供了最基本的持久化存儲(chǔ)。
- 文件系統(tǒng)則在磁盤(pán)基礎(chǔ)上,提供了一個(gè)用來(lái)管理文件的樹(shù)狀結(jié)構(gòu)。
文件系統(tǒng)
1. 索引節(jié)點(diǎn)和目錄項(xiàng)
Linux中的一切都由統(tǒng)一的文件系統(tǒng)來(lái)管理,包括普通的文件和目錄,以及塊設(shè)備、套接字、管道等。Linux文件系統(tǒng)為每個(gè)文件都分配了兩個(gè)數(shù)據(jù)結(jié)構(gòu),索引節(jié)點(diǎn)(index node)和目錄項(xiàng)(directory entry),主要用來(lái)記錄文件的元信息和目錄結(jié)構(gòu)。
- 索引節(jié)點(diǎn),簡(jiǎn)稱為 inode,用來(lái)記錄文件的元數(shù)據(jù),比如inode編號(hào)、文件大小、訪問(wèn)權(quán)限、修改日期、數(shù)據(jù)的位置等。索引節(jié)點(diǎn)和文件一一對(duì)應(yīng),它跟文件內(nèi)容一樣會(huì)被持久化到磁盤(pán),所以,索引節(jié)點(diǎn)同樣占磁盤(pán)。
- 目錄項(xiàng),簡(jiǎn)稱為dentry,用來(lái)記錄的文件的名字、索引節(jié)點(diǎn)指針以及與其他目錄項(xiàng)的關(guān)聯(lián)關(guān)系。多個(gè)關(guān)聯(lián)的目錄項(xiàng),就構(gòu)成了文件系統(tǒng)的目錄結(jié)構(gòu),它是由內(nèi)核維護(hù)的一個(gè)內(nèi)存數(shù)據(jù)結(jié)構(gòu),通常也被稱為目錄項(xiàng)緩存。
換句話說(shuō),索引節(jié)點(diǎn)是每個(gè)文件的唯一標(biāo)志,目錄項(xiàng)維護(hù)的是文件系統(tǒng)的樹(shù)狀結(jié)構(gòu)。目錄項(xiàng)和索引節(jié)點(diǎn)的關(guān)系是多對(duì)一,或者可理解為一個(gè)文件多個(gè)別名。舉個(gè)例子,通過(guò)硬鏈接為文件創(chuàng)建的別名,就會(huì)對(duì)應(yīng)不同目錄項(xiàng),這些目錄項(xiàng)本質(zhì)上是連接同一個(gè)文件,所以索引節(jié)點(diǎn)相同。
更具體地說(shuō),文件數(shù)據(jù)是怎么存儲(chǔ)的,是直接保存到磁盤(pán)的?實(shí)際上磁盤(pán)讀寫(xiě)的最小單位是扇區(qū),扇區(qū)只有512B大小,如果每次讀寫(xiě)這么小的單位,效率一定很低。所以,文件系統(tǒng)又把連續(xù)的扇區(qū)組成邏輯塊,再以邏輯塊為最小單元去管理數(shù)據(jù)。常見(jiàn)的邏輯塊大小是4KB,即連續(xù)的8個(gè)扇區(qū)。下面展示一張示意圖:
這里需要注意兩點(diǎn):
第一,目錄項(xiàng)本身在內(nèi)存中,索引節(jié)點(diǎn)在磁盤(pán)中。前面的 Buffer 和 Cache 原理中提到,為了協(xié)調(diào)慢速磁盤(pán)和快速CPU之間的性能差異,文件內(nèi)容會(huì)緩存到頁(yè)緩存 Cache中。索引節(jié)點(diǎn)自然也會(huì)緩存到內(nèi)存中,增加速文件訪問(wèn)。
第二,磁盤(pán)在執(zhí)行文件系統(tǒng)格式化時(shí),會(huì)被分成三個(gè)存儲(chǔ)區(qū)域,超級(jí)塊、索引節(jié)點(diǎn)區(qū) 和 數(shù)據(jù)塊區(qū)。其中,超級(jí)塊存儲(chǔ)整個(gè)文件系統(tǒng)狀態(tài);索引節(jié)點(diǎn)區(qū)存儲(chǔ)索引節(jié)點(diǎn);數(shù)據(jù)塊區(qū),存儲(chǔ)文件數(shù)據(jù)。
2. 虛擬文件系統(tǒng)
目錄項(xiàng)、索引節(jié)點(diǎn)、超級(jí)塊、邏輯塊構(gòu)成Linux文件系統(tǒng)四大基本要素。不過(guò),為了支持各種不同的文件系統(tǒng),Linux內(nèi)核在用戶進(jìn)程和文件系統(tǒng)中間,引入了一個(gè)抽象層,即虛擬文件系統(tǒng)VFS。VFS定義了一套所有文件系統(tǒng)都支持的數(shù)據(jù)結(jié)構(gòu)和標(biāo)準(zhǔn)接口。這樣,用戶層和內(nèi)核其他子系統(tǒng)都只需要跟 VFS 提供的統(tǒng)一接口交互就可以了,不需要關(guān)心底層各種文件系統(tǒng)的實(shí)現(xiàn)細(xì)節(jié)。下圖很好展示了Linux文件系統(tǒng)的架構(gòu)圖,能更好的幫助理解系統(tǒng)調(diào)用、VFS、緩存、文件系統(tǒng)以及塊存儲(chǔ)之間的關(guān)系:
從圖中可以看到,在VFS下面Linux可以支持各種文件系統(tǒng),按照存儲(chǔ)位置的不同,可以分為三類:
- 基于磁盤(pán)的文件系統(tǒng),也就是把數(shù)據(jù)直接存儲(chǔ)到計(jì)算機(jī)本地掛載的磁盤(pán)中。如 EXT4、XFS、OverlayFS等。
- 基于內(nèi)存的文件系統(tǒng),也就是虛擬文件系統(tǒng),不需要磁盤(pán)分配任何存儲(chǔ)空間,只占用內(nèi)存。如 /proc 文件系統(tǒng)、/sys 文件系統(tǒng)(主要向用戶空間導(dǎo)出層次化的內(nèi)核對(duì)象)。
- 網(wǎng)絡(luò)文件系統(tǒng),用來(lái)訪問(wèn)其他計(jì)算機(jī)數(shù)據(jù)的文件系統(tǒng),如 NFS、SMB、iSCSI等。
這些文件系統(tǒng),要先掛載到 VFS 目錄樹(shù)中的子目錄(掛載點(diǎn)),然后才能訪問(wèn)其中文件。比如安裝系統(tǒng)時(shí),要先掛在一個(gè)根目錄( / ),在根目錄下,再把其他文件系統(tǒng)掛在進(jìn)來(lái)。
3. 文件系統(tǒng)I/O
把文件掛到掛載點(diǎn)后,就能通過(guò)它去訪問(wèn)它管理的文件了。VFS提供的訪問(wèn)文件的標(biāo)準(zhǔn)接口,以系統(tǒng)調(diào)用的方式提供給應(yīng)用程序使用。比如,cat命令,相繼調(diào)用 open()、read()、write()。文件讀寫(xiě)方式的各種差異,也導(dǎo)致I/O 的分類多種多樣。常見(jiàn)的有,緩沖與非緩沖I/O、直接與非直接I/O、阻塞與非阻塞I/O、同步與異步I/O等。下面詳細(xì)解釋下這四種 I/O分類:
第一種,根據(jù)是否利用標(biāo)準(zhǔn)庫(kù)緩存,可以把文件I/O 分為 緩沖I/O 和 非緩沖I/O。這里的“緩沖”,其實(shí)指的是標(biāo)準(zhǔn)庫(kù)內(nèi)部實(shí)現(xiàn)的緩存。例如,很多程序遇到換行時(shí)才真正輸出,換行前的內(nèi)容,就是被標(biāo)準(zhǔn)庫(kù)暫時(shí)緩存起來(lái)。因此,緩沖I/O 指的是利用標(biāo)準(zhǔn)庫(kù)緩存來(lái)加速文件的訪問(wèn),在標(biāo)準(zhǔn)庫(kù)內(nèi)部再通過(guò)系統(tǒng)調(diào)用訪問(wèn)文件;非緩沖I/O 指的是直接通過(guò)系統(tǒng)調(diào)用訪問(wèn)文件,而不通過(guò)標(biāo)準(zhǔn)庫(kù)緩存。無(wú)論是緩沖還是非緩沖 I/O,最后都是通過(guò)系統(tǒng)調(diào)用訪問(wèn)文件。而根據(jù)前面內(nèi)容,系統(tǒng)調(diào)用后,還通過(guò)頁(yè)緩存,來(lái)減少磁盤(pán)I/O操作。
第二種,根據(jù)是否利用操作系統(tǒng)的頁(yè)緩存,可以把文件I/O 分為直接I/O 和 非直接I/O。想要實(shí)現(xiàn)直接I/O,需要在系統(tǒng)調(diào)用中指定標(biāo)志 O_DIRECT,如果不指定,默認(rèn)是非直接I/O。不過(guò)注意,這里的直接、非直接I/O,其實(shí)最終還是和文件系統(tǒng)交互。如果實(shí)在數(shù)據(jù)庫(kù)等場(chǎng)景中,還會(huì)看到,跳過(guò)文件系統(tǒng)讀寫(xiě)磁盤(pán)的情況,即裸I/O。
第三種,根據(jù)應(yīng)用程序是否阻塞自身運(yùn)行,可以把文件I/O 分為阻塞I/O 和 非阻塞I/O。在應(yīng)用程序執(zhí)行I/O 操作后,如果沒(méi)獲得響應(yīng),就阻塞當(dāng)前線程,自然不能執(zhí)行其他任務(wù),這是阻塞I/O;如果沒(méi)獲得響應(yīng),卻不阻塞當(dāng)前線程,繼續(xù)執(zhí)行其他任務(wù),隨后通過(guò)輪詢或者時(shí)間通知的形式,獲得之前調(diào)用的結(jié)果。比如,訪問(wèn)管道或者網(wǎng)絡(luò)套接字時(shí),設(shè)置 O_NONBLOCK 標(biāo)志,表示非阻塞方式訪問(wèn),若不做任何設(shè)置,默認(rèn)就是阻塞方式訪問(wèn)。
第四種,根據(jù)是否等待響應(yīng)結(jié)果,可以把文件I/O 分為同步I/O 和 異步I/O。在應(yīng)用程序執(zhí)行I/O 操作后,如果一直等到 整個(gè) I/O完成后才獲得響應(yīng),就是同步I/O;如果不等待 I/O 完成以及完成后的響應(yīng),繼續(xù)往下執(zhí)行,等到 I/O 完成后,響應(yīng)會(huì)用事件通知的方式,告訴應(yīng)用程序。比如,在操作文件時(shí),如果設(shè)置了 O_SYNC 或 O_DSYNC標(biāo)志,就代表同步I/O,后者是等待文件數(shù)據(jù)寫(xiě)入磁盤(pán)后才返回,而前者是在后者基礎(chǔ)上,要求文件元數(shù)據(jù)也要寫(xiě)入磁盤(pán)后才能返回。再比如,在訪問(wèn)管道或者網(wǎng)絡(luò)套接字時(shí),設(shè)置選項(xiàng) O_ASYNC后,就是異步 I/O內(nèi)核會(huì)通過(guò) SIGIO 或者 SIGPOLL,來(lái)通知進(jìn)程,文件是否可讀寫(xiě)。
總之,無(wú)論是普通文件和塊設(shè)備、還是網(wǎng)絡(luò)套接字和管道等,都通過(guò)統(tǒng)一的VFS接口來(lái)被訪問(wèn)。
4. 文件系統(tǒng)性能觀測(cè)
$ df /dev/sda1
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 30308240 3167020 27124836 11% /
$ df -h /dev/sda1
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 29G 3.1G 26G 11% /
$ df -i /dev/sda1
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 3870720 157460 3713260 5% /
加上-i 參數(shù)查看索引節(jié)點(diǎn)的使用情況,索引節(jié)點(diǎn)的容量,(也就是 Inode個(gè)數(shù))是在格式化磁盤(pán)時(shí)設(shè)定好的,由格式化工具自動(dòng)生成。當(dāng)你發(fā)現(xiàn)索引節(jié)點(diǎn)空間不足時(shí),但磁盤(pán)空間充足時(shí),很可能是過(guò)多的小文件導(dǎo)致的,一般的刪除它們或者移到其他的索引節(jié)點(diǎn)充足的磁盤(pán)上,就能解決問(wèn)題。
接下來(lái),文件系統(tǒng)的目錄項(xiàng)和索引節(jié)點(diǎn)的緩存,如何查看呢?
實(shí)際上,內(nèi)核使用 Slab 機(jī)制,管理目錄項(xiàng)和索引節(jié)點(diǎn)的緩存。/proc/meminfo 只給出了Slab整體大小,具體到每一種Slab緩存,就要查看 /proc/slabinfo。運(yùn)行下面命令可以得到,所有目錄項(xiàng)和各種文件系統(tǒng)的索引節(jié)點(diǎn)的緩存情況:
$ cat /proc/slabinfo | grep -E '^#|dentry|inode'
# name < active_objs > < num_objs > < objsize > < objperslab > < pagesperslab > : tunables < limit >
dentry 行表示目錄項(xiàng)緩存,inode_cache 行,表示VFS 索引節(jié)點(diǎn)緩存,其余的則是各種文件系統(tǒng)的緩存。這里列比較多,可查詢man slabinfo。實(shí)際性能分析時(shí),更多使用 slabtop,來(lái)找到占用內(nèi)存最多的緩存類型:
# 按下c按照緩存大小排序,按下a按照活躍對(duì)象數(shù)排序
$ slabtop
Active / Total Objects (% used) : 277970 / 358914 (77.4%)
Active / Total Slabs (% used) : 12414 / 12414 (100.0%)
Active / Total Caches (% used) : 83 / 135 (61.5%)
Active / Total Size (% used) : 57816.88K / 73307.70K (78.9%)
Minimum / Average / Maximum Object : 0.01K / 0.20K / 22.88K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
69804 23094 0% 0.19K 3324 21 13296K dentry
16380 15854 0% 0.59K 1260 13 10080K inode_cache
58260 55397 0% 0.13K 1942 30 7768K kernfs_node_cache
485 413 0% 5.69K 97 5 3104K task_struct
1472 1397 0% 2.00K 92 16 2944K kmalloc-2048
從這個(gè)結(jié)果可以看到,目錄項(xiàng)和索引節(jié)點(diǎn)占用最多的 Slab緩存,但其實(shí)并不大,約23MB。
思考:find / -name file-name 命令導(dǎo)致會(huì)不會(huì)導(dǎo)致緩存升高,如果會(huì),導(dǎo)致哪類緩存升高呢?
find / -name 命令是全盤(pán)掃描(包括內(nèi)存文件系統(tǒng)、磁盤(pán)文件系統(tǒng)等),所以這里會(huì)導(dǎo)致 xfs_inode 、proc_inode_cache、dentry、 inode_cache這幾類緩存的升高,而且在下次執(zhí)行 find 命令時(shí),就會(huì)快很多,因?yàn)樗蟛糠謺?huì)直接在緩存中查找結(jié)果。這里你可以在執(zhí)行find命令前后,比較slabtop、free、vmstat輸出結(jié)果,又會(huì)有更深的理解。
磁盤(pán) I/O
1. 磁盤(pán)
首先,根據(jù)存儲(chǔ)介質(zhì)的不同,可以分為兩類,機(jī)械磁盤(pán) 和 固態(tài)磁盤(pán)。
機(jī)械磁盤(pán):也稱為硬盤(pán)驅(qū)動(dòng)器(Hard Disk Driver,縮寫(xiě)HDD),機(jī)械磁盤(pán)由盤(pán)片和讀寫(xiě)磁頭組成,數(shù)據(jù)存儲(chǔ)在盤(pán)片的環(huán)狀磁道中,最小讀寫(xiě)單位 扇區(qū),一般大小為512B。在讀寫(xiě)數(shù)據(jù)時(shí),需要移動(dòng)磁頭,定位到數(shù)據(jù)所在的盤(pán)片磁道中,然后才訪問(wèn)數(shù)據(jù)。如果 I/O 請(qǐng)求剛好連續(xù),那就不需要磁道尋址,可獲得最佳性能,這就是順序I/O 的工作原理。隨機(jī) I/O,需要不停地移動(dòng)磁頭,來(lái)定位數(shù)據(jù)位置,讀寫(xiě)速度比較慢。
固態(tài)磁盤(pán):Solid State Driver,縮寫(xiě)SSD,由固態(tài)電子元器件組成,最小讀寫(xiě)單位 頁(yè),一般大小4KB、8KB等。固態(tài)磁盤(pán)不需要磁道尋址,不管是連續(xù)I/O,還是隨機(jī)I/O的性能,都比機(jī)械磁盤(pán)好得多。
另外,相同磁盤(pán)的順序I/O 都要比 隨機(jī)I/O 快得多,原因如下:
- 對(duì)于機(jī)械磁盤(pán)來(lái)說(shuō),隨機(jī) I/O需要更多的磁頭尋道和盤(pán)片旋轉(zhuǎn),性能比順序I/O 慢。
- 對(duì)于固態(tài)盤(pán)來(lái)說(shuō),雖然隨機(jī)I/O 性能比機(jī)械盤(pán)好很多,但是它也會(huì)有“先擦除、再寫(xiě)入”的限制。隨機(jī)讀寫(xiě)也有大量的垃圾回收,所以還是會(huì)比順序I/O 慢很多。
- 另外,順序I/O 可以通過(guò)預(yù)讀的方式,來(lái)減少 I/O請(qǐng)求的次數(shù),這也是其性能優(yōu)異的原因之一。
在上一節(jié)提到過(guò),如果每次都讀寫(xiě) 512B 數(shù)據(jù),效率會(huì)很低。文件系統(tǒng)會(huì)把連續(xù)的扇區(qū)或頁(yè)組成邏輯塊,作為最小單元管理數(shù)據(jù),常見(jiàn)的邏輯塊是 4KB,即連續(xù)的8個(gè)扇區(qū),或者一個(gè)頁(yè)。
其次,還可以按照接口來(lái)分類,可以把硬盤(pán)分為 IDE、SCSI、SAS、SATA、FC等。不同的接口,分配不同的設(shè)備名稱。比如 IDE的會(huì)分配一個(gè)前綴為 hd 的設(shè)備名,SCSI 和 SATA會(huì)分配一個(gè) sd 前綴的設(shè)備名。如果是多塊同類型的磁盤(pán),會(huì)按照a、b、c等字母順序編號(hào)。
第三,還可以根據(jù)使用方式,將磁盤(pán)劃分為不同架構(gòu)。最簡(jiǎn)單的就是,作為獨(dú)立磁盤(pán)來(lái)使用。然后再根據(jù)需要,將磁盤(pán)劃分成多個(gè)邏輯分區(qū),再給分區(qū)編號(hào)。比如前面多次用到的 /dev/sda,還可以分成兩個(gè)分區(qū) /dev/sda1 和 /dev/sda2。另一個(gè)比較常用的架構(gòu)是,將多塊磁盤(pán)組成一個(gè)邏輯磁盤(pán),構(gòu)成冗余獨(dú)立 的磁盤(pán)陣列,RAID,提高數(shù)據(jù)訪問(wèn)性能,增強(qiáng)數(shù)據(jù)存儲(chǔ)的可靠性。
根據(jù)容量、性能、可靠性的不同,RAID可以分為多個(gè)級(jí)別,如RAID0、RAID1、RAID5、RAID10等。RAID0有最優(yōu)的讀寫(xiě)性能,但不提供數(shù)據(jù)冗余的功能,其他級(jí)別的 RAID,在數(shù)據(jù)冗余的基礎(chǔ)上,對(duì)讀寫(xiě)性能有一定的優(yōu)化。
最后一種架構(gòu),把磁盤(pán)組合成網(wǎng)絡(luò)存儲(chǔ)集群,再通過(guò)NFS、SMB、iSCSI等網(wǎng)絡(luò)存儲(chǔ)協(xié)議,暴露給服務(wù)器使用。
其實(shí),在Linux下,磁盤(pán)是作為塊設(shè)備來(lái)管理的,也就是以塊為單位來(lái)讀寫(xiě)數(shù)據(jù),且支持隨機(jī)讀寫(xiě)。每個(gè)塊設(shè)備都被賦予主、次兩個(gè)設(shè)備號(hào),主設(shè)備號(hào)用在驅(qū)動(dòng)程序中區(qū)別設(shè)備類型,次設(shè)備號(hào)用來(lái)給多個(gè)同類設(shè)備編號(hào)。
2. 通用塊層
為了減少不同塊設(shè)備的差異帶來(lái)的影響,Linux通過(guò)一個(gè)統(tǒng)一的通用塊層,來(lái)管理各種不同的塊設(shè)備。通用塊層其實(shí)是處在文件系統(tǒng)和磁盤(pán)驅(qū)動(dòng)中間的一個(gè)塊設(shè)備抽象層。有兩個(gè)功能:
第一個(gè)跟虛擬文件系統(tǒng)的功能類似。向上,為文件系統(tǒng)和應(yīng)用程序,提供訪問(wèn)塊設(shè)備的標(biāo)準(zhǔn)接口;向下,把各種異構(gòu)的磁盤(pán)設(shè)備抽象成統(tǒng)一的塊設(shè)備,并提供統(tǒng)一框架來(lái)管理這些設(shè)備的驅(qū)動(dòng)程序。
第二個(gè)功能,通用塊層還給文件系統(tǒng)和應(yīng)用程序發(fā)來(lái)的I/O請(qǐng)求排隊(duì),并通過(guò)請(qǐng)求排隊(duì)、合并等,提高磁盤(pán)讀寫(xiě)的效率。
對(duì) I/O請(qǐng)求排序也是 I/O調(diào)度。事實(shí)上,Linux內(nèi)核支持四種 I/O調(diào)度算法,NONE、NOOP、CFQ、DeadLine。
NONE:確切的說(shuō)并不能算調(diào)度,因?yàn)樗耆皇褂萌魏握{(diào)度器,對(duì)文件系統(tǒng)和應(yīng)用程序的 I/O不作任何處理,常用在虛擬機(jī)中(此時(shí)磁盤(pán) I/O調(diào)度完全由物理機(jī)支持)。
NOOP:最簡(jiǎn)單的一種調(diào)度算法,是一個(gè)先進(jìn)先出的隊(duì)列,只做一些最基本的請(qǐng)求合并,常用于SSD盤(pán)。
CFQ:完全公平調(diào)度器,是現(xiàn)在很多發(fā)行版的默認(rèn) I/O調(diào)度器。它為每個(gè)進(jìn)程維護(hù)了一個(gè) I/O調(diào)度隊(duì)列,并按時(shí)間片來(lái)均勻分布每個(gè)進(jìn)程的 I/O請(qǐng)求。類似于進(jìn)程的CPU調(diào)度,CFQ調(diào)度還支持進(jìn)程 I/O的優(yōu)先級(jí)調(diào)度,所以適用運(yùn)行著大量進(jìn)程的系統(tǒng),像桌面環(huán)境、多媒體應(yīng)用等。
DeadLine:分別為讀、寫(xiě)請(qǐng)求創(chuàng)建不同的 I/O 隊(duì)列,可以提高機(jī)械磁盤(pán)的吞吐量,并確保達(dá)到最終期限的請(qǐng)求被優(yōu)先處理。這種調(diào)度算法 多用在 I/O 壓力比較大的場(chǎng)合,如數(shù)據(jù)庫(kù)等。
3. I/O棧
結(jié)合上面講的文件系統(tǒng)、磁盤(pán)和通用塊層的工作原理,我們可以整體來(lái)看 Linux存儲(chǔ)系統(tǒng)的 I/O原理了。事實(shí)上,我們可以把 Linux存儲(chǔ)系統(tǒng)的 I/O棧,由上至下分為三層:文件系統(tǒng)層、通用塊層、設(shè)備層。看圖:
根據(jù)這張全景圖,我們可以更清楚理解,存儲(chǔ)系統(tǒng)的 I/O的工作原理:
- 文件系統(tǒng)層,包括虛擬文件系統(tǒng)和其他各種文件系統(tǒng)的具體實(shí)現(xiàn)。首先為上層的應(yīng)用程序提供標(biāo)準(zhǔn)的文件訪問(wèn)接口,對(duì)下會(huì)通過(guò)通用塊層,來(lái)存儲(chǔ)和管理磁盤(pán)數(shù)據(jù)。
- 通用塊層,是Linux磁盤(pán) I/O的核心,包括設(shè)備 I/O隊(duì)列和 I/O調(diào)度器。會(huì)對(duì)文件系統(tǒng)的 I/O請(qǐng)求進(jìn)行排隊(duì),再通過(guò)重新排序和請(qǐng)求合并,再發(fā)給下一級(jí)設(shè)備層。
- 設(shè)備層,包括存儲(chǔ)設(shè)備和相應(yīng)的驅(qū)動(dòng)程序,負(fù)責(zé)最終物理設(shè)備的 I/O操作。
存儲(chǔ)系統(tǒng)的 I/O,通常是整個(gè)Linux系統(tǒng)中最慢的一環(huán)。所以,Linux通過(guò)多種緩存機(jī)制來(lái)優(yōu)化 I/O 效率。比如,為了優(yōu)化文件訪問(wèn)性能,會(huì)使用頁(yè)緩存、索引節(jié)點(diǎn)緩存、目錄項(xiàng)緩存等多種緩存機(jī)制,減少對(duì)下層塊設(shè)備的直接調(diào)用。同樣,為了優(yōu)化塊設(shè)備的訪問(wèn)性能,會(huì)使用緩沖區(qū),來(lái)緩存塊設(shè)備的數(shù)據(jù)。
4. 磁盤(pán)性能指標(biāo)以及觀測(cè)
這里說(shuō)一下常見(jiàn)的五個(gè)指標(biāo),使用率、飽和度、IOPS、吞吐量以及響應(yīng)時(shí)間等,這五個(gè)指標(biāo)是衡量磁盤(pán)性能的基本指標(biāo)。
- 使用率,是指磁盤(pán)處理 I/O的時(shí)間百分比。過(guò)高的使用率(如超過(guò)80%),通常意味著磁盤(pán) I/O的性能瓶頸。
- 飽和度,磁盤(pán)處理 I/O的繁忙程度,過(guò)高的飽和度,意味著磁盤(pán)存在嚴(yán)重的性能瓶頸。當(dāng)達(dá)到100%時(shí),磁盤(pán)就無(wú)法接受新的 I/O請(qǐng)求。
- IOPS,每秒的 I/O請(qǐng)求數(shù)。
- 吞吐量,每秒的 I/O請(qǐng)求大小。
- 響應(yīng)時(shí)間,從發(fā)出請(qǐng)求到收到響應(yīng)的時(shí)間間隔。
注意,使用率只考慮有沒(méi)有 I/O,而不考慮 I/O大小,即使達(dá)到100%,也有可能接受新的 I/O請(qǐng)求。在數(shù)據(jù)庫(kù)、大量小文件等這類隨機(jī)讀寫(xiě)比較多的場(chǎng)景中,IOPS更能反應(yīng)系統(tǒng)整體性能。在多媒體等順序讀寫(xiě)較多的場(chǎng)景中,吞吐量更能反應(yīng)系統(tǒng)整體性能。
一般來(lái)說(shuō),我們?cè)跒閼?yīng)用程序的服務(wù)器選型時(shí),要先對(duì)磁盤(pán) I/O的性能進(jìn)行基準(zhǔn)測(cè)試,推薦的性能測(cè)試工具 fio,來(lái)測(cè)試磁盤(pán)的 IOPS,吞吐量以及響應(yīng)時(shí)間等核心指標(biāo)。用性能工具得到的指標(biāo),作為后續(xù)分析應(yīng)用程序的性能依據(jù)。一旦發(fā)生性能問(wèn)題,就可以把它們作為磁盤(pán)性能的極限值,進(jìn)而評(píng)估磁盤(pán) I/O的使用情況。
接下來(lái)看看怎么觀測(cè)磁盤(pán) I/O?首推的工具 iostat,它提供每個(gè)磁盤(pán)的使用率、IOPS、吞吐量等各種常見(jiàn)的性能指標(biāo),當(dāng)然這些指標(biāo)來(lái)自 /proc/diskstats。iostats 的輸出界面如下:
# -d -x表示顯示所有磁盤(pán)I/O的指標(biāo)
$ iostat -d -x 1
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util
loop0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
loop1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 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 0.00 0.00 0.00 0.00
下圖說(shuō)明了這些列的具體含義:
這些指標(biāo),你要注意,%util 磁盤(pán)使用率,r/s + w/s IOPS,rkB/s + wkB/s 吞吐量, r_await + w_await 響應(yīng)時(shí)間。另外從 iostat 并不能直接得到磁盤(pán)的飽和度,但是可以把觀測(cè)到的,平均請(qǐng)求隊(duì)列長(zhǎng)度 或者 讀寫(xiě)請(qǐng)求完成的等待時(shí)間,跟基準(zhǔn)測(cè)試的結(jié)果進(jìn)行對(duì)比,綜合來(lái)評(píng)估。
我們?cè)賮?lái)看看,每個(gè)進(jìn)程的 I/O情況。iostat只能看到磁盤(pán)整體的 I/O性能數(shù)據(jù),并不能知道具體哪些進(jìn)程 在進(jìn)行磁盤(pán)讀寫(xiě),推薦兩個(gè)工具:pidstat 和 iotop。具體使用這里略過(guò)。
-
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7085瀏覽量
89203 -
Linux
+關(guān)注
關(guān)注
87文章
11322瀏覽量
209861 -
磁盤(pán)
+關(guān)注
關(guān)注
1文章
379瀏覽量
25224 -
文件系統(tǒng)
+關(guān)注
關(guān)注
0文章
287瀏覽量
19929
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論