XFS 文件系统 (一) :设计概览
文章目錄
- 0 前言
- 1 設(shè)計背景
- 2. 需要解決的問題
- 2.1 異常恢復(fù)太慢
- 2.2 不支持大文件系統(tǒng)
- 2.3 不支持大型稀疏文件
- 2.4 不支持大型連續(xù)文件
- 2.5 不支持大目錄
- 2.6 不支持過多文件個數(shù)
- 3 XFS 架構(gòu)
- 4 痛點解決
- 4.1 Allocation Groups
- 4.2 Manging Free Space
- 4.3 大文件的支持
- 5 總結(jié)
0 前言
雖然工作精力主要是在 存儲引擎方向上,但是目前業(yè)界大多數(shù)的存儲引擎都是構(gòu)建在 os fs上, 所以深入理解文件系統(tǒng)工作原理對于存儲引擎的設(shè)計也有不少的幫助。
尤其是近期工作中遇到一些 engine on ape-xfs 的性能問題,發(fā)現(xiàn)文件系統(tǒng)的知識欠缺還是比較嚴(yán)重的。
舉個例子,on aep 也就是 pmem 上做了一個fsdax 模式的pmem namespace,像使用磁盤一樣使用它 需要格式化為對應(yīng)的文件系統(tǒng)。因為 pmem 是插在內(nèi)存插槽上(和cpu 更近),且libpmem 驅(qū)動僅只支持 dax 模式的掛載,用于加速訪問pmem。所以 on pmem 的文件系統(tǒng) 是無法使用 page-cache 的,也就是像 inode/dentry 這樣的文件/目錄元數(shù)據(jù) 信息是沒有辦法緩存到 icache/dcache的,這樣,針對這一些元數(shù)據(jù)的更新就需要直接落在pmem上,像存儲引擎的 wal 是需要頻繁寫文件,那么文件的inode 元信息(file size)的更新就會非常頻繁(除非預(yù)分配),沒有預(yù)分配的情況下寫性能就會非常之差。
這里如果能夠深入了解文件系統(tǒng)的基本原理,這樣的問題抓個棧就是一眼的事情,不需要消耗過多的時間。
本篇 以及 后續(xù)的文章還是以技術(shù)設(shè)計 為主 進(jìn)行學(xué)習(xí),不會太深入代碼。
先以 xfs 設(shè)計實現(xiàn)為主,畢竟centos7/8 的默認(rèn)文件系統(tǒng),后面再逐個梳理 與其他文件系統(tǒng)的實現(xiàn)差異,畢竟文件系統(tǒng)過于龐大,這里僅僅做一些初步設(shè)計的記錄
1 設(shè)計背景
xfs 是大名鼎鼎的 硅谷 圖形圖像高性能計算公司巨頭 SiliconGraphic Inc 1993 年為自己內(nèi)部 高性能服務(wù)器設(shè)計的文件系統(tǒng)。因為現(xiàn)在的 不少開發(fā)者 深度參與了 xfs 的設(shè)計開發(fā),所以才成為今天centos 的主流文件系統(tǒng)。
XFS 被 SGI 設(shè)計出來的目的肯定是未來解決已有文件系統(tǒng)在大多數(shù)場景下的問題的,SGI 內(nèi)部現(xiàn)有的文件系統(tǒng) EFS(existing file system) 因為設(shè)計,無法發(fā)揮硬件性能,導(dǎo)致文件系統(tǒng)成為 os 的 i/o 瓶頸。還有很多其他功能上的限制,主要是以下幾個方面。
- EFS 采用的是 extent 方式管理 磁盤塊的分配 以及 調(diào)度磁盤IO,無法完全發(fā)揮磁盤介質(zhì)性能。
- 單個文件系統(tǒng)的大小不能超過 8G (當(dāng)時的磁盤已經(jīng)有T級別的了,hdd),單個文件的大小不能超過2G。
- 在EFS 上解決一些功能上的限制和 性能問題,因為架構(gòu)設(shè)計,工作量基本接近重寫了。
因為SGI 提供給用戶的服務(wù)器需要解決 用戶大量的視頻/圖像 存儲需求 以及 訪問性能,這一些隨著用戶需求的不斷增加(全球化時代 上層互聯(lián)網(wǎng)應(yīng)用在高速發(fā)展,單服務(wù)器的存儲體量在不斷增加,存儲更大性能更快是當(dāng)時的服務(wù)器存儲的必然趨勢。。。),滿足不了需求的SGI 需要開辟新疆土,所以就有了XFS。
2. 需要解決的問題
這里新設(shè)計的 XFS 需要解決的問題基本就是前面設(shè)計背景中描述的EFS的現(xiàn)有功能/性能問題,會對每一個問題做一個展開描述。
2.1 異常恢復(fù)太慢
EFS 是基于 BSD的 Fast File System(不太熟) 設(shè)計的,在機(jī)器異常之后啟動一個守護(hù)程序重新 從磁盤 load 文件系統(tǒng)的元數(shù)據(jù),達(dá)到一個一致性狀態(tài)。這個過程會需要 fsck 不斷的檢查一個 8G 的文件系統(tǒng)中 上百個inode 需要花費幾分鐘的時間(HDD的帶寬應(yīng)該有百M,這么慢的話大概率還是文件系統(tǒng)設(shè)計的問題),隨著磁盤容量得不斷增加, 當(dāng)達(dá)到TB 級別以及 上萬的 inodes,如果還是這樣 recovery 速度是不能忍受的。
這里啟動 fsck check 一致性的過程應(yīng)該是 檢查了全量文件,后面的XFS 設(shè)計中就只會檢查元數(shù)據(jù)了。
2.2 不支持大文件系統(tǒng)
這里也就是 EFS 不支持 管理大文件系統(tǒng)容量。SGI 希望文件系統(tǒng)能夠支持 PB級別的容量管理功能,但是當(dāng)時業(yè)界主流的文件系統(tǒng)基本都是 GB 級別,像是EFS 就僅僅支持8GB。因為EFS 管理文件系統(tǒng)空間的數(shù)據(jù)結(jié)構(gòu)是沒有辦法動態(tài)擴(kuò)展的,它用 32bit的 bitmap指針管理磁盤空間,32bit 的指針最多能夠管理40億的block,即使每一個block 的大小是8K ,最多也只能管理32T 的空間。
2.3 不支持大型稀疏文件
當(dāng)時的業(yè)界也沒有支持全量 64bit 的 稀疏文件存儲。稀疏文件便于壓縮,這樣的文件一般是針對大視頻處理之后形成的。
2.4 不支持大型連續(xù)文件
EFS支持 超大連續(xù)塊的存儲下讀性能不友好。EFS 使用的是 bitmap 數(shù)組結(jié)構(gòu)來管理文件系統(tǒng)中的空間分配和釋放記錄。想要在一段超大連續(xù)空間中讀取指定的部分區(qū)域,查找性能并不會特別好。因為寫入的時候在連續(xù)的磁盤空間上寫入(順序?qū)?#xff09;本身對HDD性能非常友好,但是讀的時候在超大文件下的查找(即使是二分) 因為bitmap 數(shù)組結(jié)構(gòu)的限制 會產(chǎn)生多次i/o,而如果不分配連續(xù)塊,那寫性能將會巨差。
2.5 不支持大目錄
EFS 并不支持一個目錄下 上千的文件管理機(jī)制。還是性能問題,因為大多的文件系統(tǒng)當(dāng)時從一個目錄下找一個文件是需要順序遍歷這個目錄下的文件(懷疑目錄項下的文件管理用的鏈表),還有一些使用的是hash 數(shù)據(jù)結(jié)構(gòu),這對點查性能友好,但是大范圍掃描整個目錄文件的時候性能也會很差。
當(dāng)時的 NTFS 則使用 Btree 對目錄下的文件entries 進(jìn)行管理。
2.6 不支持過多文件個數(shù)
當(dāng)時的EFS 理論上在一個文件系統(tǒng)內(nèi)支持超大數(shù)量的文件,但是實際過程中并非如此。因為E FS 在創(chuàng)建文件提供的時候就已經(jīng)分配好了足量個數(shù)的 inodes,這在文件系統(tǒng)并沒有太多文件的情況下對磁盤空間浪費較為嚴(yán)重。同樣也為文件系統(tǒng)管理如此巨量 的inode 帶來負(fù)擔(dān),尤其是寫入了很少的文件卻需要從如此巨量的inode 中查找。
總之,因為EFS 內(nèi)部架構(gòu)設(shè)計和各個小組件的數(shù)據(jù)結(jié)構(gòu)選型,導(dǎo)致當(dāng)前文件系統(tǒng)的各種功能并不完備,存在較多問題,所以 全新的文件系統(tǒng) XFS 設(shè)計迫在眉睫。
3 XFS 架構(gòu)
基本架構(gòu)如下
這個當(dāng)時 (1996)年最初的XFS 基本架構(gòu)。
和其他傳統(tǒng)文件系統(tǒng)一樣,都有一個 transaction manager 以及 volumn manager。XFS 支持了標(biāo)準(zhǔn)的 UNIX 和 POSIX 的語義,在當(dāng)時的 SGI 自己的內(nèi)核 IRIX 中基本使用了內(nèi)核所提供的有利特性,包括buffer/page cache,dcache(directory cache) 以及 icache(當(dāng)時叫vnode cache)。
整個XFS 架構(gòu)被模塊化為了幾部分:
- 最核心,最重要的就是 space manager。這個模塊用來管理文件系統(tǒng)的空間釋放和 inode的分配 以及 單個文件內(nèi)部空間的分配。
- IO manager。用來管理文件系統(tǒng)下發(fā)的i/o請求,依賴space manager 進(jìn)行請求空間的分配和釋放,并且需要持續(xù)追蹤每一個文件的空間。
- Directory manager。管理文件系統(tǒng)的 名字空間。
- Buffer Cache。用于緩存前面的管理數(shù)據(jù)結(jié)構(gòu),將本應(yīng)該存儲在磁盤上的這一些結(jié)構(gòu)緩存到內(nèi)存中,加速訪問。而且 buffer cache 是 被整個os 所有進(jìn)程訪問的。
- Transaction manager。用于用戶對一個文件元數(shù)據(jù)的原子更新需求。這有利于加速文件系統(tǒng)的crash recovery。
- Volumn manager 主要是 XFS 自己做的屏蔽不通 disk driver的組件,能夠方便對接不同的磁盤驅(qū)動,簡化文件系統(tǒng)的實現(xiàn)(不需要為每一個磁盤驅(qū)動實現(xiàn)對應(yīng)的調(diào)度接口,當(dāng)然后來linux kernel 的 generic block layer 更完備得做了這個事情,只是當(dāng)時SGI 是自己的服務(wù)器,自己維護(hù)的os)。
因為XFS 全新的設(shè)計,更完備的功能和更高的性能支持,其復(fù)雜度也更高,SGI 第一版本的XFS 實現(xiàn)已經(jīng)超過50000 行 代碼,而對應(yīng)其內(nèi)部的EFS 才12000 行代碼。
這里簡單匯總一下 xfs 實現(xiàn)過程中對b+ tree 的鐘愛:
- 追蹤磁盤空閑空間的數(shù)據(jù)結(jié)構(gòu) 從之前的bitmap 變更為了b+ tree。
- 目錄項下的文件管理數(shù)據(jù)結(jié)構(gòu)也從之前的線性查找數(shù)據(jù)結(jié)構(gòu)變更為了 b+tree.
- B+tree 管理extent map,再由 extent map管理inodes,從而達(dá)到對整個文件系統(tǒng)inodes 的管理。
- B+tree 用于追蹤文件系統(tǒng) inodes 的動態(tài)分配
接下來看看 XFS 實現(xiàn)過程中如何解決之前 EFS 的問題的。
4 痛點解決
4.1 Allocation Groups
XFS 支持全64bits 的存儲管理。內(nèi)部用到的所有計數(shù)變量都是 64bits 長度(block address 以及 inode nubmer)。為了充分利用 64bits 的并行性和可伸縮性,且 避免XFS 內(nèi)部所有的數(shù)據(jù)結(jié)構(gòu)都擴(kuò)展到64bits,這里XFS 將文件系統(tǒng)拆分成不同的 region,也就是 AGs,當(dāng)然也會考慮磁盤訪問的局部性來利用AG 設(shè)計存儲方式(畢竟。。。HDD的隨機(jī)I/O 實在是不忍直視)。
每一個AG 管理整個文件系統(tǒng)的一部分容量,且不通 AG 之間可以并行操作。每一個AG 大小是 500M --> 4G 之間(現(xiàn)在已經(jīng)支持到了16M-- 1TB 之間)。每一個AG 有自己的獨立數(shù)據(jù)存儲區(qū)域,在自己的邊界區(qū)域內(nèi),管理自己內(nèi)部的空閑空間和inodes。
AG結(jié)構(gòu) 的設(shè)計目的 就是前面提到的提升 64bits 的文件系統(tǒng)并發(fā)訪問 以及 文件系統(tǒng)的可伸縮性, 但是要說提升磁盤訪問的局部性 這個 很少,主要是用在目錄項的存儲中。因為文件系統(tǒng)創(chuàng)建的文件會分布在不同的AG內(nèi)部,如果創(chuàng)建了目錄,那針對這個目錄下創(chuàng)建的文件 inodes 和 blocks 索引都會放在這個目錄對應(yīng)的AG內(nèi)部,利用 磁盤訪問的局部性 (os 預(yù)讀)加速讀性能。不同的AG 內(nèi)部可以通過 文件系統(tǒng)全局的 ag 指針/files/directories 來訪問整個文件系統(tǒng)其他 AG 的文件。
當(dāng)然AG 設(shè)計最主要的目的是為了 提升64bits 下的并發(fā)訪問性能 和 空閑空間管理以及 inodes 分配的性能。因為 SGI 的EFS 都是單線程處理 block 的分配和釋放。這種方式隨著文件系統(tǒng)的規(guī)模不斷增加,可能成為性能瓶頸,通過設(shè)計 AG 內(nèi)部 擁有獨立的數(shù)據(jù)結(jié)構(gòu),這樣XFS 文件系統(tǒng)可以 在不同AG 互不影響的情況下 并發(fā)調(diào)度 一些 釋放/分配 磁盤空間的操作。
更詳細(xì)的AG 設(shè)計后面的系列文章會展開。
4.2 Manging Free Space
空間分配/釋放的性能 和 可擴(kuò)展性 是衡量一個好的文件系統(tǒng)的基礎(chǔ)。能夠高效的分配和釋放空間,并且能夠很好得處理空間碎片問題 對文件系統(tǒng)的性能至關(guān)重要。
XFS 在空間管理的數(shù)據(jù)結(jié)構(gòu)上 相比于 EFS 來說做了比較大的改動,在每個AG 內(nèi)部 將EFS原本的 bitmap 換成了b+tree。其中空閑空間的 start block的維護(hù)有一個單獨的b+ tree,同時 length(有多少個空閑塊)的維護(hù)也有一個b+tree,這樣想要查找 一個空閑塊的時候可以根據(jù)傳入的空閑塊的個數(shù)以及 起始空閑塊進(jìn)行,極大得提升了空閑空間的索引效率。
4.3 大文件的支持
在64bits 下支持超大的稀疏文件,也就是允許大文件內(nèi)部有空洞,而這一些空洞不應(yīng)該占用磁盤空間。如果按照傳統(tǒng)的磁盤block 方式來管理一個文件所占用空間的話,那在這種場景下需要管理大量的blocks。XFS 采用了Data extent 的方式,每一個 extent 都是一段連續(xù)的分配給當(dāng)前文件的block 空間,由一個個block offset組成,這樣對于超大文件的空間管理就更加高效了。原本 采用block 的方式 , 可能一個文件需要 百萬級別的block,現(xiàn)在這一些block 都可以聚合成一個大的extent統(tǒng)一管理,在extent 內(nèi)部會盡可能保持 block 的連續(xù)性,甚至隨著文件大小的不斷增加,不同的extent 之間也可以合并。
每一個 Data Extent 是128bits,其中1bits 用來記錄標(biāo)識,高54bits 存儲block 的偏移地址,后52bits 存儲 完整的 block number,后21 bits 存儲block 個數(shù) (一個extent中能夠保存 200w的block,也就是8G 的磁盤空間)。
5 總結(jié)
還有更多 XFS 如何解決 EFS 前面提到的痛點方案,因為 整體的體系較為龐大,這里先做一個記錄,更多的細(xì)節(jié)會慢慢展開。
總結(jié)
以上是生活随笔為你收集整理的XFS 文件系统 (一) :设计概览的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 有谁知道周星驰抢劫处女贞操的那个片段出自
- 下一篇: 求一个qq头像和网名一套!