文件系統(tǒng)考古 3:1994 - The SGI XFS Filesystem

在 1994 年,論文《XFS 文件系統(tǒng)的可擴(kuò)展性》發(fā)表了。自 1984 年以來(lái),計(jì)算機(jī)的發(fā)展速度變得更快,存儲(chǔ)容量也增加了。值得注意的是,在這個(gè)時(shí)期出現(xiàn)了更多配備多個(gè) CPU 的計(jì)算機(jī),并且存儲(chǔ)容量已經(jīng)達(dá)到了 TB 級(jí)別。對(duì)于這些設(shè)備,僅僅對(duì) 4.3BSD 快速文件系統(tǒng)(或 SGI IRIX 中稱(chēng)為 EFS 的修改版本)進(jìn)行改進(jìn)已不再足夠。(點(diǎn)擊此處

SGI 的基準(zhǔn)測(cè)試中采用的計(jì)算機(jī)擁有大型背板和多個(gè)控制器(其中一項(xiàng)基準(zhǔn)測(cè)試采用了一個(gè)具有 20 個(gè) SCSI 控制器的設(shè)備),大量的磁盤(pán)(上百塊硬盤(pán)驅(qū)動(dòng)器)以及多個(gè) CPU(12個(gè) CPU 插槽)和大量?jī)?nèi)存(最高1GB)。

SGI 是一家制造高性能計(jì)算機(jī)(HPC)和圖形工作站的企業(yè)。在 20 世紀(jì) 80 年代和 90 年代,SGI 是計(jì)算機(jī)圖形和可視化領(lǐng)域的先驅(qū)和領(lǐng)導(dǎo)者。在進(jìn)行基準(zhǔn)測(cè)試時(shí),SGI 會(huì)使用一系列具有特定配置的計(jì)算機(jī)設(shè)備,并進(jìn)行性能測(cè)試和比較,以評(píng)估其系統(tǒng)的性能和能力。

然而,SGI 在 2009 年申請(qǐng)破產(chǎn)保護(hù),并在 2016 年以“Silicon Graphics International”為名重組,繼續(xù)致力于提供高性能計(jì)算和數(shù)據(jù)分析解決方案。SGI 在計(jì)算機(jī)發(fā)展史上留下了重要的足跡,并對(duì)計(jì)算機(jī)圖形和可視化領(lǐng)域產(chǎn)生了深遠(yuǎn)的影響。

IRIX 6.5 Desktop

當(dāng)前所需的文件系統(tǒng)處理能力已經(jīng)超出了 FFS(Fast Filling System),文件的大小也超過(guò)了 FFS 可以的處理能力,目錄中的文件數(shù)量增大導(dǎo)致查找時(shí)間過(guò)長(zhǎng),像分配位圖(allocation bitmaps)這樣的中央數(shù)據(jù)結(jié)構(gòu)無(wú)法進(jìn)行有效的擴(kuò)展,并且全局鎖在多個(gè) CPU 的情況下會(huì)造成低效的文件系統(tǒng)并發(fā)訪(fǎng)問(wèn)。于是,SGI 決定設(shè)計(jì)一個(gè)完全不同的文件系統(tǒng)。

此外,整個(gè) Unix 社區(qū)也面臨著來(lái)自 David Cutler 和 Helen Custer 的挑戰(zhàn),他們開(kāi)發(fā)了 Windows NT 4.0 的開(kāi)發(fā)者。通過(guò) Windows NT 4.0 中的 NTFS,他們展示了從頭開(kāi)始設(shè)計(jì)系統(tǒng)的可能性。

新要求

