1. 程式人生 > 其它 >MIT6.824 lec3 GFS

MIT6.824 lec3 GFS

2022.5.15

3.1 分散式儲存系統的難點(Why Hard)

  • 824主要關注大型儲存,因為簡單的儲存介面往往極其通用,構建分散式系統大多是關於如何設計儲存系統。我們需要關注如何為大型分散式儲存系統設計一個優秀的介面,以及如何設計儲存系統的內部結構,這其中涉及到並行效能,容錯,複製和一致性
  • 人們涉及大型分散式系統或大型儲存系統的出發點是,想要獲取巨大的效能加成,進而利用數百臺計算機的資源同時完成大量工作,效能問題是最初訴求。一個想法是分片,也就是將資料分割到大量的伺服器,這樣就可以並行的從多臺伺服器讀取資料。
  • 由於分片涉及到上千臺機器,所以經常會出現故障,所以需要一個自動化容錯系統
    複製(replication)是實現容錯的一個方法。
  • 為了容錯,需要設定多個副本,那麼副本可能會存在不一致(inconsistency),為了處理不一致,需要不同伺服器之間通過網路額外的互動,這樣會導致低效能。高效能與一致性之間存在矛盾。

3.2 錯誤的設計

  • 在客戶端或應用程式看來,強一致性模型表現得就像是一臺伺服器,一份資料,系統只做一件事。對於儲存伺服器,它上面會有一塊磁碟,執行一個寫請求或許意味著向磁碟寫入一個數據或者對資料做一次自增。如果是一次修改操作,並且我們有一個key-value為索引的資料表單,那麼我們會修改這個表單,如果是一次讀操作,我們只需要將之前寫入的資料,從表單中取出即可即使是對一個無副本的伺服器做兩次寫請求,仍然存在先後問題的模糊場景。
  • 一個簡單的多副本伺服器設計,有兩臺伺服器,每臺伺服器的磁碟都存在資料的拷貝,以太伺服器故障了,可以去讀另一臺伺服器,那麼每一個寫請求都必須寫到兩個伺服器之上,讀請求只需要在一臺伺服器上執行,否則就沒有容錯性了。假設客戶端C1和C2都想執行寫請求,其中一個要寫X為1,另一個寫X為2。C1會將寫X為1的請求傳送個兩個伺服器,因為我們想要更新兩臺伺服器上的資料。C2也會將寫X為2的請求傳送給兩個伺服器。那麼沒有任何事情來保證伺服器以相同的順序處理這2個請求,如果S1先1後2,S2先2後1,則會出現不一致的情況那麼之後兩個客戶端去讀取,資料可能會不一致。可能的解決方法是要客戶端都去讀S1,但是當S1故障之後,客戶端讀的資料將從2變成1
  • 當然可以通過通訊解決這些問題,但是複雜度也會提升

3.3 GFS的設計目標

  • GFS的目標是構建一個大型的,快速的檔案系統,並且這個檔案系統是全域性有效的。一種構建大型儲存系統的方法是針對某個特定的應用程式構建特定的裁剪的儲存系統,但是如果另一個應用程式也想要一個大型儲存系統,那麼又需要重新構建一個儲存系統。如果有一個全域性通用的儲存系統,那就意味著如果我儲存了大量從網際網路抓取的資料,你也可以通過申請許可權來檢視這些資料,因為我們使用了同一個儲存系統,這樣任何Google內部的人員可以根據名字讀取這個GFS中被共享的內容
  • 為了獲取大容量和高速的特性,每個包含了資料的檔案會被GFS自動分割存放在多個伺服器之上,這樣讀寫操作就很快。因為可以並行從多個伺服器上讀取資料,進而獲得更高的聚合吞吐量。將檔案分割還可以在儲存系統中儲存比單個磁碟還要大的檔案
  • 自動修復,在數百臺伺服器上構建儲存系統
  • GFS被設計在一個數據中心執行,所以這裡沒有將副本儲存在世界各地,單個GFS只存在於單個數據中心的單個機房中,雖然著不是設計的目標。理論上來說,資料的多個副本一個彼此之間隔得遠一些,但是實現起來困難
  • GFS是內部使用的系統
  • GFS在各個方面對於大型的順序檔案讀寫做了限制。在儲存系統中有些完全不同的領域,這個領域只對小份資料進行優化。比如一個銀行系統就需要一個能夠讀寫100位元組的資料庫,因為100位元組就可以表示人們的銀行賬戶,但是GFS需要處理TB級別的資料,GFS只支援順序處理,不支援隨機訪問,有點像批處理,GFS並沒有花費過多精力來降低延遲,它只關注巨大的吞吐量
  • GFS具有弱一致性,它表明儲存系統具有弱一致性也是可以的,這樣保證了良好的效能
  • GFS的資料量之龐大,模糊了正確性的判斷,應用程式應當對資料做校驗,並明確標記資料的邊界,這樣應用程式在GFS返回不正確資料時可以恢復

