同 cpu、記憶體一樣,磁碟和檔案系統的管理,也是作業系統最核心的功能。
有以下兩個基本功能:
1 磁碟為系統提供了最基本的持久化儲存。
2 檔案系統則在磁碟的基礎上,提供了乙個用來管理檔案的樹狀結構。
索引節點和目錄項
在linux作業系統中,遵循「一切皆是檔案」的思想。包括檔案,目錄,塊裝置、套接字、管道等,都是通過檔案系統來管理的。組織檔案的方式不同,就形成了不同的檔案系統。
檔案系統包括了索引節點(index node)和目錄項(directory entry)。它們主要用來記錄檔案的元資訊和目錄結構。
索引節點,簡稱為 inode,用來記錄檔案的元資料,比如 inode 編號、檔案大小、訪問許可權、修改日期、資料的位置等。索引節點和檔案一一對應,它跟檔案內容一樣,都會被持久化儲存到磁碟中。所以記住,索引節點同樣占用磁碟空間。
目錄項,簡稱為 dentry,用來記錄檔案的名字、索引節點指標以及與其他目錄項的關聯關係。多個關聯的目錄項,就構成了檔案系統的目錄結構。不過,不同於索引節點,目錄項是由核心維護的乙個記憶體資料結構,所以通常也被叫做目錄項快取。
索引節點是每個檔案的唯一標誌,而目錄項維護的檔案系統的樹狀結構。他們之間的關係是多對一,你可以簡單理解為,乙個檔案可以有多個別名。
因為磁碟讀寫的最小單位是扇區,然而扇區只有 512b 大小,如果每次都讀寫這麼小的單位,效率一定很低。所以,檔案系統又把連續的扇區組成了邏輯塊,然後每次都以邏輯塊為最小單元,來管理資料。常見的邏輯塊大小為 4kb,也就是由連續的 8 個扇區組成。
檔案系統示意圖:
需要注意的是:
第一,目錄項本身就是乙個記憶體快取,而索引節點則是儲存在磁碟中的資料。在前面的 buffer 和 cache 原理中,我曾經提到過,為了協調慢速磁碟與快速 cpu 的效能差異,檔案內容會快取到頁快取 cache 中。那麼,你應該想到,這些索引節點自然也會快取到記憶體中,加速檔案的訪問。
第二,磁碟在執行檔案系統格式化時,會被分成三個儲存區域,超級塊、索引節點區和資料塊區。 超級塊,儲存整個檔案系統的狀態。
索引節點區,用來儲存索引節點。
資料塊區,則用來儲存檔案資料
乙個磁碟的分割槽
1 引導塊。引導塊占用第0號物理塊,不屬於檔案系統管轄;如果系統中有多個檔案系統,只有跟檔案系統才有引導程式放入引導塊中,其餘檔案系統都不使用引導塊。
2 超級塊。檔案系統的第乙個塊被稱為超級塊,這個塊存放的是檔案系統本身的結構資訊;比如超級塊記錄了每個區域的大小,存放未使用磁碟的資訊等。
3 i節點表。超級塊是下乙個部分就是i節點表,每個檔案對應乙個i節點,每個檔案都有一些屬性,如檔案大小,所有者,建立時間等。這些資訊存放在對應的i節點的結構中,所有的檔案都具有相同大小的i節點,這些i節點組成乙個i節點表,檔案系統建立後,i節點的數目是有限的。所以乙個檔案系統能夠建立的檔案也是有限的。
4 檔案儲存區。檔案系統的第3個部分是檔案儲存區,檔案的內容儲存在這裡,磁碟所有的塊大小都是一樣,如果檔案大小超過乙個塊的大小,則檔案會存放在多個次磁碟塊中。
5 程序對換區。磁碟上會開闢一塊區域, 為對換區, 當記憶體中的程序需要擴大占用的記憶體空間, 而當前記憶體空間不足時, 則把某些不常用的程序暫時替換到對換區中, 在適用的時候又把他們換進 記憶體,解決記憶體不足和程序之間對記憶體的競爭問題。
虛擬檔案系統
為了支援各種不同的檔案系統,linux在使用者程序和檔案系統之間引入了乙個抽象層,vfs。vfs 定義了一組所有檔案系統都支援的資料結構和標準介面。使用者程序只需要根vfs對接,而不需要處理各種檔案系統的細節。
他們之間的關係如下:
檔案系統分為3類:
第一類是基於磁碟的檔案系統,也就是把資料直接儲存在計算機本地掛載的磁碟中。常見的 ext4、xfs、overlayfs 等,都是這類檔案系統。
第二類是基於記憶體的檔案系統,也就是我們常說的虛擬檔案系統。這類檔案系統,不需要任何磁碟分配儲存空間,但會占用記憶體。我們經常用到的 /proc 檔案系統,其實就是一種最常見的虛擬檔案系統。此外,/sys 檔案系統也屬於這一類,主要向使用者空間匯出層次化的核心物件。
第三類是網路檔案系統,也就是用來訪問其他計算機資料的檔案系統,比如 nfs、smb、iscsi 等。
各種檔案系統都必須要掛載到目錄下,才能使用。
檔案系統 i/o
檔案系統掛載到目錄以後,就可以使用vfs的標準介面進行檔案的操作。
文學系統是有讀寫方式的差異,導致了io也是分為多種。
第一種,根據是否利用標準庫快取,可以把檔案 i/o 分為緩衝 i/o 與非緩衝 i/o。
緩衝 i/o,是指利用標準庫快取來加速檔案的訪問,而標準庫內部再通過系統排程訪問檔案。
非緩衝 i/o,是指直接通過系統呼叫來訪問檔案,不再經過標準庫快取。
「緩衝」,是指標準庫內部實現的快取。比方說,你可能見到過,很多程式遇到換行時才真正輸出,而換行前的內容,其實就是被標準庫暫時快取了起來。但是無論緩衝 i/o 還是非緩衝 i/o,它們最終還是要經過系統呼叫來訪問檔案。系統呼叫後,還會通過頁快取,來減少磁碟的 i/o 操作。
第二,根據是否利用作業系統的頁快取,可以把檔案 i/o 分為直接 i/o 與非直接 i/o。
直接 i/o,是指跳過作業系統的頁快取,直接跟檔案系統互動來訪問檔案。
非直接 i/o 正好相反,檔案讀寫時,先要經過系統的頁快取,然後再由核心或額外的系統呼叫,真正寫入磁碟。
想要實現直接 i/o,需要你在系統呼叫中,指定 o_direct 標誌。如果沒有設定過,預設的是非直接 i/o。不過要注意,直接 i/o、非直接 i/o,本質上還是和檔案系統互動。如果是在資料庫等場景中,你還會看到,跳過檔案系統讀寫磁碟的情況,也就是我們通常所說的裸 i/o。
第三,根據應用程式是否阻塞自身執行,可以把檔案 i/o 分為阻塞 i/o 和非阻塞 i/o:
阻塞 i/o,是指應用程式執行 i/o 操作後,如果沒有獲得響應,就會阻塞當前執行緒,自然就不能執行其他任務。
非阻塞 i/o,是指應用程式執行 i/o 操作後,不會阻塞當前的執行緒,可以繼續執行其他的任務,隨後再通過輪詢或者事件通知的形式,獲取呼叫的結果。
比方說,訪問管道或者網路套接字時,設定 o_nonblock 標誌,就表示用非阻塞方式訪問;而如果不做任何設定,預設的就是阻塞訪問。
第四,根據是否等待響應結果,可以把檔案 i/o 分為同步和非同步 i/o:
同步 i/o,是指應用程式執行 i/o 操作後,要一直等到整個 i/o 完成後,才能獲得 i/o 響應。
非同步 i/o,是指應用程式執行 i/o 操作後,不用等待完成和完成後的響應,而是繼續執行就可以。等到這次 i/o 完成後,響應會用事件通知的方式,告訴應用程式。
使用標誌位。可以控制io的方式:
o_sync 或者 o_dsync 標誌,就代表同步 i/o
o_async 選項後,相應的 i/o 就是非同步 i/o
效能觀測
容量
df 命令,就能檢視檔案系統的磁碟空間使用情況
快取
free 或 vmstat,來觀察頁快取的大小
核心使用 slab 機制,管理目錄項和索引節點的快取。/proc/meminfo 只給出了 slab 的整體大小,具體到每一種 slab 快取,還要檢視 /proc/slabinfo 這個檔案。
cat /proc/slabinfo | grep -e 『^#|dentry|inode』
slabtop ,找到占用記憶體最多的快取型別
磁碟工作原理與IO效能分析
最近,在研究如何優化產品裝置的磁碟io效能,需要深入研究磁碟及檔案系統原理和工作機制,下面簡要總結下關於磁碟方面的東西,下篇文章再分享檔案系統的。機械磁碟結構 無論哪種機械硬碟,都主要由碟片 磁頭 碟片主軸 控制電機 磁頭控制器 資料轉換器 介面 快取等幾個部份組成。其中所有的碟片都固定在乙個旋轉軸...
Spark SQL工作原理剖析和效能優化
一 工作原理剖析 spark sql 架構中主要有這幾個關鍵的元件 sqlparser sql分析程式 analyser 分析器 optimizer 優化器 sparkplan spark計畫 sparksql大致的執行流程是這樣的 1.sql 語句經過sqlparser 完成sql 語句的語法解析...
IO效能的優化
一 載入前 1.預讀取,避免後面一下子讀取任務太多 使用預先讀取,分步讀取,避免記憶體峰值突然上公升。預載入 cctexturecache ccspriteframecache ccanimationcache 都可以為其新增乙個 key,後面通過 key索引獲取紋理 精靈或動畫。二 載入時 2.非...