XFS 文件系統(tǒng)充滿(mǎn)了創(chuàng)新思想,與傳統(tǒng)的 Unix 文件系統(tǒng)設(shè)計(jì)有很大的不同。其中的新特性包括:

  • 通過(guò)以下方式實(shí)現(xiàn)并發(fā)性

    • 分配區(qū)域
    • Inode 鎖分離
    • 大規(guī)模并行 I/O 請(qǐng)求、DMA 和零拷貝 I/O 功能
  • 通過(guò)以下概念,提高訪(fǎng)問(wèn)的可擴(kuò)展性

    • B+樹(shù):一種平衡的多路搜索樹(shù),可以有效地存儲(chǔ)和檢索大量的數(shù)據(jù);
    • extent:一種用來(lái)描述連續(xù)的磁盤(pán)塊的數(shù)據(jù)結(jié)構(gòu),由(起始?jí)K,長(zhǎng)度)兩個(gè)字段組成2;
    • 將“文件寫(xiě)入”和“文件在磁盤(pán)上的布局”分離,以便通過(guò)使用延遲分配和預(yù)分配來(lái)實(shí)現(xiàn)連續(xù)的文件。

extent(區(qū)段)表示文件在磁盤(pán)上連續(xù)的一段數(shù)據(jù)塊。每個(gè) extent 由一個(gè)起始位置(start)和一個(gè)長(zhǎng)度(length)描述符組成,用于指定文件在磁盤(pán)上的物理存儲(chǔ)位置。通過(guò)使用 extent,文件系統(tǒng)可以實(shí)現(xiàn)動(dòng)態(tài)增長(zhǎng)的 I/O 大小,從而提高吞吐量。extent 的概念還可以與延遲分配和預(yù)分配相結(jié)合,以?xún)?yōu)化文件的布局,使得文件在磁盤(pán)上可以連續(xù)存儲(chǔ)。這種連續(xù)存儲(chǔ)可以減少磁盤(pán)尋址的開(kāi)銷(xiāo),提高文件讀寫(xiě)的效率。

  • 引入預(yù)寫(xiě)日志(write-ahead log)以記錄元數(shù)據(jù)更改
    • 異步記錄日志以實(shí)現(xiàn)寫(xiě)入合并
    • 利用日志進(jìn)行恢復(fù),使恢復(fù)時(shí)間與正在處理的數(shù)據(jù)量成比例,而不是與文件系統(tǒng)的大小成比例。

XFS 是為了滿(mǎn)足這些特性而開(kāi)發(fā)的,實(shí)現(xiàn)這些特性后就可以在視頻編輯、視頻服務(wù)和科學(xué)計(jì)算等領(lǐng)域充分發(fā)揮大型 SGI 設(shè)備的性能。

一個(gè)不使用日志結(jié)構(gòu)的日志文件系統(tǒng)

在約同一時(shí)期,John K. Ousterhout 提出了一個(gè)問(wèn)題:“為什么操作系統(tǒng)的速度沒(méi)有跟上硬件的發(fā)展速度?Ousterhout 開(kāi)始在實(shí)驗(yàn)性的 Sprite 操作系統(tǒng)中探索基于日志的文件系統(tǒng)的想法。

Sprite 是一種早期的分布式操作系統(tǒng),最早由John K. Ousterhout 和 Kenneth L. Dickey)于1984年在加州大學(xué)伯克利分校開(kāi)發(fā)。Sprite 的設(shè)計(jì)目標(biāo)是提供高度可靠的分布式環(huán)境,支持在網(wǎng)絡(luò)上連接的多臺(tái)計(jì)算機(jī)之間進(jìn)行協(xié)作和通信。它在學(xué)術(shù)界和研究領(lǐng)域具有一定影響力,為后續(xù)分布式操作系統(tǒng)的發(fā)展奠定了基礎(chǔ)。

基于日志的文件系統(tǒng)是一個(gè)非常激進(jìn)的想法,我們?cè)诤罄m(xù)的文章中會(huì)討論。盡管它們?cè)跁r(shí)間上比 XFS 早一點(diǎn),但這個(gè)概念的引入具有重要的意義。最初它們并不實(shí)用,因?yàn)樗鼈冃枰煌挠布峁└嗟拇疟P(pán)尋道。日志結(jié)構(gòu)化文件系統(tǒng)的理念必須變得更加精細(xì)才能產(chǎn)生實(shí)際影響,我們將在本系列的后續(xù)部分中討論它們。

IRIX 的處境

