Google文件系統(三)

譯自The Google File Systemgit

做者:Sanjay Ghemawat, Howard Gobioff, and Shun-Tak Leunggithub

2.7 一致性模型web

GFS支持弱一致性模型。這種模型可以很好地支撐高度分佈式應用,同時實現相對簡單容易。本節討論GFS的一致性保障機制及其對應用程序的意義。數據庫

2.7.1 GFS一致性保障機制緩存

文件命名空間的修改(如文件建立)是原子性的,僅由Master節點控制:命名空間鎖保證了原子性和正確性;Master節點的操做日誌定義了操做的全局順序。安全

數據修改後,文件區域的狀態取決於操做的類型、成功與否、以及是否存在同步修改。 表1列出了各類操做的結果。若是全部客戶端不管從各個副本讀取的數據都是同樣的,則視其文件區域爲一致。若是修改文件數據後,文件區域是一致的,且客戶端可以看到所有寫入操做的內容,則該區域爲「已定義」區域。若是一個數據修改操做成功執行且沒有受到同時執行的其它寫入操做的干擾,則影響的區域就是已定義區域(隱含了一致性):全部的客戶端均可以看到寫入的內容。並行修改操做成功完成以後,區域處於未定義的一致狀態:全部的客戶端能夠看到一樣的數據,但沒法讀取任何一次寫入操做寫入的數據。一般狀況下,文件區域內包含了來自多個修改操做的數據片斷。修改操做失敗會致使區域處於不一致狀態(同時也是未定義狀態):不一樣的客戶在不一樣的時間會看到不一樣的數據。後文將介紹應用如何區分已定義區域和未定義區域。應用程序不須要進一步細分未定義區域的類型。服務器

數據修改操做分爲寫入和追加兩種。寫入操做把數據寫在應用程序指定的文件位置上。即使存在多個並行修改操做,記錄追加操做能夠至少把數據原子性地追加到文件中一次,可是追加位置取決於GFS。GFS給客戶端返回一個位置信息,標記了包含寫入記錄的已定義區域的起點。另外,GFS可能會在文件中間插入填充數據或者重複記錄。通常認爲,這些數據佔據的文件區域是不一致的,且這類數據一般比用戶數據小不少。網絡

完成一系列成功修改操做以後,GFS確保被修改的文件區域是已定義的,且包含最後一次修改操做寫入的數據。GFS 經過如下措施確保上述行爲:(a)按照一樣的順序對數據塊的全部副本進行修改操做,(b)經過數據塊版本號檢測副本是否因其所在的數據塊服務器宕機錯過了修改操做,最終致使其失效。失效的副本不會再進行任何修改操做,Master服務器也再也不將該數據塊副本的位置信息返回給客戶端。這些副本一經發現,便會被垃圾收集系統回收。架構

因爲數據塊的位置信息會被客戶端緩存,因此在信息刷新前,客戶端有可能從失效的副本讀取數據。在緩存的超時時間和文件下一次被打開的時間之間存在時間窗,文件再次被打開後會清除緩存中與該文件有關的全部數據塊的位置信息。並且,因爲咱們的大多數文件只進行追加操做,所以失效的副本一般返回提早結束的數據塊而不是過時的數據。當讀取程序嘗試從新聯繫Master服務器時,便會馬上獲得數據塊最新的位置信息。併發

即便在修改操做成功執行很長時間以後,組件的失效也可能損壞或刪除數據。GFS經過Master服務器和全部數據塊服務器的按期通訊定位失效的數據塊服務器,並使用校驗和來校驗數據是否損壞。一旦發現問題,要儘快利用有效副本恢復數據。若是在GFS檢測到並採起措施以前(通常只須要幾分鐘),數據塊的全部副本已經所有丟失,該數據塊便徹底沒法恢復了。不過在這種狀況下,數據塊也只是不可用了,而不是損壞了:應用程序會收到明確的錯誤信息而非損壞的數據。

2.7.2 應用程序的實現

結合一些簡單的技術,GFS應用程序的弱一致性模型還能實現其它功能,包括:儘可能採用追加寫入而不是覆蓋,Checkpoint,自驗證寫入,自標識記錄。

在實際應用中,咱們全部的應用程序都儘可能採用追加而非覆蓋的方式對文件進行寫入操做。一般狀況下,應用程序從頭至尾寫入數據,生成了一個文件。寫入全部數據以後,應用程序自動將文件更名爲永久保存的文件名;或者週期性地進行Checkpoint,記錄成功寫入的數據數量。Checkpoint文件可能包含程序級別的校驗和。讀取程序僅校驗並處理上個Checkpoint以後產生的文件區域,這些文件區域爲已定義狀態。這個方法知足了咱們除一致性和併發處理以外的需求。追加寫入比隨機寫入效率更高,且可以更快地從應用程序失效中恢復。Checkpoint可以讓寫入程序不斷從新開始,而且能夠防止讀取程序處理已經被成功寫入但從應用程序的角度來看還沒有寫入完成的數據。

