⑴ GFS論文筆記
GFS的誕生來源於google日益增長的數據量的處理需求,它是一個可擴展的分布式文件系統,用於大型分布式數據密集型應用,在廉價的通用硬體上運行時提供容錯機制,並且可以為大量客戶端提供較高的聚合性能。
它的設計由當前和預期的應用負載(當時的)和技術環境驅動,與以前的文件系統的假設有著明顯不同,因此gfs在設計上有幾個不同的points:
當前已部署多個集群用於不同目的,最大的擁有1000多個存儲節點,超過300TB的存儲服務,並且有數百個客戶端連續不斷地高負載請求。
前面提到一些對應用負載和技術環境的觀察,現在更詳細地進行闡述:
雖然GFS不能提供像POSIX標準的API,但它提供一個相似的文件系統介面。文件在目錄中按層次結構組織,並以路徑名作為標識。支持create、delete、open、close、read and write files。
gfs支持快照和record append操作。快照以低代價創建文件副本或者目錄樹,record append支持多個客戶端並發地寫文件,保證每個獨立客戶端append的原子性。
一個gfs集群包含一個master和多個chunkservers,chunkserver被多個客戶端訪問,如圖1所示。每一個都是普通linux機器上運行的用戶態服務進程。資源允許的情況下,客戶端可以和chunkserver部署在同一台機器上。
文件被劃分為固定大小的塊。每個chunk由一個獨一無二的64位大小的chunk handle所標識,chunk handle在chunk被創建時由master分配。每個chunk的副本分布在多個機器上,系統默認為三副本模式,用戶也可以為不同namespace的文件指定不同級別的副本。
master包含文件系統的所有元信息。包含namespace、訪問控制許可權信息、文件到chunks的映射、當前chunks的位置信息。也控制著全局的活動,像chunk租約管理、gc、chunk遷移等。master通過心跳的方式與每個chunkserver交流來發送它的指令和收集狀態。
客戶端與master的交互涉及元信息操作,所有數據操作直接與chunkserver交互。gfs不提供POSIX標准API,因此不需要掛接到linux的vnode層。
客戶端和chunkserver都不緩存文件數據。大多數應用傳輸大文件,客戶端緩存收益很低。chunks作為本地的文件存儲,linux系統有自己的buffer cache,chunkserver不需要再增加緩存。
單master簡化了系統的設計,但是會有單點的瓶頸問題,這是必須要解決的。客戶端不會從master讀寫數據文件,客戶端請求master它需要的交互的chunkserver信息,並且將其緩存一段時間,後續的操作直接與chunkservers交互。
客戶端會發送請求給離它最近的一個副本。實際上,客戶端通常會向master請求多個chunk的信息,以減少未來與maser交互的代價。
chunk size定為64MB,相比普通的文件系統的block size更大。每個chunk副本以linux文件的形式存在chunkserver上,僅根據需要來擴展。使用lazy space allocation的方式避免空間浪費。
large chunk size有以下幾個優點:
但是large chunk size with lazy space allocation也有其缺點:單個文件可能包含很少數量的chunks,或許只有一個,當許多客戶端訪問相同文件時這些chunks成為熱點。但由於目標應用大多是順序的讀多個large chunk文件,熱點並不是主要的問題。
然而GFS第一次用於批處理隊列系統時確實出現了熱點問題,數百個客戶端同時訪問一個單chunk文件,存儲這個文件的幾個chunkserver超負荷運轉,當時通過錯開應用的啟動時間避免了這個問題,一個潛在、長期的解決方法是允許客戶端從其它客戶端讀取數據。
master保存三種類型的元數據:
所有元數據都保存在內存中 。對於元數據的內存操作是很快的,後台任務周期巡檢整個狀態也是比較簡單高效的。周期巡檢用於實現chunk gc、在chunkserver故障時重新構造副本、chunk遷移以平衡多個chunkserver的負載和disk usage。
雖然系統的容量受master內存大小的限制,但這並不是一個嚴重的問題,64MB的chunk只需要不到64byte大小的元信息,如果一定需要更大的文件系統,那麼增加內存的代價相比為可靠性、性能和靈活性等付出的代價是較小的。
前兩種類型的元數據通過寫日誌來保證持久化,並且會復制日誌到遠程機器上。master不需要將chunks的位置信息持久化,而是在master啟動和新的chunkserver加入集群時向每個chunkserver詢問它的位置信息,之後通過心跳信息監控chunk位置變更信息。chunkserver作為最後一關是確切知道自己本地有沒有哪些chunk的,因此維護一個一致性的視圖是沒有必要的。
operation log 包含元數據的變更記錄, 它是GFS的核心 ,它不僅僅是唯一的元數據持久化記錄,也表明了並發操作的邏輯時間線。文件、chunks和它們的版本都是由邏輯時間線唯一標識。元數據變更記錄在持久化之前對客戶端是不可見的,而且日誌被復制到多個遠程的機器,只有相應的記錄在本地和遠程都持久化到硬碟了才可以回復客戶端。master使用批處理log的方式提高系統的吞吐。
master通過回放日誌來恢復文件系統的狀態,為提高恢復速度需要保持log量足夠小。當log增長超過特定大小時,master會checkpoint它的狀態,以加速恢復提高可用性。構建checkpoint可能需要花費一段時間,因此master以一種不delay後續變化的方式來組織內部狀態,先switch到一個新的日誌文件,使用獨立的線程創建checkpoint,新的checkpoint包含了所有switch之前的變化。幾百萬個文件的集群在一分鍾內可以完成,完成後將同時被寫入本地和遠程。恢復只需要最新的checkpoint和之後的日誌文件,舊的checkpoints和日誌文件可以完全刪除。
GFS使用一個寬松的一致性模型,這種模型可以很好地支持分布式應用程序,而且實現起來簡單有效。
file namesapce變化(例如文件創建)是原子的,使用namespace鎖。
master的operation log定義了這些操作的全局順序。
數據變化後文件region的狀態取決於變化的類型,是否成功、失敗或者是並發的。Table1做了總結。如果所有客戶端都能看到相同的數據,無論它們讀的是哪個副本,則這個file region是一致的。
數據變化有兩種:writes或者record appends。write是指從應用指定offset處開始寫數據,record append指即使存在並發沖突,數據也要被原子地append到文件至少一次,但offset是由GFS選定。
GFS保證在一系列成功的mutations後,file region是defined,通過下面兩點來保證:
過期的副本將不會再涉及到任何mutation,master也不會將其位置信息回應給客戶端,不久後將會被gc。但客戶端緩存的信息可能包含過期的副本,緩存失效存在一個時間窗口,文件再次打開也會清除該文件的所有chunk信息。由於大多數文件是append-only,過期的副本通常返回的是過早的結尾???而不是過期的數據。
介紹客戶端、master和chunkserver之間如何交互來實現數據變化、原子追加寫和快照的。
使用租約的方式維護多個副本間一致的mutation order。master授權租約給副本中的一個,稱之為primary。primary為chunk的mutaions選擇一個順序,所有副本都按照這個順序apply。
租約機制最小化了master的管理overhead。租約初始的超時時間是60s,如果chunk一直在變化過程中,primary可以申請續租。這些授權和續租請求由master和chunkserver之間的心跳信息攜帶。master也可以嘗試撤銷租約,即使它與primary失去了聯系,也可以等租約過期後安全地授權給另外一個副本。
在Figure2中,跟隨著寫入控制流展示了處理過程:
如果一個寫請求比較大或者超出了chunk邊界,GFS客戶端將它拆為多個寫操作,但是多個操作可能與其它客戶端並發交叉寫入,因此共享的fie region最終可能包含多個不同客戶端的碎片,這會造成 一致性模型 中所描述的file region處於consistent but undefined狀態。
數據以pipline的機制在chunkserver鏈上線性傳輸,而控制流是從客戶端到primary再到所有的其它副本。分離數據流和控制流可以更高效地使用網路。可以帶來以下好處:
GFS提供原子的append operaton叫作 record append 。傳統的write中,客戶端指定offset,並發寫相同region時不是serializable,最終region可能包含多個客戶端的碎片數據。而對於record append,客戶端僅指定數據,GFS保證至少一次成功的原子append,offset由GFS選定,與Unix的O_APPEND模式相似。
多個客戶端並發操作相同文件是比較重的。如果處理傳統的write,客戶端需要額外復雜和昂貴的同步邏輯,像分布式鎖。而record append僅需要primary增加一點額外的邏輯:primary檢查是否並發append數據的chunk會超出max size,如果會超出則將chunk填充到max size,並且告訴所有二級副本同樣操作,然後回應客戶端指出這個操作應該選擇另一個chunk重試;大多數情況下記錄是在max size內的,primary將數據append到自己的副本,並告訴所有二級副本按照確切的offset寫數據,最後回應給客戶端。
如果中間出現錯誤,客戶端重試,相同chunk的副本可能包含不同的數據,可能包含相同的記錄或者一部分相同,GFS不保證bytewise identical,僅僅保證數據至少有一次被成功地原子寫入。從report success邏輯可以容易得出,數據必須是在某個chunk的所有副本上以相同的offset寫入。在此之後,所有副本都與記錄end一樣長,即使後面不同的副本成為primary,任何將來的記錄也將分配到更高的offset或者不同的chunk。根據上述的一致性保證,成功的record append的region是defined和一致的,而中間的region是不一致的(undefined)。GFS的應用可以處理這種不一致的region(2.7.2)。
snapshot 操作拷貝一份文件或者目錄樹,幾乎是實時的,同時最大程度減少對正在進行中的mutation的干擾。
像AFS一樣,使用標準的COW技術實現snapshot。當master接收到一個snapshot請求,首先將所有涉及到chunks的租約撤銷,這保證了這些chunks後續的write將會先請求master查找租約持有者,master會創建一個新的副本來回應。
租約被撤銷或者過期後,master將這個操作記錄日誌到disk。新創建的snapshot引用元數據相同的chunks。
當snapshot操作完成後,客戶端第一次要寫chunk C,發送請求給master查詢持有租約者,master察覺到chunk C的引用大於1,則讓每個含有當前chunk副本的chunkserver創建一個新的chunk叫作C',所有創建都使用本地的副本,相比100Mb的網路本地速度大約是三倍速度。master授權租約給新的chunk C'中的一個並且回復給客戶端,之後正常地寫chunk。整個過程對客戶端是透明的。
master執行所有的namespace操作。另外,它管理整個系統的chunk副本:
接下來,詳細探討這些細節。
許多master操作可能花費較長一段時間,比如snapshot操作需要撤銷相關的所有chunks的租約。因此為了不delay其它master操作,在namesapce的regions上使用locks來確保串列化。
GFS沒有按目錄列出該目錄中所有文件的結構,也不支持文件和目錄的別名(unix中的硬鏈和軟鏈)。GFS將完整的路徑名到元數據的映射表作為它的邏輯namespace。使用前綴壓縮,這個表可以有效保存在內存中。namespace tree中的每個節點都有一個關聯的讀寫鎖。
每個master操作在運行前都會獲取一組鎖。如果涉及到/d1/d2/../dn/leaf,它將獲取目錄名稱/d1、/d1/d2、...、/d1/d2/.../dn上的讀鎖,完整路徑/d1/d2/../dn/leaf的讀鎖或者寫鎖。leaf可以是文件或者目錄。
創建文件不需要對父級目錄加鎖,因為沒有"目錄"的概念不會修改它,而加讀鎖是防止它被刪除、重命名或者snapshot。這種鎖機制的好處是允許相同目錄下並發的mutations。
一個GFS集群通常具有分布在多個機架上的數百個chunkserver,這些chunkserver也會被相同或者不同機架的數百個客戶端訪問。不同機架上的兩台計算機之間的通信可能會跨越一個或者多個網路交換機。另外進出機架的帶寬可能小於機架內所有計算機的總帶寬。多級分布式對如何分發數據以實現可伸縮性、可靠性和可用性提出了獨特的挑戰。
副本放置策略有兩個目的:最大化數據可靠性和可用性,最大化網路帶寬利用率。不僅要在多台機器上放置,還要在多個racks上,即使整個racks損壞也可以確保部分副本保持可用。也可以利用多個racks的總帶寬。
chunk副本創建有三個原因:
當master創建新的chunk時,根據幾個因素考慮如何放置新的副本:
當chunk可用副本的數量低於用戶指定時,master會重新復制。可能發生在幾種情況:
需要重新復制的chunk根據以下幾個因素確定優先順序:
master限制集群和每一個chunkserver內的活躍的clone數量,另外chunkserver通過限制其對源chunkserver的讀請求來限制在每個clone操作上花費的帶寬。
master會定期重新平衡副本:檢查當前副本的分布,遷移副本以獲得更好的磁碟空間利用率和負載平衡。同樣通過此過程,master逐漸填充一個新的chunkserver。另外,master通常更傾向於移除具有低磁碟利用率chunkservers上的副本,以平衡空間使用。
當文件被刪除時,master記錄日誌,但不會立即回收資源,而是將文件重命名為包含刪除時間戳標記的隱藏名稱。如果這些文件存在時間超過三天(時間可配置),master巡檢時會將其刪除。在此之前,仍然可以用特殊名稱來讀取文件,並且可以重命名為正常名稱來取消刪除。當從namesapce中刪除隱藏文件時,其內存元數據將被刪除,這有效切斷了所有chunk的連接,在對chunk namespace的掃描中,master識別出孤立的chunk並清除元數據。在心跳信息中,每個chunkserver報告其擁有的chunks子集,而master將回應不在存在於master元數據中的所有的chunk的標識。chunkserver可以自由刪除此類chunk的副本。
這種gc機制相比立即刪除有以下幾個優點:
這種機制主要的缺點是當存儲空間緊張時,延遲有時會影響用戶的使用,重復創建和刪除臨時文件的應用可能無法立即重用存儲。如果刪除的文件再次被明確刪除,GFS將通過加快存儲回收來解決這些問題。還允許用戶將不同的復制和回收策略應用於不同的namespace的不同部分中。
如果一個chunkserver故障或者chunk丟失了mutations,這個chunk副本可能是過期的。對於每個chunk,master都維護了一個chunk版本號。
當master授權租約給一個chunk時,這個chunk的版本號增加1,如果一個副本當前不可用了,則其版本號將不會領先。當chunkserver重新啟動並報告其chunks集合和相關聯的版本號時,master將檢測到該chunkserver上具有過期的副本。如果master看到的版本號大於它記錄的版本號,則認為在授權租約時失敗了,因此將較高的版本號更新。
master在常規gc中刪除舊的副本。另一個保護措施,在master回應客戶端哪個chunk持有租約或者clone操作中chunkserver從另一個chunkserver讀取chunk時會包含chunk的最新版本號。客戶端或者chunkserver在執行操作時會驗證版本號。
這個系統最大的挑戰之一是處理經常故障的組件。組件的質量和數量造成的問題會超出預期,組件故障可能造成系統不可能,甚至數據錯誤。接下來討論GFS如何應對這些挑戰,還有系統如何診斷不可避免問題。
使用兩個簡單有效的方式保證系統的高可用:快速恢復和復制。
master和chunkserver的恢復都是秒級別的。
master維護每個chunk的副本數量,當chunkserver下線或者checksum檢測出錯誤副本時,master會通過已有副本來復制。盡管復制提供了很好的解決方式,但仍在探索其它形式的跨伺服器冗餘方案,例如奇偶校驗或者糾刪碼,以適應不斷增長的只讀存儲需求。在非常松耦合的系統中實現這些更復雜的冗餘方案更具有挑戰性。
master的操作日誌和checkpoint會被復制到多台機器上,狀態的變化只有在本地和所有副本上都持久化以後才可以commit。master進程負責所有的mutations以及後台任務,當它宕機時可以很快重啟,如果機器或者磁碟故障,GFS的外部監控將使用日誌在其它節點重啟新的master進程。在master宕機時,master的備節點只提供只讀服務,它們不與master保持強一致,可能會落後於master,通常在1/4秒內。它們保證了那些不介意讀到過期數據的應用的高可用讀。類似於chunk的primary機制,master的備按照相同的序列應用日誌。與master一樣,在啟動時從每個chunkserver拉取chunks的位置信息,與它們頻繁交換握手消息來監控其狀態。
每個chunkserver使用checksum來檢測存儲數據的損壞。數據損壞的chunk可以通過其它的副本來恢復,但是通過副本間比較來檢驗數據是不切實際的。正常的副本也不是完全一樣的,如前文所講,原子的append並不能保證完全一樣的副本。因此每個chunkserver會維護自己的checksum。
每個chunk分為多個64kb的blocks,每個block包含一個32位的checksum,與其它元數據一樣,checksum保存在內存中,依靠log持久化,與用戶數據分離。
對於讀,chunkserver在返回數據給請求者前先檢測checksum,確保不會將出錯的數據傳輸給其它chunkservers或者客戶端。如果數據是壞的,chunkserver將錯誤返回給請求者並報告給master,請求者將會去讀其它副本, master將會根據其它副本重新克隆一份。當新的副本創建以後,master指示chunkserver將錯誤的副本刪除。checksum的計算不涉及I/O,對讀的影響比較小,客戶端通常嘗試使用對齊block邊界讀來減少overhead。
為append寫是做了checksum計算上的優化的,因為append寫是主要的負載(相比於overwrite)。GFS只增量地更新最後部分block的checksum,為新的block的計算新的checksum。這樣即使block已經損壞,新的checksum將與存儲的數據不會匹配,下次讀時將會與正常一樣被檢測出來。
如果一個寫請求要寫一個chunk中已存在的region,必要要先檢驗region的第一個和最後一個block的checksum,然後再重寫,最後計算新的checksums。因為第一個和最後一個block可能含有不被重寫的內容,如果這部分數據是損壞的,則新的checksum將包含錯誤的數據。
在idle時,checkserver可以掃描並檢查不活躍的chunks,可以檢測到冷chunks的錯誤,一旦錯誤被檢測到,master可以創建一個新的副本。
GFS在設計上與傳統文件系統有很多不同,這些點是基於對當時應用負載和技術環境的觀察所重新設計,將組件故障看作平常的事件而非異常,為大文件的讀取和追加寫做優化,擴展和放寬了標準的文件系統介面以改善整個系統。通過監控、復制以及快速恢復能力提供容錯能力,使用checksum機制來校驗數據的正確性。通過將控制流和數據流分離,數據直接在chunkservers、客戶端之間傳輸,為許多並發的各種任務的讀取和寫入提供了高吞吐量。大chunk size和租約機制使得master的操作足夠輕量化,使得這樣一個簡單中心化的master不會成為瓶頸。
GFS成功地滿足了google的存儲需求,作為研究、開發和數據處理的存儲平台廣泛地應用於google內部。
⑵ 系統一啟動就出現u大俠一鍵急救系統這一項,如何刪除
如果是WinXP系統,可以直接修改C盤下boot.ini文件。
如果是Win7系統,按以下操作:在運行輸入框上輸入「cmd」,打開了命令提示符窗口,會顯示U大俠一鍵急救系統的標識符,類似「{xxxxxxxx-xxxx-xxxx-xxxx- xxxxxxxxxxxx}」這樣的長字元串
然後將以下命令「bcdedit /delete {xxxxxxxx-xxxx-xxxx-xxxx- xxxxxxxxxxxx}」輸入上去,按回車鍵運行該命令即可刪除多餘的啟動菜單選項了。具體參見下圖