3.4 GFS Master節點

  • 假設我們有上百個客戶端和一個Master節點,儘管實際中可以拿多型機器作為Master節點,但是GFS中Master是Active-Standby模式,所以只有一個Master節點在工作。Master節點儲存了檔名和儲存位置對應關係。除此之外,還有大量的Chunk伺服器,可能會有上百個,每個Chunk伺服器都有1-2快磁碟
  • Master節點用來管理檔案和Chunk的資訊,而Chunk伺服器用來儲存實際的資料。這是GFS設計中比較好的一面,它將這兩類資料管理的問題幾乎完全隔離開了,這樣兩個問題可以使用獨立設計來解決。
    • Master節點知道每一個檔案對應的所有Chunk的ID,這些Chunk每個是64MB大小,它們共同構成了一個檔案。
    • 如果我有一個1GB的檔案,那麼Master節點就知道檔案的第一個Chunk儲存在哪裡,第二個Chunk儲存在哪裡,當我想讀取這個檔案的任意部分,我需要向Master節點查詢對應的Chunk在哪個伺服器上,之後我可以直接從Chunk伺服器讀取對應的Chunk資料
  • 為了處理故障與實現一致性,Master節點儲存了一些資料內容:
    • 第一個表單是檔名到Chunk ID或者Chunk Handle陣列的對應,這個表單告訴你,檔案對應了哪些Chunk。這個資料要儲存在磁碟上,所以標記為NV(non-volatile)
    • 第二個表單記錄了Chunk ID到Chunk資料的對應關係,這些資料包括:
      • 每個Chunk儲存在哪些伺服器上,所以這部分是Chunk伺服器的列表。這個資料不用儲存在磁碟上,因為Master節點重啟之後可以和所有的Chunk伺服器通訊,並查詢每個Chunk伺服器儲存了哪些Chunk
      • 每個Chunk當前的版本號,所以Master節點必須記錄每個Chunk對應的版本號。版本號,我認為其需要寫入磁碟。
      • 所有對於Chunk的寫操作都必須在主Chunk(Primary Chunk)上順序處理,主Chunk是Chunk的多個副本之一。所以,Masrter節點必須記住哪個Chunk伺服器持有主Chunk。Master節點重啟之後會忘記誰是主Chunk,只需要等待60秒租約到期,那麼它知道對於這個Chunk來說沒有主Chunk,所以這時候可以安全的指定一個新的主Chunk,所以標記為V。
      • 並且,主Chunk只能在特定的租約時間內擔任主Chunk,所以Master節點要記住主Chunk的租約過期時間,不用寫入磁碟。
  • 以上資料都儲存在記憶體中,如果Master宕機了,資料就丟失了,為了能使Master重啟而不丟失資料,Master節點會同時將資料儲存在磁碟上,所以Master節點讀資料只會從記憶體讀,但是寫資料的時候,至少一部分資料會寫入到磁碟中,更具體來說,Master會從磁碟上儲存log,每次有資料變更時,Master會在磁碟的log中追加一條記錄,並生成CheckPoint
  • 任何時候,如果檔案擴充套件到達了一個新的64MB,需要新增一個Chunk或者由於指定了新的主Chunk而導致版本號更新了(版本號更新是指什麼鴨?),Master節點需要向磁碟中的Log追加一條記錄,來說明剛剛向這個檔案添加了一個新的Chunk或者是修改了Chunk的版本號。由於寫磁碟慢,所以Master節點需要經可能少的寫入資料到磁碟。
  • 在磁碟中寫log而不是資料庫,資料庫本質上是某種B數或hash table,那麼寫B樹需要在磁碟上隨機訪問,而寫Log是順序寫入,會快很多。
  • 並且log中存在checkpoint,所以Master節點恢復從最近的checkpoint開始,逐條恢復

3.5 GFS 讀檔案

  • 對於讀請求,GFS客戶端或應用程式會將一個檔名與檔案中的讀取偏移量傳送給Master節點,那麼Master節點會從file表單中查詢檔名,通過偏移量除以64MB就可以得到對應的Chunk ID,之後Master節點再從Chunk表單中找到存有Chunk的伺服器表單,並將列表返回給客戶端
  • 客戶端得到Chunk伺服器位置後,可以去從最近的伺服器讀取資料,並且會快取Chunk ID和伺服器的對應關係
  • 客戶端之後就和Chunk伺服器通訊,Chunk伺服器將每個Chunk儲存為獨立的Linux檔案
  • 對於GFS客戶端一次請求的資料量超過了64MB或者跨越了Chunk的邊界的情況,GFS客戶端每次請求會依賴於一個GFS的庫,這個庫會將這個請求劃分為兩個給Master節點,也就是GFS庫和Master節點會共同協商這些資訊轉化為一個Chunk

3.6 GFS寫檔案

  • 寫檔案也會呼叫GFS的庫。可能存在多個客戶端同時寫一個檔案的情況,那麼多個客戶端寫一個同一個檔案,一個個客戶端沒法知道其他客戶端寫了多少,也就不知道偏移量
  • 並且,對於讀檔案而言,可以從任何最新的Chunk副本讀,但是寫檔案,必須要寫入到Chunk的主副本(Primary Chunk),但是存在某個時間點,Master不一定指定了Chunk的主副本,所以,寫檔案需要考慮Chunk的主副本不存在的情況,Master節點需要弄清楚再追加檔案時,客戶端需要與哪個Chunk伺服器通訊Master的做法是,將所有儲存了最新Chunk的伺服器集合完成,然後挑選一個為Primary,其他作為Secondary,這個時候Master會增加這個Chunk的版本號
  • Chunk的版本號用來標識最新的副本,Master節點會記錄Chunk的最新版本號,由於需要通過Chunk的版本號來區分副本是否是最新的,所以Chunk的版本號需要儲存在磁碟中同時,一定要記錄最新版本號,而不是最大版本號
  • 大量的客戶端會去向Primary發起一些併發的寫請求,並且Primary需要保證所有的Secondary都寫入成功了,如果沒有,就會像客戶端返回寫入失敗,那麼客戶端需要重新月Master互動
  • 對於寫檔案的失敗,Primary和Secondary伺服器並不會去做任何的恢復

3.8 GFS的一致性

  • 弱一致性,Master節點只有一臺機器,並且它發生故障,需要人工切換

參考

文件
視訊