另一種典型的應用場景是多個應用程序同時向同一個文件追加數據進行結果合併或以生產者-消費者隊列的形式進行數據追加。記錄追加方式中,「至少一次追加」的特性保證了寫入程序的輸出。讀取程序經過下面的方式處理偶然填充和重複內容。寫入程序的每條記錄都包含了額外信息,例如用於驗證有效性的驗證和。讀取程序能夠利用驗證和識別並拋棄額外的填充數據和記錄片斷。若是應用不能容忍偶然的重複內容(如重複數據觸發了非冪等操做),能夠用記錄的惟一標識符進行過濾。惟一標識符一般用於命名程序處理的實體對象,如web文檔。這些記錄I/O功能都在程序共享代碼庫中,而且適用於Google內部其它文件接口的實現。這樣,相同記錄序列和偶然出現的重複數據都被分發到讀取程序了。

3 系統交互

設計系統時,咱們儘可能減小全部操做與Master節點的交互。所以,本節主要介紹客戶端、Master服務器以及數據塊服務器如何經過交互實現數據修改、原子性記錄追加操做和快照功能的。

3.1 租約與修改操做的順序

修改操做會改變數據塊的內容或元數據,包括寫入操做或記錄追加操做等。修改操做會在數據塊的全部副本上執行。咱們經過租約(lease)機制保證多個副本間修改操做順序的一致性。Master節點爲數據塊的一個副本創建一份租約,咱們稱該數據塊爲主數據塊。主數據塊對數據塊的全部修改操做進行排序。全部副本均遵循這一順序進行修改操做。所以,修改操做的全局順序首先由Master節點選擇的租約的順序決定,而後由租約中主數據塊分配的序列號決定。

設計租約機制的目的是爲了儘可能減小Master節點的管理負擔。租約的初始時效爲60秒。不過,只要數據塊被修改了,主數據塊就能夠申請延長租期。申請一般會獲得Master節點的確認並收到延長時間。租約延長請求和批信息一般都是附加在Master節點與數據庫服務器之間的心跳消息中。有時Master節點會試圖提早取消租約(例如,Master節點想撤銷對一個已被更名文件的修改操做)。即便與主數據塊失去聯繫,Master節點仍然能夠安全地在原有租約到期後與另一個數據塊副本簽定新的租約。

圖2爲寫入操做的控制流程。

  • 客戶機向Master節點詢問持有當前租約的數據塊服務器以及其它副本的位置。若是尚不存在租約,則Master節點會選擇其中一個副本創建租約。
  • Master節點將主數據塊的標識符以及其它副本的位置信息返回給客戶機。戶機緩存這些數據以便後續的操做。只有在主數據塊不可用或主數據塊回覆信息告知已再也不持有租約時,客戶機才須要與Master節點從新聯繫。
  • 客戶機能夠按照任意順序把數據推送到全部副本上。數據塊服務器接收到數據並保存在其內部LRU緩存中,直到數據被使用或過時。因爲數據流的網絡傳輸負載很是高,經過分離數據流和控制流,能夠基於網絡拓撲狀況對數據流進行規劃,提升系統性能,不須要關注主數據塊保存在哪一個數據塊服務器上。
  • 全部副本都確認收到數據後,客戶機會向主數據塊服務器發送寫入請求。請求標識了此前推送到全部副本的數據。主數據塊爲接收到的全部操做分配連續的序列號,這些操做可能來自不一樣的客戶機,序列號保證操做會按順序執行,並將操做應用到本地狀態。 主數據塊將寫入請求傳遞到全部二級副本。每一個二級副本依照主數據塊分配的序列號執行操做。
  • 二級副本完成操做後便會回覆主數據塊。
  • 主數據塊服務器回覆客戶機。任何副本產生的任何錯誤都會返回給客戶機。出現錯誤時,寫入操做有可能在主數據塊和部分二級副本上執行成功。(若是操做在主數據塊上失敗了,操做就不會被分配序列號,也不會被傳遞。)客戶端的請求被確認爲失敗後,被修改的區域便會處於不一致狀態。客戶機代碼會重複執行失敗的操做。重複執行操做前,客戶機會先嚐試重複步驟(3)到步驟(7)。

若是應用程序一次寫入的數據量很大或數據跨越了多個數據塊,GFS客戶機代碼會把數據分紅多個寫入操做。這些操做都遵循前述控制流程,但可能會被其餘客戶機上同時進行的操做打斷或覆蓋。

所以,共享文件區域的尾部可能包含來自不一樣客戶機的數據片斷,但因爲這些分解後的寫入操做在全部副本上都按照相同的順序執行完成,所以數據塊的全部副本都是一致的。這使文件區域處於一致但未定義的狀態。

參考資料

  1. Sanjay Ghemawat, Howard Gobioff, and Shun-Tak Leung. The Google File System
  2. Yan Wei. The Google File System中文版

官方網站

開源地址

UAVStack已在Github上開放源碼,並提供了安裝部署、架構說明和用戶指南等雙語文檔,歡迎訪問-給星-拉取~~~

掃一掃下方二維碼,關注一個不會讓你失望的公衆號

相關文章
相關標籤/搜索