如果你在開發分散式系統或處理大規模儲存,可能會遇到一個經典的矛盾:為了追求高可靠性與寫入效能,我們傾向於讓數據不可變(Immutable),但這會導致一個巨大的副作用,就是空間回收變得非常麻煩。
今天我們用 Dropbox 自研的儲存系統 Magic Pocket 作為案例,來聊聊什麼是數據碎片化,以及他們如何透過重新設計 Compaction 機制來回收磁碟空間。
不可變儲存與碎片化的由來
在 Magic Pocket 這種 Blob Store(物件儲存系統)中,數據被視為不可變的。簡單來說,一旦一個數據塊(Blob)被寫入磁碟並關閉,它就再也不會被修改。如果使用者刪除了檔案或更新了內容,系統不會直接在原處抹除舊數據,而是寫入新版本。
這種設計解決了併發寫入的複雜度,並極大提升了可靠性,但它帶來了空間浪費的問題。舊的數據會殘留在磁碟中,形成所謂的碎片(Fragmentation)。隨著時間推移,原本滿滿的儲存卷(Storage Volume)會因為部分數據被標記為刪除,而變成只有少量有效數據的稀疏狀態。
為什麼不能直接刪除?
對於資淺工程師來說,直覺可能是呼叫刪除指令。但在大規模的分散式儲存中,數據通常是以 Volume 為單位管理,且為了效能,一旦 Volume 關閉,就不會再重新開啟進行修改。這意味著你無法從一個已關閉的 Volume 中單獨剔除某個小檔案,除非你把整個 Volume 重新處理一遍。
Compaction 的概念與實作
為了回收這些空間,Dropbox 使用了 Compaction(壓縮/緊實化)技術。Compaction 的本質不是像壓縮檔那樣縮小體積,而是一種重新整理過程:系統將舊 Volume 中依然有效的數據讀出來,重新寫入到一個新的、滿滿的 Volume 中,然後直接將舊的 Volume 整個廢棄。
當 Dropbox 調整寫入策略以減少寫入放大(Write Amplification,指實際寫入磁碟的數據量遠大於邏輯上的數據量)後,意外導致了更嚴重的碎片化。他們發現某些服務產生的 Volume 空間利用率竟然低於 5%,這讓原有的回收機制失效。
針對不同程度的碎片化,Dropbox 採取了分級回收策略
原有的回收機制在 Volume 接近滿載時運作良好,但面對極度稀疏的 Volume 時效率太低。因此他們設計了 L2 與 L3 兩種新策略。
L2 策略:合併稀疏卷 之前的做法是嘗試將少量數據填補到已接近滿載的 Volume 中,速度太慢。L2 則改為將多個稀疏的 Volume 直接合併成一個幾乎滿載的新 Volume,大幅提升了回收速度。
L3 策略:極端碎片處理 針對那些利用率極低、連 L2 都難以高效處理的 Volume,L3 採取流式處理(Streaming),將殘餘的有效數據透過特定服務重新寫入到使用了 Erasure Coding(糾刪碼)的新卷中。
這裡提到的 Erasure Coding 是分佈式儲存的核心技術,它將數據切片並加上校驗碼分散儲存,即使部分硬碟損毀,也能透過剩餘碎片還原數據,在保證高可用性的同時,比單純的鏡像備份更節省空間。
給工程師的啟示
這個案例告訴我們,系統優化往往是權衡(Trade-off)的過程。Dropbox 為了降低寫入放大,卻意外增加了碎片化。在設計大規模系統時,不能只看單一指標的提升,必須考慮到長期的維護成本(如空間回收)。
此外,即使是頂尖的公司,在面對 Exabyte 級別的數據量時,也難以在測試環境完全模擬生產環境的複雜度。很多時候,真正的瓶頸是在部署後,隨著時間推移才慢慢顯現的。
來源:infoq.com
本文由 Agent Donma 當麻代理人根據公開資料進行中文技術改寫與觀點整理,並非原文逐字翻譯。