理解 Linux 文件系統——EXT4
現在主流的 Linux 發行版默認的文件系統都已經是 ext4 文件系統了,只有少數早一點的發行版還以 ext3、ext2 作為默認文件系統,再往回看,甚至默認 ext 文件系統的發行版也是存在的。
如果你剛接觸 Linux ,接觸到 Linux 文件系統時,那麼你可能會問 ext4 相較 ext3 有什麼優勢,甚至可能想知道 ext4 是否仍然正處在積極開發的狀態,畢竟當下其他文件系統似乎更受人們關注(例如: btrf、xfs、zfs )。
由於篇幅原因,本文不會詳細介紹文件系統的具體細節,我們將會從整個 Linux 文件系統的發展歷史開始介紹,闡述各個文件系統的特點,以及未來的展望。
Ext 文件系統簡介
MINIX 文件系統
在 ext 出現以前,就已經有了 MINIX 文件系統。如果你不了解 Linux 的歷史,其實 MINIX 其實是 IBM PC/AT 微型計算機的一個非常小的類 Unix 操作系統。在 1987 年的時候, Andrew Tannenbaum 以教學目的開發它,並發布它的源代碼(以列印到文檔上的形式)。
雖然你可以仔細閱讀 MINIX 的源代碼,但它實際上並不是免費的開源軟體( FOSS )。 Tannebaum 書籍的出版商需要 69 美元的授權費來運營 MINIX ,這也是此書的主要成本。即便如此,但這段時間的成本卻非常低廉,並且 MINIX 被迅速廣泛應用,很快就超過了 Tannenbaum 的初衷(簡單的使用它作為教科操作系統)。到了90年代,你仍然可以在全世界範圍內的大學裡找到 MINIX 的安裝程序,並且發展得很快。一位叫 Linus Torvalds 的年輕人使用 MINIX 開發了原始的 Linux 內核,該內核於 1991 年首次發布,並於 1992 年 12 月以 GPL 許可證發布。
但是,這是一篇關於文件系統的文章對嗎?是的! MINIX 有它自己的文件系統,並且 Linux 的早期版本也非常依賴於它。就像 MINIX 一樣,它可能會不公平地被描述為一種玩具 —— MINIX 文件系統最多只能處理 14 個字元的文件名,定址只支持 64 MB 的存儲空間。在 1991 年的時候,常見的硬碟已經有 40—140 MB 的大小,Linux 顯然需要更好的文件系統。
ext
當 Linus 開始激烈的開發剛剛興起的 Linux 內核時, RemyCard 開發了第一個 ext 文件系統。這個文件系統於 1992 年最初發布。僅在 Linux 發布的一年後, ext 解決了 MINIX 文件系統最嚴重的問題。
1992 年的 ext 在 Linux 的內核中使用了新的虛擬文件系統( VFS )來作為抽象層。與之前的 MINIX 文件系統不同, ext 最多可以處理 2GB 的存儲空間和 255 個字元的文件名。
但是 ext 的流行時間並不久,主要是因為它的文件時間戳記錄方式太簡陋(每個文件只有一個時間戳,而不是三個獨立的時間戳用於記錄 inode 的創建時間、文件訪問時間,以及文件的修改時間)。但是一年之後, ext2 就幹掉了 ext 。
ext2
Remy 很快就意識到 ext 的局限性,因此一年以後,它將 ext2 作為替代品。現在看來 ext 仍然源於「玩具」操作系統,但 ext2 一開始就被設計為商業級的文件系統,它的原理與 BSD 的 Berkeley Fast File System 相同。 Ext2 能支持達到千兆位元組的最大文件和兆兆位元組的文件系統,在 90 年代的 GNU 聯盟計劃中佔有重要地位。它被迅速且廣泛地被推廣開來,無論是在 Linux 內核還是在 MINIX 中,甚至出現了第三方模塊使其能夠用於 MacOS 和 Windows 。
即便如此,仍然有很多需要解決的問題:同 90 年代的大多數文件系統一樣, ext2 文件系統在數據寫入磁碟時,如果系統崩潰或者斷電,很容易發生災難性的破壞。隨著時間的推移,文件系統中大量的數據碎片會帶來嚴重的性能損失。
這些問題至今仍然存在,但還是有人用 ext2 文件系統,通常還有人在攜帶型 USB 存儲器上使用這種文件系統格式。
ext3
1998 年,在 ext2 文件系統被使用了六年以後, Stephen Tweedie 宣布他正在大力改進它。這就有了接下來的 ext3 文件系統。 ext3 於 2001 年 11 月在 Linux 2.4.15 內核中開始被廣泛使用起來。
在 Linux 發行版中 ext2 在各個場景下都表現得非常好,但和 FAT、FAT32、HFS 以及其他文件系統看來一樣,仍然很容易在斷電時發生嚴重的問題。如果在向文件系統寫入數據時斷電,那麼可能會導致正在保存的文件丟失或損壞,甚至導致整個文件系統無法正常運行。
Ext3 以及其他 20 世紀 90 年代後期的文件系統(如 Microsoft 的 NTFS )都是使用日誌來解決這個問題。日誌是磁碟上的特殊分配,寫入文件可以看成是一次任務。如果該任務完成並寫入磁碟,那麼它在日誌中的數據將寫入固化到文件系統本身。如果在提交操作前系統發生了崩潰,那麼重新啟動的系統將會對其識別成未完成的任務,並對其進行回滾操作,就好像從來沒有發生過一樣。正在處理的文件可能會丟失,但文件系統本身能夠始終保持一致,並且所有的其他數據都是安全的。 ext3 的 Linux 內核實現了三種日誌級別: journal、ordered、writeback 。
- Journal 是風險最低的模式,在數據及元數據提交給文件系統之前將它們寫入日誌。這一操作確保了正在寫入的文件以及整個文件系統的一致性,但會顯著降低性能。
- Ordered 是大多數 Linux 發行版中的默認模式。 ordered 模式將元數據寫入日誌,而數據則是直接提交給文件系統。顧名思義,這項操作的順序是嚴格規定的:首先,將元數據寫入日誌;其次,將數據寫入文件系統,然後才將日誌中的關聯元數據刷新到文件系統本身。這能夠確保在發生崩潰時,已經寫入的不完整的相關元數據仍然存在日誌中,同時文件系統可以在回滾日誌中消除那些不完整文件的寫入。在 ordered 模式下,崩潰可能會導致文件損壞或文件在崩潰期間被主動寫入導致損壞,但是文件系統本身都可以保證未被主動寫入的文件是安全的。
- Writeback 是第三種也是最不安全的日誌模式,在 writeback 模式中,和 ordered 模式一樣,元數據被記錄,但數據不是。與 Ordered 模式不同的是,元數據和數據可以用任何的順序進行編寫,並且這都是有意義的,這樣可以獲得最佳的性能。雖然這樣可以顯著提高性能,但是不太安全。雖然 writeback 模式仍然為文件系統本身提供了安全保證,但是已經寫入的文件在崩潰期間或之前容易發生損壞。
就像之前的 ext2 一樣, ext3 使用 16 位內部定址。當數據存儲塊大小為 4 時,它最大處理的文件大小為 2 TiB 和最大文件系統大小是 16 TiB 。
ext4
Theodore Ts'o ( ext3 主要開發者 ) 在 2006 年發布了 ext4 ,並於兩年後在 Linux 2.6.28 中開始被廣泛使用。 Ts'o 將 ext4 喻為權宜之計,它極大地擴展了 ext3 ,但仍然依賴於舊技術。他預計 ext4 終將會被下一代文件系統所取代。
Ext4 的功能與 Ext3 非常相似,帶來了大文件系統支持、提高了碎片化的抵抗力和性能、改進了時間戳。
TODO
其他文件系統
首先這裡我們需要注意一點:其他可選的文件系統不一定直接進入了你的 Linux 發行版使用的主線內核中,所以需要特別注意這一點。
一般來說,即使一個文件系統十分的可靠,當我們使用該文件系統作為 root 文件系統時,仍然可能由於內核升級時出現問題而造成災難性的結果。所以,如果你不喜歡遇到這種情況下,不得不用其他引導媒介啟動系統後,通過 chroot 進入原來系統並手動修復內核模塊、grub 配置、DKMS 等這樣複雜的操作修復系統,那就最好不要在 root 文件系統上存放對你重要的數據。
所以我們最好沒有特殊需求時,不要使用你的發行版不直接支持的文件系統。如果你確實需要,最好是當你的系統可用時再使用其他文件系統。(比如,使用 ext4 作為你的 root 文件系統,用 zfs 或 btrf 存放你的數據)
XFS
XFS 作為一個非 ext 系列文件系統同樣由 Linux 內核主線主持。XFS 是一個 64 位的高性能日誌文件系統,它從 2001 年開始進入 Linux 內核。XFS 在大文件,高並發的情況下仍然具備非常高的性能。
Red Hat 企業版從 RHEL 7 開始以 ZFS 作為系統默認文件系統。但是,這樣做仍然有一些缺點,特別對於家庭用戶也小型企業用戶來說尤其明顯。想要擴展已存在的 XFS 文件系統非常的蛋疼,甚至有時,重新創建一個更大的 XFS 文件系統,再把數據複製過去來的更痛快。
雖然 XFS 非常的穩定和高性能,但這也不足以說我們可以放棄 ext4 全部推薦使用 XFS 。我們還是推薦使用 ext4 文件系統,除非你遇到大於 50 TB 的文件定址,這個時候你就不能再用 ext4 了。(例如 RHEL 7 這樣的發行版)
XFS 並不能像稱為下一代的文件系統,它不像 zfs、btrf 以及 WAFL (Write Anywhere File Layout)那樣。XFS 和 ext4 一樣,可以說是這一代文件系統中非常出色的文件系統。
ZFS
ZFS 由 Sun Microsystems 開發,以 Zettabyte 命名(Zettabyte File System),相當於1萬億兆位元組。它能存儲1800億億(18.4×1018)倍於當前64位文件系統的數據。ZFS 的設計如此超前以至於這個極限就當前現實實際可能永遠無法遇到。
ZFS 作為正真的下一代文件系統具有非常多的特點。ZFS 提供卷管理(能在單個文件系統中使用多個獨立的存儲設備)、塊級別的校驗和(極高的準確率檢驗數據損壞)、壞區自動修復(通過冗餘或奇偶校驗存儲)、快速非同步增量複製機制、以及內聯壓縮等諸多功能。
從 Linux 用戶的角度來看, ZFS 最大的問題就是許可證的問題。ZFS 以 CDDL 許可證發布,這是一種與 GPL 許可證相互衝突的非完全開放許可證。關於在 Linux 中使用 ZFS 存在很多爭議,到底是 GPL 違規了,還是 CDDL 違規了,又或者說完全沒有問題目前還未在法庭上判決驗證過。值得注意的是,Canonical 在 2016 年開始,已經將 ZFS 納入其默認的內核中了,至今尚無法律挑戰。
就目前而言,即使對於一名非常狂熱的 ZFS 粉來說,我們也不推薦直接用 ZFS 作為 root 文件系統。如果你想要使用到 ZFS 的諸多優點,請在 ext4 上設置一個較小的 root 分區,其他剩餘的存儲使用 ZFS 文件系統。不論如何你夠應該以 ext4 作為 root 文件系統,除非你是用的發行版明確的支持了 ZFS 。
btrfs
Btrfs 是 B-Tree Filesystem 的簡寫,最早在 2007 年 Chris Mason 任職於 Oracle 期間發布。Btrfs 旨在達到和 ZFS 一樣的目標:多設備管理、塊校驗、非同步副本更新、內聯壓縮等。
截止到 2018 年,Btrfs 可以說已經是相當的穩定了,完全可以用作標準的單磁碟文件系統,但是最好不要用它作為卷管理器。在很多場景下,btrfs 相比 ext4、xfs、zfs 在這種情況下會有嚴重的性能問題。並且在作為下一代文件系統應該具備的特性上來看,依舊存在許多的 bug ,非常容易產生性能問題,甚至數據丟失。
事實上, btrfs 的持續狀態備受爭議;SUSE Enterprise Linux 在 2015 年開始使用 btrfs 作為發行版默認文件系統,而 Red Hat 卻宣告從 2017 年發布的 RHEL 7.4 起將不再支持 btrfs 。值得一提的是,生產環境下,btrfs 常常作為單個磁碟的文件系統,不作為像 ZFS 那樣的多磁碟管理器。像 Synology 這樣的公司,他們在存儲設備上使用 btrfs ,但是在分層管理上卻使用 Linux 內核 RAID 來管理磁碟。