IRIX 是 Silicon Graphics Inc.(SGI)開(kāi)發(fā)的操作系統(tǒng),用于其工作站和服務(wù)器產(chǎn)品線(xiàn)。它是基于Unix System V 的變種,并包含了許多 SGI 獨(dú)有的功能和優(yōu)化,以適應(yīng)其高性能計(jì)算和圖形處理需求。IRIX 在1988年首次發(fā)布,并成為 SGI 工作站的主要操作系統(tǒng),為許多科學(xué)、工程和創(chuàng)意領(lǐng)域的應(yīng)用提供了強(qiáng)大的計(jì)算和圖形處理能力。

IRIX 最初使用 EFS(Extent File System)作為其文件系統(tǒng),它是 BSD FFS 的一個(gè)改進(jìn)版本,使用了 extents 來(lái)描述文件的連續(xù)磁盤(pán)塊。它受到 8 GB 文件系統(tǒng)大小限制,2 GB 文件大小限制,以及無(wú)法充分利用硬件 I/O 帶寬的影響,這讓許多購(gòu)買(mǎi)了這些昂貴機(jī)器的客戶(hù)感到不滿(mǎn)。后來(lái),SGI 開(kāi)發(fā)了 XFS 文件系統(tǒng)來(lái)取代 EFS,并在 IRIX 5.3 版本中引入了 XFS3。XFS 是一種高性能的 64 位日志文件系統(tǒng),支持大容量存儲(chǔ)、快速恢復(fù)和高級(jí)管理功能。

視頻播放和數(shù)據(jù)庫(kù)社區(qū)對(duì)文件系統(tǒng)提出了新的需求:需要支持?jǐn)?shù)百 TB 的磁盤(pán)空間、數(shù)百 MB/s 的 I/O 帶寬以及許多并行的 I/O 請(qǐng)求,以便能夠充分利用硬件資源,同時(shí)確保不會(huì)出現(xiàn) CPU 資源瓶頸。

“XFS文件系統(tǒng)的可擴(kuò)展性”這篇論文主要展示了它的功能,對(duì)其實(shí)現(xiàn)和設(shè)計(jì)決策進(jìn)行了簡(jiǎn)要討論,也沒(méi)有提供詳盡的基準(zhǔn)測(cè)試。

功能特性

大容量文件系統(tǒng)

XFS 支持大容量文件系統(tǒng)。之前的文件系統(tǒng)使用 32 位的指針來(lái)指向磁盤(pán)塊。塊的大小是 8 KB ,使用 32 位的塊指針,文件系統(tǒng)的上限是 32 TB。

當(dāng)使用 64 位的塊指針會(huì)導(dǎo)致許多數(shù)據(jù)結(jié)構(gòu)的大小變成 8 字節(jié)的倍數(shù),這樣的操作會(huì)造成一些些浪費(fèi)。

為了提高并發(fā)性(參見(jiàn)下文),XFS引入了“分配組”(Allocation Groups,簡(jiǎn)稱(chēng)AG)的概念,其大小總是小于 4GB。分配組(AG)擁有本地實(shí)例,這些實(shí)例具備文件系統(tǒng)數(shù)據(jù)結(jié)構(gòu),例如,inode 映射或空閑塊跟蹤。這些本地實(shí)例可以獨(dú)立進(jìn)行加鎖,從而允許在不同的分配組中進(jìn)行并發(fā)操作。

分配組(AG)還有助于減小指針的大?。阂话憬M內(nèi)編號(hào)可以用 32 位指針表達(dá)。事實(shí)上,一個(gè) 4GB 的分配組可以容納最多 1M 個(gè)塊的塊,因?yàn)槊總€(gè)塊的最小大小為 4K。組內(nèi)單個(gè)最大的 extent 可以用 40 位(5字節(jié))來(lái)表示(位置和大小各占 20 位)。

文件和文件系統(tǒng)最大值為 8 EB(2^63-1)。

帶寬和并發(fā)

