一則胡亂科普
我爸打電話來,聲稱菜鳥驛站的工作機制可以改進。
驛站現在會將快遞員運來的一車包裹順序地擺放在貨架上。我爸則認為:驛站完全可以把同一個人的包裹擺放在一起,從而優化取件體驗。
我不是學物流的,是學計算機的。而這個問題恰恰與文件系統碎片化問題很接近,於是我寫了這一篇科普。
文件系統碎片化問題(File System Fragmentation) 是指單個文件被分成幾個區段存儲的現象。這使得我們讀取整個文件時,磁盤針頭必須不停地移動,造成嚴重的效率問題。這不是與同一個人的包裹被分成幾個地方擺放的現象很相似嗎?
造成這個問題的原因很簡單。設想這樣一個場景:假設你正在做大作業,要完成 PA.h
與 PA.cpp
兩個文件。你不時地修改兩個文件,插入一些文本。若文件系統簡單地、線性地存儲所有你寫入的內容,這兩個文件自然就都被碎片化地存儲了成了形如:###@@@##@############@@@##@###@@@@@
的樣子。
當然,文本編輯相關的問題是容易解決的。但若考慮從網絡上下載大文件等場景呢?實際上,在 FAT 與 NTFS 一類的文件系統上,這樣的碎片化問題是相當嚴重、影響巨大的。
但 ext4 下則幾乎不存在碎片化問題。Linux 用戶可以試着用 e4defrag
命令檢查自己的硬盤中有多少個文件被碎片化了。一位網友在 Linux ext4 下只有兩個文件被碎片化了,而在 Windows NTFS 下,這個數字是 95%。
這主要依靠 ext4 的幾個偉大機制:
-
預分配(Preallocation)
應用程序可以預先向文件系統申請一塊空間,之后再慢慢完成寫入工作。這可以當然可以保證數據存儲的連續性,尤其是對於一些 P2P 應用程序而言。
而在 NTFS 下,因為預分配機制沒有較好的實現,一些程序(比如百度網盤)在運行時會產生海量的磁盤碎片。一種替代方案是在磁盤上預先寫0占用空間,不過那當然需要相當大的開銷。
-
區塊預留(Block reservation)
最后一次分配區塊的后繼區塊將被預留下來,作為未來文件增改而避免碎片化的備用。
在 NTFS 下,如果順序地新建一系列文件,它們也會被連續地存儲在磁盤中。而后續增加其中文件的內容則會導致碎片化問題。
-
延遲分配(Delayed Allocation)
文件系統會將用戶試圖寫入硬盤的數據暫存,僅當寫入磁盤可以保證區塊數據連續性時才真正寫入對應位置。
盡管許多現代文件系統都采用了這一機制,在 NTFS 下,文件寫入磁盤仍幾乎是實時的。
這幾個機制帶來的改善非常大。根據 Ubuntu 的說法,除非硬盤剩余空間不足 5%,ext4 是幾乎不可能產生磁盤碎片。
計算機環節告一段落,我們回到菜鳥驛站的問題,容易構造這樣的映射:
包裹 -> 數據;文件 -> 收件人;貨架 -> 磁盤;快遞車 -> 寫入;驛站 -> 文件系統
這樣一番對號入座之后,我們能否將 ext4 的幾個機制照搬過來呢?
實際上仍然很困難,物理世界不是計算機。首要的問題是貨櫃空間相對包裹而言並不那么充裕,而整個磁盤相對單個文件而言非常龐大。此外,更有商業上、隱私上的考量:文件系統自然可以輕松地處理多用戶操作,那么驛站能夠打通各家快遞公司的數據庫嗎?
參考閱讀:
Link: https://superuser.com/questions/536788
Link: https://ext4.wiki.kernel.org/index.php/Ext4_Howto
Link: https://www.landley.net/kdocs/ols/2007/ols2007v2-pages-179-186.pdf