1. Introduction
本文是讀GFS論文的總結,收錄在我的github中papers專案,papers專案旨在學習和總結分散式系統相關的論文。
全文主要分為以下幾方面:
- Design Motivation
- Architecture
- System Interactions
- Master Operation
- Fault Tolerance and Diagnose
- Discussion
2. Design Motivation
google對現有系統的執行狀態以及應用系統進行總結,抽象出對檔案系統的需求,主要分為以下幾個方面。
- 普通商用的機器硬體發生故障是常態
- 儲存的問題普遍比較大,幾個G的檔案很常見
- 大部分的檔案操作都是在追加資料,覆蓋原來寫入的資料的情況比較少見,隨機寫幾乎不存在
- 讀操作主要包括兩種,large streaming read和small random read
- 為了應用使用方便,多客戶端並行地追加同一個檔案需要非常高效
- 頻寬的重要性大於時延,目標應用是高速讀大塊資料的應用,對響應時間沒有過多的需求
3. Architecture
本部分討論gfs的總體架構,以及在此架構上需要考慮的一些問題。
3.1 Overview
GFS的整體架構如下圖:
(圖片來源:gfs論文)
GFS中有四類角色,分別是
- GFS chunkserver
- GFS master
- GFS client
- Application
3.1.1 GFS chunkserver
在GFS chunkserver中,檔案都是分成固定大小的chunk來儲存的,每個chunk通過全域性唯一的64位的chunk handle來標識,chunk handle在chunk建立的時候由GFS master分配。GFS chunkserver把檔案儲存在本地磁碟中,讀或寫的時候需要指定檔名和位元組範圍,然後定位到對應的chunk。為了保證資料的可靠性,一個chunk一般會在多臺GFS chunkserver上儲存,預設為3份,但使用者也可以根據自己的需要修改這個值。
3.1.2 GFS master
GFS master管理所有的後設資料資訊,包括namespaces,訪問控制資訊,檔案到chunk的對映資訊,以及chunk的地址資訊(即chunk存放在哪臺GFS chunkserver上)。
3.1.3 GFS client
GFS client是GFS應用端使用的API介面,client和GFS master互動來獲取後設資料資訊,但是所有和資料相關的資訊都是直接和GFS chunkserver來互動的。
3.1.4 Application
Application為使用gfs的應用,應用通過GFS client於gfs後端(GFS master和GFS chunkserver)打交道。
3.2 Single Master
GFS架構中只有單個GFS master,這種架構的好處是設計和實現簡單,例如,實現負載均衡時可以利用master上儲存的全域性的資訊來做決策。但是,在這種架構下,要避免的一個問題是,應用讀和寫請求時,要弱化GFS master的參與度,防止它成為整個系統架構中的瓶頸。
從一個請求的流程來討論上面的問題。首先,應用把檔名和偏移量資訊傳遞給GFS client,GFS client轉換成(檔名,chunk index)資訊傳遞給GFS master,GFS master把(chunk handle, chunk位置資訊)返回給客戶端,客戶端會把這個資訊快取起來,這樣,下次再讀這個chunk的時候,就不需要去GFS master拉取chunk位置資訊了。
另一方面,GFS支援在一個請求中同時讀取多個chunk的位置資訊,這樣更進一步的減少了GFS client和GFS master的互動次數,避免GFS master成為整個系統的瓶頸。
3.3 Chunk Size
對於GFS來說,chunk size的預設大小是64MB,比一般檔案系統的要大。
優點
- 可以減少GFS client和GFS master的互動次數,chunk size比較大的時候,多次讀可能是一塊chunk的資料,這樣,可以減少GFS client向GFS master請求chunk位置資訊的請求次數。
- 對於同一個chunk,GFS client可以和GFS chunkserver之間保持持久連線,提升讀的效能。
- chunk size越大,chunk的metadata的總大小就越小,使得chunk相關的metadata可以儲存在GFS master的記憶體中。
缺點
- chunk size越大時,可能對部分檔案來講只有1個chunk,那麼這個時候對該檔案的讀寫就會落到一個GFS chunkserver上,成為熱點。
對於熱點問題,google給出的解決方案是應用層避免高頻地同時讀寫同一個chunk。還提出了一個可能的解決方案是,GFS client找其他的GFS client來讀資料。
64MB應該是google得出的一個比較好的權衡優缺點的經驗值。
3.4 Metadata
GFS master儲存三種metadata,包括檔案和chunk namespace,檔案到chunk的對映以及chunk的位置資訊。這些metadata都是儲存在GFS master的記憶體中的。對於前兩種metadata,還會通過記操作日誌的方式持久化儲存,操作日誌會同步到包括GFS master在內的多臺機器上。GFS master不持久化儲存chunk的位置資訊,每次GFS master重啟或者有新的GFS chunkserver加入時,GFS master會要求對應GFS chunkserver把chunk的位置資訊彙報給它。
3.4.1 In-Memory Data Structures
使用記憶體儲存metadata的好處是讀取metadata速度快,方便GFS master做一些全域性掃描metadata相關資訊的操作,例如負載均衡等。
但是,以記憶體儲存的的話,需要考慮的是GFS master的記憶體空間大小是不是整個系統能儲存的chunk數量的瓶頸所在。在GFS實際使用過程中,這一般不會成為限制所在,因為GFS中一個64MBchunk的metadata大小不超過64B,並且,對於大部分chunk來講都是使用的全部的空間的,只有檔案的最後一個chunk會儲存在部分空間沒有使用,因此,GFS master的記憶體空間在實際上很少會成為限制系統容量的因素。即使真的是現有的儲存檔案的chunk數量超過了GFS master記憶體空間大小的限制,也可以通過加記憶體的方式,來獲取記憶體儲存設計帶來的效能、可靠性等多種好處。
3.4.2 Chunk Locations
GFS master不持久化儲存chunk位置資訊的原因是,GFS chunkserver很容易出現當機,重啟等行為,這樣GFS master在每次發生這些事件的時候,都要修改持久化儲存裡面的位置資訊的資料。
3.4.3 Operation Log
operation log的作用
- 持久化儲存metadata
- 它的儲存順序定義了並行的操作的最終的操作順序
怎麼存
operation log會儲存在GFS master和多臺遠端機器上,只有當operation log在GFS master和多臺遠端機器都寫入成功後,GFS master才會向GFS client返回成功。為了減少operation log在多臺機器落盤對吞吐量的影響,可以將一批的operation log形成一個請求,然後寫入到GFS master和其他遠端機器上。
check point
當operation log達到一定大小時,GFS master會做checkpoint,相當於把記憶體的B-Tree格式的資訊dump到磁碟中。當master需要重啟時,可以讀最近一次的checkpoint,然後replay它之後的operation log,加快恢復的時間。
做checkpoint的時候,GFS master會先切換到新的operation log,然後開新執行緒做checkpoint,所以,對新來的請求是基本是不會有影響的。
4. System Interactions
本部分討論GFS的系統互動流程。
4.1 Leases and Mutation Order
GFS master對後續的資料流程是不做控制的,所以,需要一個機制來保證,所有副本是按照同樣的操作順序寫入對應的資料的。GFS採用lease方式來解決這個問題,GFS對一個chunk會選擇一個GFS chunkserver,發放lease,稱作primary,由primary chunkserver來控制寫入的順序。
Lease的過期時間預設是60s,可以通過心跳資訊來續時間,如果一個primary chunkserver是正常狀態的話,這個時間一般是無限續下去的。當primary chunkserver和GFS master心跳斷了後,GFS master也可以方便的把其他chunk副本所在的chunkserver設定成primary。
4.1.1 Write Control and Data Flow
(圖片來源:gfs論文)
- GFS client向GFS master請求擁有具有當前chunk的lease的chunkserver資訊,以及chunk的其他副本所在的chunkserver的資訊,如果當前chunk沒有lease,GFS master會分配一個。
- GFS master把primary chunkserver以及其他副本的chunkserver資訊返回給client。client會快取這些資訊,只有當primary chunkserver連不上或者lease發生改變後,才需要再向GFS master獲取對應的資訊。
- client把資料推送給所有包含此chunk的chunkserver,chunkserver收到後會先把資料放到內部的LRU buffer中,當資料被使用或者過期了,才刪除掉。注意,這裡沒有將具體怎麼來傳送資料,會在下面的Data Flow講。
- 當所有包含chunk副本的chunkserver都收到了資料,client會給primary傳送一個寫請求,包含之前寫的資料的資訊,primary會分配對應的序號給此次的寫請求,這樣可以保證從多個客戶端的併發寫請求會得到唯一的操作順序,保證多個副本的寫入資料的順序是一致的。
- primary轉發寫請求給所有其他的副本所在的chunkserver(Secondary replica),操作順序由primary指定。
- Secondary replica寫成功後會返回給primary replica。
- Primary replica返回給client。任何副本發生任何錯誤都會返回給client。
這裡,寫資料如果發生錯誤可能會產生不一致的情況,會在consistency model中討論。
4.2 Data Flow
4.1中第三步的Data Flow採用的是pipe line方式,目標是為了充分利用每臺機器的網路頻寬。假設一臺機器總共有三個副本S1-S3。整個的Data Flow為:
- client選擇離它最近的chunkserver S1,開始推送資料
- 當chunkserver S1收到資料後,它會立馬轉發到離它最近的chunkserver S2
- chunkserver S2收到資料後,會立馬轉發給離它最近的chunkserver S3
不斷重複上述流程,直到所有的chunkserver都收到client的所有資料。
以上述方式來傳送B位元組資料到R個副本,並假設網路吞吐量為T,機器之間的時延為L,那麼,整個資料的傳輸時間為B/T+RL。
4.3 Atomic Record Appends
Append操作流程和寫差不多,主要區別在以下
- client把資料推送到所有副本的最後一個chunk,然後傳送寫請求到primary
- primary首先檢查最後一個chunk的剩餘空間是否可以滿足當前寫請求,如果可以,那麼執行寫流程,否則,它會把當前的chunk的剩餘空間pad起來,然後告訴其他的副本也這麼幹,最後告訴client這個chunk滿了,寫入下個chunk。
這裡需要討論的是,如果append操作在部分副本失敗的情況下,會發生什麼?
例如,寫操作要追加到S1-S3,但是,僅僅是S1,S2成功了,S3失敗了,GFS client會重試操作,假如第二次成功了,那麼S1,S2寫了兩次,S3寫了一次,目前的理解是GFS會先把失敗的記錄進行padding對齊到primary的記錄,然後再繼續append。
4.4 Snapshot
Snapshot的整個流程如下:
- client向GFS master傳送Snapshot請求
- GFS master收到請求後,會回收所有這次Snapshot涉及到的chunk的lease
- 當所有回收的lease到期後,GFS master寫入一條日誌,記錄這個資訊。然後,GFS會在記憶體中複製一份snapshot涉及到的metadata
當snapshot操作完成後,client寫snapshot中涉及到的chunk C的流程如下:
- client向GFS master請求primary chunkserver和其他chunkserver
- GFS master發現chunk C的引用計數超過1,即snapshot和本身。它會向所有有chunk C副本的chunkserver傳送建立一個chunk C的拷貝請求,記作是chunk C',這樣,把最新資料寫入到chunk C'即可。本質上是copy on write。
4.5 Consistency Model
(圖片來源:gfs論文)
GFS中consistent、defined的定義如下:
- consistent:所有的客戶端都能看到一樣的資料,不管它們從哪個副本讀取
- defined:當一個檔案區域發生操作後,client可以看到剛剛操作的所有資料,那麼說這次操作是defined。
下面分析表格中出現的幾種情況。
- Write(Serial Success),單個寫操作,並且返回成功,那麼所有副本都寫入了這次操作的資料,因此所有客戶端都能看到這次寫入的資料,所以,是defined。
- Write(Concurrent Successes),多個寫操作,並且返回成功,由於多個客戶端寫請求傳送給priamary後,由primary來決定寫的操作順序,但是,有可能多個寫操作可能是有區域重疊的,這樣,最終寫完成的資料可能是多個寫運算元據疊加在一起,所以這種情況是consistent和undefined。
- Write(Failure),寫操作失敗,則可能有的副本寫入了資料,有的沒有,所以是inconsistent。
- Record Append(Serial Success and Concurrent Success),由於Record Append可能包含重複資料,因此,是inconsistent,由於整個寫入的資料都能看到,所以是defined。
- Record Append(Failure),可能部分副本append成功,部分副本append失敗,所以,結果是inconsistent。
GFS用version來標記一個chunkserver掛掉的期間,是否有client進行了write或者append操作。每進行一次write或者append,version會增加。
需要考慮的點是client會快取chunk的位置資訊,有可能其中某些chunkserver已經掛掉又起來了,這個時候chunkserver的資料可能是老的資料,讀到的資料是會不一致的。讀流程中,好像沒有看到要帶version資訊來讀的。這個論文中沒看到避免的措施,目前還沒有結果。
4.5.1 Implications for Applications
應用層需要採用的機制:用append而不是write,做checkpoint,writing self-validating和self-identifying records。具體地,如下:
- 應用的使用流程是append一個檔案,到最終寫完後,重新命名檔案
- 對檔案做checkpoint,這樣應用只需要關注上次checkpoint時的檔案區域到最新檔案區域的資料是否是consistent的,如果這期間發生不一致,可以重新做這些操作。
- 對於並行做append的操作,可能會出現重複的資料,GFS client提供去重的功能。
5. Master Operation
GFS master的功能包括,namespace Management, Replica Placement,Chunk Creation,Re-replication and Rebalancing以及Garbage Collection。
5.1 Namespace Management and Locking
每個master操作都需要獲得一系列的鎖。如果一個操作涉及到/d1/d2/.../dn/leaf,那麼需要獲得/d1,/d1/d2,/d1/d2/.../dn的讀鎖,然後,根據操作型別,獲得/d1/d2/.../dn/leaf的讀鎖或者寫鎖,其中leaf可能是檔案或者路徑。
一個例子,當/home/user被快照到/save/user的時候,/home/user/foo的建立是被禁止的。
對於快照,需要獲得/home和/save的讀鎖,/home/user和/save/user的寫鎖。對於建立操作,會獲得/home,/home/user的讀鎖,然後/home/user/foo的寫鎖。其中,/home/user的鎖產生衝突,/home/user/foo建立會被禁止。
這種加鎖機制的好處是對於同一個目錄下,可以並行的操作檔案,例如,同一個目錄下並行的建立檔案。
5.2 Replica Placement
GFS的Replica Placement的兩個目標:最大化資料可靠性和可用性,最大化網路頻寬的使用率。因此,把每個chunk的副本分散在不同的機架上,這樣一方面,可以抵禦機架級的故障,另一方面,可以把讀寫資料的頻寬分配在機架級,重複利用多個機架的頻寬。
5.3 Creation, Re-replication, Rebalancing
5.3.1 Chunk Creation
GFS在建立chunk的時候,選擇chunkserver時考慮的因素包括:
- 磁碟空間使用率低於平均值的chunkserver
- 限制每臺chunkserver的最近的建立chunk的次數,因為建立chunk往往意味著後續需要寫大量資料,所以,應該把寫流量儘量均攤到每臺chunkserver上
- chunk的副本放在處於不同機架的chunkserver上
5.3.2 Chunk Re-replication
當一個chunk的副本數量少於預設定的數量時,需要做複製的操作,例如,chunkserver當機,副本資料出錯,磁碟損壞,或者設定的副本數量增加。
chunk的複製的優先順序是按照下面的因素來確定的:
- 丟失兩個副本的chunk比丟失一個副本的chunk的複製認為優先順序高
- 檔案正在使用比檔案已被刪除的chunk的優先順序高
- 阻塞了client程式的chunk的優先順序高(這個靠什麼方法得到?)
chunk複製的時候,選擇新chunkserver要考慮的點:
- 磁碟使用率
- 單個chunkserver的複製個數限制
- 多個副本需要在多個機架
- 叢集的複製個數限制
- 限制每個chunkserver的複製網路頻寬,通過限制讀流量的速率來限制
5.3.3 Rebalancing
週期性地檢查副本分佈情況,然後調整到更好的磁碟使用情況和負載均衡。GFS master對於新加入的chunkserver,逐漸地遷移副本到上面,防止新chunkserver頻寬打滿。
5.4 Garbage Collection
在GFS刪除一個檔案後,並不會馬上就對檔案物理刪除,而是在後面的定期清理的過程中才真正的刪除。
具體地,對於一個刪除操作,GFS僅僅是寫一條日誌記錄,然後把檔案命名成一個對外部不可見的名稱,這個名稱會包含刪除的時間戳。GFS master會定期的掃描,當這些檔案存在超過3天后,這些檔案會從namespace中刪掉,並且記憶體的中metadata會被刪除。
在對chunk namespace的定期掃描時,會掃描到這些檔案已經被刪除的chunk,然後會把metadata從磁碟中刪除。
在與chunkserver的heartbeat的互動過程中,GFS master會把不在metadata中的chunk告訴chunkserver,然後chunkserver就可以刪除這些chunk了。
採用這種方式刪除的好處:
- 利用心跳方式互動,在一次刪除失敗後,還可以通過下次心跳繼續重試操作
- 刪除操作和其他的全域性掃描metadata的操作可以放到一起做
壞處:
- 有可能有的應用需要頻繁的建立和刪除檔案,這種延期刪除方式會導致磁碟使用率偏高,GFS提供的解決方案是,對一個檔案呼叫刪除操作兩次,GFS會馬上做物理刪除操作,釋放空間。
5.5 Stale Replication Detection
當一臺chunkserver掛掉的時候,有新的寫入操作到chunk副本,會導致chunkserve的資料不是最新的。
當master分配lease到一個chunk時,它會更新chunk version number,然後其他的副本都會更新該值。這個操作是在返回給客戶端之前完成的,如果有一個chunkserver當前是當機的,那麼它的version number就不會增加。當chunkserver重啟後,會彙報它的chunk以及version number,對於version number落後的chunk,master就認為這個chunk的資料是落後的。
GFS master會把落後的chunk當垃圾來清理掉,並且不會把落後的chunkserver的位置資訊傳給client。
備註:
1. GFS master把落後的chunk當作垃圾清理,那麼,是否是走re-replication的邏輯來生成新的副本呢?沒有,是走立即複製的邏輯。
6. Fault Tolerance and Diagnose
6.1 High Availability
為了實現高可用性,GFS在通過兩方面來解決,一是fast recovery,二是replication
6.1.1 Fast Recovery
master和chunkserver都被設計成都能在秒級別重啟
6.1.2 Chunk Replications
每個chunk在多個機架上有副本,副本數量由使用者來指定。當chunkserver不可用時,GFS master會自動的複製副本,保證副本數量和使用者指定的一致。
6.1.3 Master Replication
master的operation log和checkpoint都會複製到多臺機器上,要保證這些機器的寫都成功了,才認為是成功。只有一臺master在來做garbage collection等後臺操作。當master掛掉後,它能在很多時間內重啟;當master所在的機器掛掉後,監控會在其他具有operation log的機器上重啟啟動master。
新啟動的master只提供讀服務,因為可能在掛掉的一瞬間,有些日誌記錄到primary master上,而沒有記錄到secondary master上(這裡GFS沒有具體說同步的流程)。
6.2 Data Integrity
每個chunkserver都會通過checksum來驗證資料是否損壞的。
每個chunk被分成多個64KB的block,每個block有32位的checksum,checksum在記憶體中和磁碟的log中都有記錄。
對於讀請求,chunkserver會檢查讀操作所涉及block的所有checksum值是否正確,如果有一個block的checksum不對,那麼會報錯給client和master。client這時會從其他副本讀資料,而master會clone一個新副本,當新副本clone好後,master會刪除掉這個checksum出錯的副本。
6.3 Diagnose Tools
主要是通過log,包括重要事件的log(chunkserver上下線),RPC請求,RPC響應等。
7. Discussion
本部分主要討論大規模分散式系統一書上,列出的關於gfs的一些問題,具體如下。
7.1 為什麼儲存三個副本?而不是兩個或者四個?
- 如果儲存的是兩個副本,掛掉一個副本後,系統的可用性會比較低,例如,如果另一個沒有掛掉的副本出現網路問題等,整個系統就不可用了
- 如果儲存的是四個副本,成本比較高
7.2 chunk的大小為何選擇64MB?這個選擇主要基於哪些考慮?
優點
- 可以減少GFS client和GFS master的互動次數,chunk size比較大的時候,多次讀可能是一塊chunk的資料,這樣,可以減少GFS client向GFS master請求chunk位置資訊的請求次數。
- 對於同一個chunk,GFS client可以和GFS chunkserver之間保持持久連線,提升讀的效能。
- chunk size越大,chunk的metadata的總大小就越小,使得chunk相關的metadata可以儲存在GFS master的記憶體中。
缺點
- chunk size越大時,可能對部分檔案來講只有1個chunk,那麼這個時候對該檔案的讀寫就會落到一個GFS chunkserver上,成為熱點。
64MB應該是google得出的一個比較好的權衡優缺點的經驗值。
7.3 gfs主要支援追加,改寫操作比較少,為什麼這麼設計?如何設計一個僅支援追加操作的檔案系統來構建分散式表格系統bigtable?
- 因為追加多,改寫少是google根據現有應用需求而確定的
- bigtable的問題等讀到bigtable論文再討論
7.4 為什麼要將資料流和控制流分開?如果不分開,如何實現追加流程?
主要是為了更有效地利用網路頻寬。把資料流分開,可以更好地優化資料流的網路頻寬使用。
如果不分開,需要討論下。
7.5 gfs有時會出現重複記錄或者padding記錄,為什麼?
padding出現場景:
- last chunk的剩餘空間不滿足當前寫入量大小,需要把last chunk做padding,然後告訴客戶端寫入下一個chunk
- append操作失敗的時候,需要把之前寫入失敗的副本padding對齊到master
重複記錄出現場景:
- append操作部分副本成功,部分失敗,然後告訴客戶端重試,客戶端會在成功的副本上再次append,這樣就會有重複記錄出現
7.6 lease是什麼?在gfs中起到了什麼作用?它與心跳有何區別?
lease是gfs master把控制寫入順序的許可權下放給chunkserver的機制,以減少gfs master在讀寫流程中的參與度,防止其成為系統瓶頸。心跳是gfs master檢測chunkserver是否可用的標誌。
7.7 gfs追加過程中如果出現備副本故障,如何處理?如果出現主副本故障,應該如何處理?
- 對於備副本故障,寫入的時候會失敗,然後primary會返回錯誤給client。按照一般的系統設計,client會重試一定次數,發現還是失敗,這時候client會把情況告訴給gfs master,gfs master可以檢測chunkserver的情況,然後把最新的chunkserver資訊同步給client,client端再繼續重試。
- 對於主副本故障,寫入的時候會失敗,client端應該是超時了。client端會繼續重試一定次數,發現還是一直超時,那麼把情況告訴給gfs master,gfs master發現primary掛掉,會重新grant lease到其他chunkserver,並把情況返回給client。
7.8 gfs master需要儲存哪些資訊?master的資料結構如何設計?
namespace、檔案到chunk的對映以及chunk的位置資訊
namespace採用的是B-Tree,對於名稱採用字首壓縮的方法,節省空間;(檔名,chunk index)到chunk的對映,可以通過hashmap;chunk到chunk的位置資訊,可以用multi_hashmap,因為是一對多的對映。
7.9 假設服務一千萬個檔案,每個檔案1GB,master中儲存後設資料大概佔多少記憶體?
1GB/64MB = 1024 / 64 = 16。總共需要16 10000000 64 B = 10GB
7.10 master如何實現高可用性?
- metadata中namespace,以及檔案到chunk資訊持久化,並儲存到多臺機器
- 對metadata的做checkpoint,保證重啟後replay消耗時間比較短,checkpoint可以直接對映到記憶體使用,不用解析
- 在primary master發生故障的時候,並且無法重啟時,會有外部監控將secondary master,並提供讀服務。secondary master也會監控chunkserver的狀態,然後把primary master的日誌replay到記憶體中
7.11 負載的影響因素有哪些?如何計算一臺機器的負載值?
主要是考慮CPU、記憶體、網路和I/O,但如何綜合這些引數並計算還是得看具體的場景,每部分的權重隨場景的不同而不同。
7.12 master新建chunk時如何選擇chunkserver?如果新機器上線,負載值特別低,如何避免其他chunkserver同時往這臺機器上遷移chunk?
如何選擇chunkserver
- 磁碟空間使用率低於平均值的chunkserver
- 限制每臺chunkserver最近建立chunk的次數,因為建立chunk往往意味著後續需要寫入大量資料,所以,應該把寫流量均攤到每臺chunkserver
- chunk的副本放置於不同機架的chunkserver上
如何避免同時遷移
通過限制單個chunkserver的clone操作的個數,以及clone使用的頻寬來限制,即從源chunkserver度資料的頻率做控制。
7.13 如果chunkserver下線後過一會重新上線,gfs如何處理?
因為是過一會,所以假設chunk re-replication還沒有執行,那麼在這期間,可能這臺chunkserver上有些chunk的資料已經處於落後狀態了,client讀資料的時候或者chunkserver定期掃描的時候會把這些狀態告訴給master,master告訴上線後的chunkserver從其他機器複製該chunk,然後master會把這個chunk當作是垃圾清理掉。
對於沒有落後的chunk副本,可以直接用於使用。
7.14 如何實現分散式檔案系統的快照操作?
Snapshot的整個流程如下:
- client向GFS master傳送Snapshot請求
- GFS master收到請求後,會回收所有這次Snapshot涉及到的chunk的lease
- 當所有回收的lease到期後,GFS master寫入一條日誌,記錄這個資訊。然後,GFS會在記憶體中複製一份snapshot涉及到的metadata
當snapshot操作完成後,client寫snapshot中涉及到的chunk C的流程如下:
- client向GFS master請求primary chunkserver和其他chunkserver
- GFS master發現chunk C的引用計數超過1,即snapshot和本身。它會向所有有chunk C副本的chunkserver傳送建立一個chunk C的拷貝請求,記作是chunk C',這樣,把最新資料寫入到chunk C'即可。本質上是copy on write。
7.15 chunkserver資料結構如何設計?
chunkserver主要是儲存64KB block的checksum資訊,需要由chunk+offset,能夠快速定位到checksum,可以用hashmap。
7.16 磁碟可能出現位翻轉錯誤,chunkserver如何應對?
利用checksum機制,分讀和寫兩種情況來討論:
- 對於讀,要檢查所讀的所有block的checksum值
- 對於寫,分為append和write。對於append,不檢查checksum,延遲到讀的時候檢查,因為append的時候,對於最後一個不完整的block計算checksum時候採用的是增量的計算,即使前面存在錯誤,也能在後來的讀發現。對於overwrite,因為不能採用增量計算,要覆蓋checksum,所以,必須要先檢查只寫入部分資料的checksum是否不一致,否則,資料錯誤會被隱藏。
7.17 chunkserver重啟後可能有一些過期的chunk,master如何能夠發現?
chunkserver重啟後,會彙報chunk及其version number,master根據version number來判斷是否過期。如果過期了,那麼會做以下操作:
- 過期的chunk不參與資料讀寫流程
- master會告訴chunkserver從其他的最新副本里拷貝一份資料
- master將過期的chunk假如garbage collection中
問題:如果chunkserver拷貝資料的過程過程中,之前拷貝的資料備份又發生了變化,然後分為兩種情況討論:
- 如果期間lease沒變,那麼chunkserver不知道自己拷貝的資料是老的,應該會存在不一致的問題?
- 如果期間lease改變,那麼chunkserver因為還不能提供讀服務,那麼version number應該不會遞增,繼續保持stable狀態,然後再發起拷貝。
PS:
本部落格更新會在第一時間推送到微信公眾號,歡迎大家關注。