XFS 的設(shè)計(jì)目標(biāo)之一就是并發(fā)操作。1994 年是 20 MB/s SCSI 控制器的時(shí)代,SGI 構(gòu)建了能夠容納多個(gè)控制器和多個(gè)驅(qū)動(dòng)器的大型機(jī)箱?;鶞?zhǔn)測(cè)試引用了具有 480 MB/s 總帶寬的計(jì)算機(jī),其文件 I/O 性能超過(guò) 370 MB/s,無(wú)需進(jìn)行任何調(diào)整,包括所有開(kāi)銷(xiāo)。這對(duì)于當(dāng)時(shí)的日常使用來(lái)說(shuō)是相當(dāng)令人印象深刻的。

XFS 通過(guò)使用大塊(4 KB或8 KB塊大小)和extents 概念來(lái)實(shí)現(xiàn)這一點(diǎn)。

Extent 和二叉樹(shù)

在 XFS 中,“extent” 是一個(gè)核心概念,它通常是一個(gè)包含兩個(gè)字段的元組(起始?jí)K和長(zhǎng)度)。將文件塊映射到磁盤(pán)塊(“bmap”)時(shí),“extent” 則包含三個(gè)元素,即一個(gè)三元組(偏移量,長(zhǎng)度,起始?jí)K)。由于分配組(AG)存在上限值,可以用一系列 4 字節(jié)的 extent 來(lái)描述連續(xù)的多達(dá) 2M 個(gè)數(shù)據(jù)塊,這比 BSD FFS 之前的方法更為高效。

extent 也使 XFS 能夠進(jìn)行大規(guī)模 I/O 請(qǐng)求。源于它們描述了連續(xù)的塊區(qū)域,這樣可以輕松創(chuàng)建讀取或?qū)懭攵鄠€(gè)塊的請(qǐng)求。默認(rèn)情況下,它使用 64 KB 的內(nèi)存緩沖區(qū)進(jìn)行 I/O 操作,除非有特殊規(guī)定使用更大的內(nèi)存緩沖區(qū)。

XFS 通過(guò)條帶化(striping)來(lái)管理底層磁盤(pán)結(jié)構(gòu),并支持同時(shí)處理 2 或 3 個(gè)并發(fā)的 IO 請(qǐng)求。它會(huì)檢查反壓(backpressure),也就是檢查應(yīng)用程序是否實(shí)際上在讀取數(shù)據(jù)。如果是的化,文件系統(tǒng)會(huì)發(fā)出額外的讀取請(qǐng)求,以保持默認(rèn)情況下最多 3 個(gè)請(qǐng)求同時(shí)進(jìn)行,這樣可以一次處理 192KB 的數(shù)據(jù)。

extent 組被組織成一個(gè)線(xiàn)性的列表,但這會(huì)導(dǎo)致擴(kuò)展性問(wèn)題。因此,XFS 使用 B+ 樹(shù)來(lái)處理多個(gè)索引塊的情況,如果只有一個(gè)索引塊時(shí),則退化為線(xiàn)性列表。

B+ 樹(shù)是一種樹(shù)狀數(shù)據(jù)結(jié)構(gòu),用于組織和管理 extent 組。它允許在大規(guī)模的 extent 組集合中高效地進(jìn)行搜索、插入和刪除操作。B+樹(shù)結(jié)構(gòu)能夠有效地處理大量的 extent 組,并且具有較好的擴(kuò)展性和性能。

通常,元組是根據(jù)其第一個(gè)值進(jìn)行索引,但對(duì)于某些結(jié)構(gòu)(如空閑列表),會(huì)保留多個(gè)索引:通過(guò) startblock 索引進(jìn)行接近性的空間索引是有用的,但也按 length 索引來(lái)適配正確的可用空間。

去掉每個(gè)文件的寫(xiě)鎖

Posix鎖定內(nèi)存中的 inode 以保證原子寫(xiě)入。這確保了任何兩個(gè)大型多塊寫(xiě)操作總是按順序進(jìn)行。

XFS還去掉了內(nèi)存中的 inode 鎖:Posix 要求對(duì)于大型、重疊的多塊寫(xiě)操作進(jìn)行完全有序的處理。當(dāng)它們重疊時(shí),不能出現(xiàn)從寫(xiě)操作 A 和寫(xiě)操作 B 交替出現(xiàn)的塊混亂現(xiàn)象。

