超過一百萬個檔案的 NTFS 資料夾…
6 |
在 NTFS 資料夾放入超過一百萬個檔案,會發生什麼事?讀寫檔案會因此變慢嗎?Windows 會不會因此崩潰?
相信很少人有類似經驗,也不會大費周章搞個 Lab 試玩,既然幸運親身體驗過,分享一下經驗。
先說結論:在 NTFS 資料夾放超過一百萬個檔案基本上是可行的(這次遇到的案例超過 150 萬個檔案),若已知完整檔案名稱,讀、寫檔案速度不受檔案數目影響,但會影響檔案總管及部分檔案操作。
我們有個批次轉檔程式會由資料庫讀取資料、存檔後上傳 FTP,每天產生的檔案數約一千筆。因追查問題有時需要檔案內容佐證(跨系統吵架,手握呈堂證供氣勢立刻翻倍呀,你懂的),故需保留檔案。每次調查問題,多半會由資料庫查到檔案名再開 DOS 視窗「notepad 檔名」調閱檔案,用起來很順手方便,感受不到速度延遲,因此大家就忽略了資料夾檔案數每天持續成長,沒人想到要安排定期歸檔搬移排程,就這麼過了七年…
依據 TechNet 文件:NTFS 每個 Volume 的檔案數上限是 4G-1,40 億個檔案放在同一個資料夾理論上是可行的。資料夾使用 B-Tree 結構管理資料,故在已知檔名的前題下,存取檔案的速度不太受同資料夾檔案數多寡影響。資料庫索引也常用 B-Tree 結構儲存索引資料,若已知完整 Key 值,讀取速度不會因為資料筆數倍增明顯下降,也是同樣道理。
關於資料夾可容許的最大檔案數,我沒有找到明確數字。但上述文件提到一個數字(在 Maximum Sizes on an NTFS Volume 段落),如果要在一個資料夾擺放超過 30 萬個檔案,建議停用 8.3 短檔名(尤其是檔名前六碼重複機率很高時),主要是 Windows 會耗費可觀成本避免短檔名重複,推測這只發生在新増或更名時,但是「30 萬」這個數字倒也意味著單一資料夾放幾十萬個檔案仍在 NTFS 設計的容許範圍。
存取檔案速度 OK,問題會出在需要列舉或掃瞄資料夾所有檔案的情境。例如:當資料夾檔案數愈來愈多,就很難再用檔案總管開啟資料夾,一開啟就卡住,甚至導致桌面凍結,只能改用 DOS 視窗,使用 TYPE、COPY 指令存取指定檔名。而且用到 DIR xxxx_*.txt 等篩選條件也會等到地老天荒。這是簡單的數學問題,假設檔案名稱有 32 個字元,100 萬筆檔案清單,光檔名就有 32MB,除了檔名外還有日期時間檔案大小等資料,搜尋時得一一檢查權限,都會消耗記憶體、CPU 並涉及可觀的磁碟 IO 動作。而檔案數一多,系統需串接更多磁區才擺得下目錄資料,列舉檔案清單需由多個零散磁區彙整資料,也會耗費額外的讀取時間。
回到實務案例,雖然已知檔名時讀寫沒什麼感覺,但系統人員發現一些使用上的問題:
- 檔案總管一打開內有百萬筆檔案的資料夾便卡死沒反應,還無法取消或關閉。到最後,「千萬不要點開 XXX 資料夾(很可怕,不要問)」列為系統管理員口耳相傳的交接事項。
- DIR 可以執行列出檔案,但只見檔案清單無窮無盡捲個不停,捲到此恨綿綿無絕期,超越常人的耐心極限,檔案總數與大小始終是謎。
- 單純 DIR 還可以看到檔名狂跑,但 DIR /OD(依日期排序)、DIR *_Blah.txt (篩選檔名特徵)則是一執行就沒反應,直到天荒地老…
- 想用 .NET Directory.GetFiles() 逐一抓取檔案歸檔,GetFiles() 會一次讀入完整清單,結果…
最後,我寫了支 .NET 歸檔程式,將檔案依日期放在 X:\Archive\yyyy\MM\dd\ 目錄下,而歸檔程式的一項挑戰是不能用 Diretory.GetFiles(),需改用 Directory.EnumerateFiles(),傳回 IEnumerable<string>,每次只取一筆,愚公移山奮戰數小時,將舊檔依日期分類,總算馴服這匹脫韁之馬。
後記,查資料在 Stackoverflow 看到一個資料夾放了 1,400 萬個檔案的案例,結論是 NTFS 資料夾能容納的檔案數比想像多很多,但在這種極端情境下要留意其副作用。
Comments
# by oaww
其實我最好奇的是為什麼不留特定區間內的就好XD
# by Jeffrey
to oaww, 理由挺簡單:一開始是沒想那麼多,後來是發懶沒處理,拖著拖著就… 「糟了,是世界奇觀!」XD
# by Ooooops
我猜可能是「硬碟比資料庫」便宜太多太多,所以都存在硬碟(資料夾)裡面吧?
# by 天空
太有趣啦!
# by GregYu
開發一隻小程式 (exe) 解決比較完整, 另外,Dos 下的 XCOPY 指令, 有個 /D:m-d-y 的參數,使用說明為: 複製在指定日期當天或之後發生變更的檔案。 如果沒有指定日期,只複製來源檔案時間比目的地時間新的檔案。 理論上也可以透過 [指令檔 (bat、vbs、ps1)] 的方式處理, 只是要從近期的檔案開始往舊的依序處理...
# by Ryan
https://imgbox.com/JTl3BkoN Windows 10 / 21h2 用迴圈製造檔案,已經超過一千萬個檔案,看起來沒問題,看看極限會到哪裡⋯