系統由一個master以及多個chunkserver構成. 一個文件被切分紅多個大小固定的chunk(默認64MB)並將多個備份(默認3個)存儲在不一樣的chunkserver上.算法
master存儲文件系統的metadata, 包括namespace, access control information, mapping from file to chunks, current locations of chunks.緩存
master週期性的與chunkserver經過心跳包下達指令並監測狀態.安全
client與master通訊得到文件的metadata並緩存後與chunkserver直接通訊進行讀寫.網絡
chunk size設置爲遠超常見的文件系統的64MB, 而且只在須要是分配新的chunk. 較大的chunk size對於系統既有好處亦有壞處.數據結構
優勢:架構
缺點:併發
master將三類metadata維持在內存中, 包括namespace, access control information, mapping from file to chunks, current locations of chunks.app
namespace以及access control information經過operation log持久化存儲在master的本地磁盤上並在遠端備份.負載均衡
current locations of chunks在master啓動時以及新chunkserver加入時主動詢問.dom
metadata被嚴格限制所有維持在內存中, 減小了master操做的時間, 但內存大小限制了GFS存儲數據的大小.
實際上對metadata的存儲作了不少壓縮, 64MB的chunk能夠經過小於64字節的數據維護, 而且經過拓展內存來支持更大容量十分低廉.
master啓動時, 以及有新的chunkserver加入時, master會主動詢問並存儲chunk location.
因爲master控制chunk的置放而且經過心跳包監測, 能夠維持chunk locations信息處在最新態.
operation log記錄了metadata的更新, 而且做爲邏輯時間線定義併發操做的順序. 文件, chunk以及其版本號經過建立時的邏輯時間統一管理.
operation log自己須要可靠存儲, 而且在metadata的更新持久化前保證對客戶端的不可見. 不然master的宕機可能會致使文件或操做的丟失.
所以operation log被存儲在多個機器上, 而且只在本地以及遠端記錄成功後纔會迴應client的操做.
master宕機時經過重作operation log重啓, 爲了保證重啓的速度, 當operation log達到必定的大小時須要對master的狀態作checkpoint, 重啓只需重作operation log中邏輯時間線在最近checkpoint建立時以後的.
當checkpoint建立時失敗, 只需從上次checkpoint處恢復, 雖然可能會增長恢復時間, 但依舊能保證可靠性.
namespace的更新由master保證原子性, 而且由operation log提供可靠性.
consistent: client在全部的副本中看到的數據是相同的.
defined: client寫入的數據可以完整的被看到.
對於record append, 保證appended atomically at least once. GFS可能會在多個defined region之間插入padding以及record duplicates致使inconsistent. 但GFS可以監測到這部分數據並管理, 最終對client是不可見的.
併發更新操做在operation log裏得到邏輯順序並執行, 並經過chunk version檢測chunk的數據是否落後, 落後的數據再也不參與更新操做而且master不會返回其chunk location, 它等待下一次的垃圾回收.
因爲client會緩存metadata, 那麼就有可能直接訪問包含落後數據的chunk. 過時時間以及打開文件會致使client從新向master請求metadata. 另外, 當操做爲append時, 落後的chunk會返回異常的文件結尾, 致使client從新向master請求metadata.
爲了解決組件失效帶來的存儲數據失敗, GFS會經過校驗和檢測到, 並經過備份副本儘快恢復. 當全部備份都不可用時, 數據真正的丟失. 但此時依舊只會收到異常而不是未知的數據.
爲了保證數據的一致性, 更新操做須要在全部的副本中以相同的順序執行. 爲了減小master的負載, master將chunk的某個副本指認爲primary, 並具備必定的過時時間, 全部的更新操做由primary統一管理. client的更新請求直接交付給primary replica.
另外, 在跨chunk寫時, 操做會被切分, 致使會出現寫覆蓋的狀況, 但仍能保證consistent.
流程與寫入流程相似, 但爲了保證原子性, primary在寫入時檢查chunk剩餘容量是否能容納這次操做的數據. 若是不能, primary以及secondaries將會填充直到chunk滿, 並通知client重試操做. 這樣操做就會落到下次請求時建立的新chunk內了.
master對namespace的管理不採用前綴式的數據結構管理(相似字典樹), 但採用前綴壓縮算法節省空間, 同時每一個結點也含有一個讀寫鎖.
當須要對namespace進行更新時, 由根目錄開始不斷獲取讀鎖直到目標路徑的上一級, 再獲取目標路徑的寫鎖. 爲了不獲取鎖時死鎖, 獲取鎖的順序必須嚴格按照namespace層次進行.
master建立chunk時, 依據如下原則選擇chunkserver
當可用備份數量小於目標數量時, 須要re-replicate, 當多個chunk須要re-replicate時, 根據如下因素排序
在複製時, 對選擇哪一個副本進行復制時, 依據如下因素選擇
master週期性地對副本進行負載均衡, 它檢查當前的副本分佈狀況, 而後移動副本以便更好的利用硬盤空間, 更有效的進行負載均衡.
master移走那些剩餘空間低於平均值的chunkserver上的副本, 從而平衡系統總體的硬盤使用率.
GFS 在文件刪除後不會馬上回收物理空間, 只在文件和 Chunk 級的常規垃圾收集時進行.
當文件被應用程序刪除時, master首先記錄到operation log中, 後將文件名改成包含刪除時間的隱藏名. 當master對namespace常規掃描時, 自動刪除必定天數前的隱藏文件的元數據. 所以在刪除元數據前, 能夠經過重命名的方式撤銷刪除.
另外在常規掃描中, master會刪除不被任何文件引用的chunk的元數據, 並在心跳信息中告知chunkserver哪些屬於它的chunk元數據已經不存在了, chunkserver可自行刪除.
垃圾回收相較於直接刪除有以下幾個優點:
垃圾回收的主要問題是會致使用戶調優存儲空間的利用率. 重複建立和刪除臨時文件將致使大量的存儲空間沒法當即重用. 能夠經過顯示的再次刪除以加速時間, 或者對namespace採用不一樣的複製和回收策略.
在master簽定租約, chunk複製時都會附帶chunk的版本號. client和chunkserver會在操做時驗證版本號以保證訪問的chunk數據是最新的.
當master進程失效後, 能夠依據operation log以及checkpoint快速重啓.
當master所在機器宕機後, 因爲operation log是多機器備份的, 所以能夠在其餘機器上從新啓動master進程.
另外還存在shadow master, 他們在master機器宕機後提供文件系統的只讀訪問. 在master正常運行時, 他們和master以及chunkserver通訊以更新元數據. shadow master沒法保證元數據永遠是最新的, 但文件內容是不會過時的.