在大多數(shù)內(nèi)核中,默認(rèn)設(shè)置是在內(nèi)存中的 inode 上放置一個(gè)文件全局鎖,以此確保每個(gè) inode 只能有一個(gè)寫(xiě)入者。數(shù)據(jù)庫(kù)的開(kāi)發(fā)者對(duì)此非常不滿(mǎn),因?yàn)樗鼘⑷魏螁蝹€(gè)文件的寫(xiě)并發(fā)性限制為 1。這也是為什么 Oracle 建議將表空間分成多個(gè)文件來(lái)實(shí)現(xiàn)并發(fā)性,每個(gè)文件的大小不超過(guò) 1GB。

O_DIRECT 模式下,XFS 消除了這個(gè)鎖,并允許原子、并發(fā)的寫(xiě)操作,數(shù)據(jù)庫(kù)開(kāi)發(fā)者對(duì)此非常認(rèn)同。

動(dòng)態(tài) inode 和空閑空間跟蹤優(yōu)化

對(duì)于大型文件系統(tǒng),你永遠(yuǎn)無(wú)法預(yù)知:應(yīng)用程序是需要大量的 inode 來(lái)存儲(chǔ)許多小文件,還是少量的大文件。此外,inode 和文件數(shù)據(jù)塊之間的距離是多少也沒(méi)有一個(gè)確定的答案。

對(duì)于第一個(gè)問(wèn)題沒(méi)有一個(gè)好的答案,而對(duì)于第二個(gè)問(wèn)題,答案是“讓它們盡可能接近”。因此,XFS 根據(jù)需要?jiǎng)討B(tài)創(chuàng)建 inode,每次創(chuàng)建 64 個(gè) inode 的塊。

對(duì)于較大的 inode,即 256 字節(jié)的 inode(相比于 BSD FFS 的 128 字節(jié)和傳統(tǒng) Unix 的64字節(jié)),XFS 使用的策略是,僅在需要時(shí)創(chuàng)建 inode,并將它們放置在文件的開(kāi)頭附近來(lái)進(jìn)行補(bǔ)償。這樣可以釋放大量的磁盤(pán)空間。在具有固定 inode 計(jì)數(shù)的傳統(tǒng) Unix 文件系統(tǒng)中,高達(dá)3-4%的磁盤(pán)空間可能被預(yù)先分配的inode 所占用。即使在使用了柱面組(cylinder groups),inode 與第一個(gè)數(shù)據(jù)塊之間仍然存在相當(dāng)大的距離。

由于 inode 可以存在于磁盤(pán)上的任何位置,而不僅僅是超級(jí)塊后面,因此需要對(duì) inode 進(jìn)行跟蹤。XFS 通過(guò)每個(gè)分配組(AG)使用一棵 B+ 樹(shù)來(lái)實(shí)現(xiàn)這一點(diǎn)。該樹(shù)以起始?jí)K為索引,在每個(gè)塊中記錄每個(gè) inode 塊是否可用或正在使用。inode 本身并不保存在樹(shù)中,而是保存在靠近文件數(shù)據(jù)的塊中。

類(lèi)似地,空閑空間以塊為單位進(jìn)行跟蹤,并在每個(gè)分配組(AG)的樹(shù)中進(jìn)行兩次索引:起始?jí)K和長(zhǎng)度索引。

預(yù)寫(xiě)式日志

系統(tǒng)崩潰后要恢復(fù)一個(gè)大型文件系統(tǒng)可能會(huì)很慢?;謴?fù)時(shí)間與文件系統(tǒng)的大小和文件數(shù)量成正比,這是因?yàn)橄到y(tǒng)基本上必須掃描整個(gè)文件系統(tǒng)并重建目錄樹(shù),以確保數(shù)據(jù)的一致性。對(duì)于 XFS 來(lái)說(shuō),文件系統(tǒng)更加脆弱,因?yàn)樗峁┝丝勺償?shù)量的 inode,并且在磁盤(pán)上分散地非連續(xù)存儲(chǔ)?;謴?fù)它們將會(huì)有很大的開(kāi)銷(xiāo)。

