在這篇論文之前 — 它所降落的世界
GFS 之前的參照系是 AFS、xFS、Frangipani、GPFS 與 Lustre:這些系統要嘛在用戶端大量快取,要嘛拿掉中央伺服器改用分散式演算法來維護一致性與管理,要嘛追求 POSIX 相容。它們預設機器大致可靠、檔案大致不大、而所謂變更就是在某個位移覆寫位元組,於是冗餘等於 RAID、正確性等於快取一致性。Google 真實的工作負載一次違反了以上全部:資料集動輒數 TB、由數十億份網頁文件組成;數千顆便宜磁碟故障頻繁到連無聲的資料毀損都成了每週例行事件;而寫入端幾乎只做 append。用戶端快取幾乎沒有價值,因為工作是串流掃過遠大於任何快取的資料集;而 POSIX 相容介面要付出的複雜度,解的是 Google 根本沒有的問題。GFS 由同時掌握檔案系統與其上所有應用的團隊寫成,這讓「協同設計 API 與應用」成為正當選項,而不是取巧。
術語 — 依本篇論文的用法
- Chunk
- 檔案被切出的固定 64 MB 片段,在 chunkserver 上就是一個普通的 Linux 檔案,並採延遲配置、需要多少才長多少。每個 chunk 會複寫到多台 chunkserver,預設三份,且可針對命名空間的不同區域設定不同的複寫層級。
- Chunk handle
- master 在建立 chunk 時指派的 64 bit 全域唯一且不可變識別碼。用戶端與 chunkserver 以 handle 加位元組範圍來指名資料,而不是用路徑名,這正是資料流量完全不需要經過 master 的原因。
- Lease 與 primary
- master 授予某個 chunk 複本的一份租約,初始逾時 60 秒,可搭 HeartBeat 續約,被授予者即成為 primary。primary 為該 chunk 的所有變更挑選序列順序,其餘複本一律照此順序套用。
- Record append
- 一種變更操作:用戶端只提供資料,由 GFS 自行選擇位移,保證至少一次原子地追加,並把該位移回傳給用戶端。單筆記錄被限制在 chunk 上限的四分之一以內,好把最壞情況的碎片維持在可接受範圍。
- Consistent 區域
- 所有用戶端不論從哪個複本讀取,都永遠看到相同資料的檔案區域。並行的成功寫入會產生 consistent 但非 defined 的區域,因為所有複本雖套用了相同順序,結果仍混雜了多次變更的片段。
- Defined 區域
- 在 consistent 之上,用戶端還能完整看到某次變更所寫入內容的區域。序列化的成功寫入會產生 defined 區域,成功的 record append 所佔的區段也是;應用則靠 checkpoint 得知哪一段前綴屬於 defined。
- Operation log
- master 唯一持久化的 metadata 記錄,任何變更在本地與遠端都刷到磁碟之前都不會對用戶端可見。它同時是一條邏輯時間線,為並行的 metadata 操作定義全序;檔案與 chunk 也永久以其建立時的邏輯時間來識別。
- Chunk 版本號
- 每個 chunk 一個的計數器,master 在每次授予新 lease 時遞增並持久化,且發生在通知任何用戶端之前。曾離線而漏掉變更的 chunkserver 重啟後會回報較低的版本,其複本在 master 回應用戶端時被視為不存在,並在垃圾回收時清除。
- Shadow master
- 唯讀的 master 複本,套用與 primary 相同的成長中 operation log,通常只落後不到一秒。它在 primary 停擺時維持 metadata 的讀取可用性;由於檔案內容是從 chunkserver 讀的,過時的只可能是 metadata,不會是檔案內容。