使用元數(shù)據(jù)的預(yù)寫(xiě)式日志(write-ahead logging),可以在大部分情況下可以避免這個(gè)問(wèn)題。使得恢復(fù)時(shí)間與日志的大小成正比,即與崩潰時(shí)正在處理的數(shù)據(jù)量成正比。

日志中包含了日志條目,每個(gè)條目包括一個(gè)描述符頭和所有更改過(guò)的元數(shù)據(jù)結(jié)構(gòu)的完整鏡像:包括 inode、目錄塊、空閑 extent 樹(shù)塊、inode 分配樹(shù)塊、分配組塊和超級(jí)塊。由于完整鏡像存儲(chǔ)在塊中,因此恢復(fù)過(guò)程非常簡(jiǎn)單:只需將這些新的、更改過(guò)的鏡像復(fù)制到它們?cè)緫?yīng)該在的位置上,而無(wú)需了解它所更改的結(jié)構(gòu)類(lèi)型。

作者對(duì)日志非常信任:因此 XFS 最初沒(méi)有 fsck (文件系統(tǒng)一致性檢查)程序。然而,事實(shí)證明這種設(shè)置過(guò)于樂(lè)觀(guān)了,因此現(xiàn)在有了 xfs_repair 程序。

元數(shù)據(jù)更新性能

XFS 會(huì)記錄元數(shù)據(jù)更新,這意味著它們需要被寫(xiě)入文件系統(tǒng)日志中。默認(rèn)情況下,該日志會(huì)放置在文件系統(tǒng)中。但也可以選擇將日志提取出來(lái),放置在其他介質(zhì)上,例如閃存存儲(chǔ)或帶有電池備份的內(nèi)存。

如果可能的話(huà),對(duì)日志的寫(xiě)入是異步進(jìn)行的,但是對(duì)于提供 NFS 服務(wù)的分區(qū)來(lái)說(shuō),這種寫(xiě)入只能是同步的。異步寫(xiě)入允許進(jìn)行寫(xiě)入批處理,從而加快速度。但NFS服務(wù)器從加速的日志存儲(chǔ)中獲益很多。

由于所有元數(shù)據(jù)更新都需要被記錄在日志中,因此在進(jìn)行大量元數(shù)據(jù)操作時(shí),可能會(huì)導(dǎo)致日志被洪水般的元數(shù)據(jù)更新所占滿(mǎn)。例如,執(zhí)行 rm -rf /usr/src/linux 這樣的操作就不會(huì)特別快,因?yàn)樵獢?shù)據(jù)更新流最終會(huì)導(dǎo)致日志溢出。而且,由于 XFS 中的其他所有操作都是基于分配組(AG)并行進(jìn)行的,因此日志是可能引起資源競(jìng)爭(zhēng)的唯一來(lái)源。

大文件和稀疏文件

在 FFS(Unix File System)中,文件通過(guò)傳統(tǒng)的動(dòng)態(tài)數(shù)組(dynamic array)進(jìn)行映射,該數(shù)組包括直接塊(direct blocks)和最多三級(jí)的間接塊(indirect blocks)。在64位文件大小的情況下,這種方式就變得很笨拙:會(huì)需要超過(guò)三級(jí)的間接塊,同時(shí)會(huì)需要大量的數(shù)據(jù)塊。由于大量的數(shù)據(jù)塊的存在,塊編號(hào)基本上形成了一個(gè)遞增的數(shù)字列表。這不僅會(huì)增加管理的復(fù)雜性,也會(huì)增大存儲(chǔ)塊編號(hào)的空間開(kāi)銷(xiāo)。FFS(以及 EFS)需要在每個(gè)塊被分配到文件系統(tǒng)緩沖池(filesystem buffer pool)時(shí)就確定它們?cè)诖疟P(pán)上的位置??梢钥吹?,F(xiàn)FS 實(shí)際上沒(méi)有嘗試在磁盤(pán)上連續(xù)布局文件,而是單獨(dú)放置每個(gè)塊。XFS 用 extents 取代了這個(gè)動(dòng)態(tài)數(shù)組。

在文件放置映射(file placement maps)中,這些映射的 extents 是三元組(塊偏移量,長(zhǎng)度,磁盤(pán)塊)。這些 extents 被存儲(chǔ)在 inode 本身中,直到溢出。然后,XFS 開(kāi)始在 inode 中創(chuàng)建一個(gè)由映射 extents 組成的B+樹(shù),通過(guò)邏輯塊號(hào)(logical block number)來(lái)索引映射 extents ,以便進(jìn)行快速查找。

在可以進(jìn)行連續(xù)分配的前提下,這種數(shù)據(jù)結(jié)構(gòu)允許將大量的塊(最多2M個(gè)塊)壓縮為一個(gè)單獨(dú)的描述符。因此,即使是大型文件,也可以在非常少的 extents 中存儲(chǔ),最理想的情況是每個(gè)分配組(AG)只需一個(gè) extent。

實(shí)現(xiàn)連續(xù)布局:延遲分配和預(yù)分配

XFS 引入了一個(gè)新概念:延遲分配,它可以在文件系統(tǒng)緩沖池中分配虛擬 extent。這些預(yù)留的 extent 是用來(lái)存放還未寫(xiě)入的數(shù)據(jù)塊,它們?cè)诖疟P(pán)上還沒(méi)有確定的物理位置。當(dāng)進(jìn)行刷新操作時(shí),這些 extent 會(huì)被填充實(shí)際的數(shù)據(jù),然后按照連續(xù)的方式進(jìn)行布局,并以大塊方式進(jìn)行線(xiàn)性寫(xiě)入。這樣的設(shè)計(jì)可以提高寫(xiě)入操作的效率。

這對(duì)文件系統(tǒng)緩沖區(qū)的工作方式產(chǎn)生了根本性的改變。以前,通過(guò)使用(設(shè)備,物理塊號(hào))可以標(biāo)識(shí)緩沖區(qū)緩存中的塊,以防止重復(fù)分配緩沖區(qū)。然而,當(dāng)將 XFS 移植到Linux時(shí),如果在普通緩沖區(qū)不使用此類(lèi)標(biāo)識(shí),最初 Linux 內(nèi)核無(wú)法適應(yīng)。因此 XFS 需要一個(gè)單獨(dú)的緩沖區(qū)緩存。隨著移植工作的進(jìn)行,這個(gè)問(wèn)題后來(lái)得到了解決。

為了確保文件可以在單個(gè) extent 中進(jìn)行存儲(chǔ)空間分配而不會(huì)出現(xiàn)碎片化,當(dāng)打開(kāi)文件時(shí),XFS 會(huì)積極為其預(yù)分配存儲(chǔ)空間。預(yù)分配的磁盤(pán)空間量是根據(jù)文件系統(tǒng)中的可用空間而確定的,默認(rèn)情況下可能會(huì)預(yù)分配相當(dāng)大的空間。

在互聯(lián)網(wǎng)上,有很多 XFS 用戶(hù)問(wèn)到他們的磁盤(pán)空間在哪里,答案是“在 /var/log 的打開(kāi)文件句柄中。此外,查看手冊(cè)頁(yè)中關(guān)于 allocsize= 的部分,以及/proc/sys/fs/xfs/speculative_prealloc_lifetime 。

局部性

在提高“局部性”方面,XFS 并不太依賴(lài)分配組(AG)來(lái)實(shí)現(xiàn)。分配組主要用于并發(fā)處理。相反,XFS 更多地通過(guò)在目錄和當(dāng)前文件的現(xiàn)有塊周?chē)胖梦募?lái)優(yōu)化數(shù)據(jù)的局部性。唯一的例外是“新目錄”,這些新目錄會(huì)被放置在不同的分配組中,遠(yuǎn)離它們的父目錄。

在大文件中,如果需要分配新的 extent,也就是為新的數(shù)據(jù)塊分配空間時(shí),根據(jù)論文中提到的規(guī)定,“首先靠近 inode ,然后靠近附近的塊”。這樣的設(shè)置方式使得 inode 放置在靠近文件開(kāi)頭的地方,并將后來(lái)添加的塊放置在已有塊的附近。

大目錄

在傳統(tǒng)的 Unix 文件系統(tǒng)和 BSD FFS 中,目錄名稱(chēng)查找是線(xiàn)性操作。對(duì)于任何類(lèi)型的路徑名到 inode 的轉(zhuǎn)換,大目錄會(huì)明顯減慢這一過(guò)程。

XFS 選擇了被廣泛使用的 B+ 樹(shù)作為目錄的數(shù)據(jù)結(jié)構(gòu)。然而,由于鍵(文件名)是可變長(zhǎng)度的結(jié)構(gòu),與其他文件系統(tǒng)中的樹(shù)實(shí)現(xiàn)完全不同。XFS 的作者不喜歡這種情況,因此對(duì)文件名進(jìn)行了哈希處理,將其轉(zhuǎn)換為一個(gè)固定長(zhǎng)度的 4 字節(jié)名稱(chēng)哈希值。然后,將一個(gè)或多個(gè)目錄條目以(名稱(chēng),inode)對(duì)的形式存儲(chǔ)在 B+ 樹(shù)的值中。通過(guò)這種方式,XFS 能夠高效地管理目錄,并在需要時(shí)快速查找和訪(fǎng)問(wèn)特定的文件。這種哈希處理方式允許 XFS 在 B+ 樹(shù)結(jié)構(gòu)中使用固定長(zhǎng)度的鍵,而不需要關(guān)注鍵的實(shí)際長(zhǎng)度。

在這方面進(jìn)行了一些討論,作者們發(fā)現(xiàn)短鍵可以讓每個(gè)塊存儲(chǔ)許多條目,從而形成寬樹(shù),進(jìn)而實(shí)現(xiàn)更快的查找速度。他們自豪地宣稱(chēng):“我們可以擁有數(shù)百萬(wàn)條目的目錄”,這在以前的 Unix 文件系統(tǒng)中是難以想象的。

大量的代碼

在 1994 年的 XFS 基準(zhǔn)測(cè)試中,XFS 顯示出良好的線(xiàn)性擴(kuò)展表現(xiàn),能夠很好地利用硬件資源。它在 多核的大型機(jī)器上表現(xiàn)良好。

XFS 是一個(gè)大型文件系統(tǒng)。Linux 的 ext2 有 5,000 行內(nèi)核代碼(和大約10倍這個(gè)數(shù)量的用戶(hù)空間代碼)。而 XFS 有 50,000 行內(nèi)核代碼,這還不包括 IRIX 卷管理器 XLV(在Linux中,XFS 移植使用的是 LVM2)。

XFS 在 1999 年 5 月以 GNU GPL 許可協(xié)議發(fā)布,并從 2001 年開(kāi)始移植到 Linux 內(nèi)核。截至 2014 年,它在大多數(shù) Linux 發(fā)行版中得到支持,RHEL(Red Hat Enterprise Linux)將其作為默認(rèn)文件系統(tǒng)。

筆者認(rèn)為,XFS 是具有最佳擴(kuò)展性、最佳并發(fā)能力和修改時(shí)間最一致的文件系統(tǒng),這使得它成為任何類(lèi)型的數(shù)據(jù)庫(kù)使用的首選文件系統(tǒng)。它消除了一些全局鎖,這些鎖會(huì)影響大型文件系統(tǒng)的并發(fā)使用和性能,并且使用了具有 O(log(n)) 擴(kuò)展性的 B+ 樹(shù)結(jié)構(gòu),而之前使用的算法擴(kuò)展性都比較差。使用 extent 還允許動(dòng)態(tài)增加 I/O 大小,有利于提高吞吐量,并與延遲分配的新穎思想一起促進(jìn)將文件在磁盤(pán)上連續(xù)地放置或存儲(chǔ)。

如有幫助的話(huà)歡迎關(guān)注我們項(xiàng)目 Juicedata/JuiceFS 喲! (0?0?)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容