1. 程式人生 > >0432-什麼是HDFS的糾刪碼

0432-什麼是HDFS的糾刪碼

Fayson的github: https://github.com/fayson/cdhproject

推薦關注微信公眾號:“Hadoop實操”,ID:gh_c4c535955d0f,或者掃描文末二維碼。

在這裡插入圖片描述

Fayson在前面的文章中介紹過CDH6,參考《Cloudera Enterprise 6正式釋出》和《如何在Redhat7.4安裝CDH6.0》。CDH6主要整合打包了Hadoop3,包括Hadoop3的一些新特性的官方支援,比如NameNode聯邦,糾刪碼等。糾刪碼可以將HDFS的儲存開銷降低約50%,同時與三分本策略一樣,還可以保證資料的可用性。本文Fayson主要介紹糾刪碼的工作原理。

預設情況下,HDFS的資料塊都會儲存三個副本。副本提供了一種簡單而健壯的冗餘方式來最大化保證資料的可用性。資料的多副本同時可以儘量保證計算任務的本地化。

但副本方式成本是較高的:預設情況下三副本方式會在儲存空間或其他資源(比如寫入資料時的網路頻寬)中產生200%的開銷。對於較少訪問的資料集(對叢集的I/O影響相對不大),它們的第二個或者第三個副本會比較少訪問,但是仍會消耗相同的儲存空間。

因此可以使用糾刪碼(ErasureCoding)來代替多副本的方式,它使用更少的儲存卻可以保證相同級別的容錯。在典型配置下,與三副本方式相比,EC可以將儲存成本降低約50%。基於這個考慮,Cloudera與Intel的工程師在

HDFS-7285下啟動並推動了HDFS-EC專案。目前HDFS-EC已經在CDH6和HDP3中釋出。

本文主要會介紹HDFS糾刪碼的設計。該需求來源於Cloudera的大型客戶對HDFS的要求,我們的設計主要是解決如何將HDFS改造以支援EC。後面將詳細討論如何將EC應用於HDFS,對NameNode,DataNode和客戶端讀寫路徑所做的更改,以及使用Intel ISA-L加速編碼和解碼計算的優化。最後,我們將討論未來的一些開發工作,包括對不同資料佈局和高階EC演算法的支援。

1.背景

1.1.EC和RAID

在比較不同的儲存方案時,有兩個重要的考慮因素:資料永續性(通過能夠容忍同時故障的數量來衡量)和儲存效率(邏輯大小除以原始使用)。

副本方式(比如RAID1和HDFS)是一種容忍磁碟故障簡單而有效的方法,但代價是額外的儲存開銷。N個副本可以容忍N-1個同時發生故障,儲存效率1/n。比如HDFS預設的三副本最多可容忍兩個副本故障,儲存效率為三分之一(或者開銷為200%)。

Erasurecoding糾刪碼技術簡稱EC,是一種資料保護技術。最早用於通訊行業中資料傳輸中的資料恢復,是一種編碼容錯技術。他通過在原始資料中加入新的校驗資料,使得各個部分的資料產生關聯性。在一定範圍的資料出錯情況下,通過糾刪碼技術都可以進行恢復。

在儲存系統中,糾刪碼技術主要是通過利用糾刪碼演算法將原始的資料進行編碼得到校驗,並將資料和校驗一併儲存起來,以達到容錯的目的。其基本思想是將k塊原始的資料元素通過一定的編碼計算,得到m塊校驗元素。對於這k+m塊元素,當其中任意的m塊元素出錯(包括資料和校驗出錯),均可以通過對應的重構演算法恢復出原來的k塊資料。生成校驗的過程被成為編碼(encoding),恢復丟失資料塊的過程被稱為解碼(decoding)。
表1:XOR (exclusive-or,異或) 操作

表1:XOR (exclusive-or,異或) 操作

如表1所示,最簡單的EC實現可以基於異或操作(XOR),XOR碼的原理是:資料編碼時按照位進行異或運算,資料恢復的時候也就是解碼時則通過結果與其他資料位進行異或操作的逆運算。異或操作與我們常見的”與”操作和”或”操作略有不同,遵循”相同為0,不同則為1”的運算原則。如表1,⊕就是異或操作的意思。

現在假設最後一個式子中的第二位,就是數字第一個數字1丟失了,變成了下面這個式子:

0 ⊕ ? ⊕ 1 = 0;

我們可以通過異或操作的逆運算恢復資料,因為最後結果為0,所以0 ⊕ ?的結果應該為1,也就是0 ⊕ ? = 1,因為異或運算,不同才為1,所以這裡丟失的資料就是1,資料成功恢復.但是這裡暴露出了一個問題,如果丟失或損壞的資料位超過1位的時候,資料好像就不是那麼好恢復了,比如丟失了頭2位:

? ⊕ ? ⊕ 1 = 0;

這個時候頭2位是0,1還是1,0呢?只能說都有可能。OK,從這裡我們可以看出XOR編碼演算法存在可容忍錯誤過少的問題,那麼有什麼別的EC演算法能幫我們解決這個問題呢?在很多場合下,是會存在多個數據丟失的情況的,並不能確保每次只有1個數據出錯的情況。下面介紹的新的編碼演算法能解決這個棘手的問題。

Reed-SolomonCodes也是EC編碼中的一種。Reed-Solomon Codes縮寫為RS碼,中文名稱裡德所羅門碼。RS使用複雜的線性代數運算來生成多個奇偶校驗塊,因此可以容忍每組多個故障。這是一個生產儲存系統的常見選擇。RS需要配置2個引數,k和m。如圖1所示,RS(k,m)通過將k個數據塊的向量與生成矩陣(GT)相乘來實現,從而得到一個碼字(codeword)向量,該向量由k個數據塊和m個校驗塊構成。如果一個數據塊丟失,可以用(GT)-1乘以碼字向量來恢復出丟失的資料塊。RS(k,m)最多可容忍m個塊(包括資料塊和校驗塊)丟失。

圖1:有4個數據庫和2個奇偶校驗塊的Reed-Solomon編碼
參考:https://www.usenix.org/legacy/event/fast09/tech/full_papers/plank/plank.pdf

使用Reed-Solomon,你可以通過設定不同的k和m來靈活的調整資料永續性和儲存成本。奇偶校驗塊的數量m確定可以容忍的同時儲存故障的數量。資料塊與奇偶校驗塊的比率決定了儲存效率:

典型的RS配置如RS(6,3)和RS(10,4)與三副本方式相比,可提供不錯的資料永續性與儲存效率。因為它們可以分別容忍多達三個或四個故障,並且<50 %儲存開銷。表2比較了副本、XOR和RS的容錯和儲存效率。

表2:副本、XOR和RS容錯和儲存效率比較

本地儲存系統也經常使用EC技術,特別是RAID5和RAID6。RAID5一般使用XOR編碼,因為她只需要容忍單個磁碟故障,而RAID6使用Reed-Solomon和兩個奇偶校驗塊來容忍最多兩個磁碟故障。資料塊與校驗塊的比例是可以配置的,一組糾刪碼資料由資料塊和校驗塊組成,這些塊與每塊磁碟是對應的。如下圖2所示:

圖2:RAID5和RAID6示例
參考:https://en.wikipedia.org/wiki/Standard_RAID_levels

1.2.分散式系統中的糾刪碼

為了管理非常大的檔案,分散式儲存系統通常將檔案劃分為固定大小的邏輯塊。然後將這些邏輯塊對映到叢集上的儲存塊,這反映了叢集上資料的物理佈局。

邏輯塊和儲存塊之間最簡單的對映是連續的塊佈局,它將每個邏輯塊一對一對映到儲存塊。讀取連續塊佈局的檔案就像按順序線性讀取每個儲存塊一樣簡單。

相比之下,條帶式塊佈局將邏輯塊分成更小的儲存單元(通常稱為cells),並在一組儲存塊中以輪詢的方式寫入單元條帶(stripes of cells)。讀取帶有條帶佈局的檔案需要查詢邏輯塊的儲存塊集,然後從儲存塊集中讀取單元條帶。本節討論如何在兩種塊佈局上支援EC。

資料被依次寫入一個塊中,一個塊寫滿之後再寫入下一個塊,資料的這種分佈方式被稱為連續佈局。在一些分散式檔案系統如QFS和Ceph中,廣泛使用另外一種佈局:條帶式佈局。條(stripe)是由若干個相同大小單元(cell)構成的序列。在條形佈局下,資料被依次寫入條的各個單元中,當條被寫滿之後就寫入下一個條,一個條的不同單元位於不同的資料塊中。如圖3所示,在條帶式示例圖中,對應的EC編碼型別是RS(6, 3)。前面從DataNode05總共6個節點存資料塊,後面的DataNode68存的則是加密塊。

圖3:EC使用連續儲存和條帶式儲存的示例

原則上,塊佈局(連續與條帶)和冗餘形式(副本複製與EC)是兩個正交維度,產生四種可能的組合。如圖4所示,主流的儲存系統都會使用這幾種方式。某些系統(包括Ceph和QFS)支援在每個目錄或每個檔案的基礎上配置佈局方式和/或冗餘方式。

圖4:現有分散式儲存系統使用塊佈局和冗餘方式的範圍

如前所述,就儲存效率而言,糾刪碼優於副本複製方式。然而,這是以額外的複雜性和更昂貴的故障恢復為代價的。

沿著塊佈局維度,條帶化可以提供比連續佈局更好的I/O吞吐量,因為它可以並行的更好的利用多個磁碟(multiple spindles)。然而這意味著大多數讀取都是遠端的,強調需要快速完全平分網路。這種方法與傳統的MapReduce在處理資料時強調的資料本地性(data locality)相矛盾,但是如果應用程式在瞭解底層cell和條帶大小的情況下讀取和寫入資料,則仍然還是可行的。

2.設計和實現

2.1.選擇塊佈局

對於HDFS-EC,最重要的問題是確定哪種塊佈局最合適。連續佈局更容易實現,因為讀取和寫入路徑與採取副本複製方式的當前系統非常相似。但是它僅適用於檔案非常大的情況,因為只有在寫入完整的條帶時,才能發揮成本節省的所有優勢。例如對於RS(10,4),如果一個條帶僅僅只有一個單獨的128MB的資料塊,但仍然需要寫入4個128MB的奇偶校驗塊,儲存開銷為400%,比三副本方式開銷還大。連續佈局也僅適用於離線或後臺EC,否則客戶端需要快取GB級的資料塊以計算奇偶校驗。

另一方面,條帶式佈局的EC可以同時實現小檔案和大檔案的儲存空間節省,因為一個cell都比較小(通常為64KB-1MB)。cell較小同時也允許你線上做EC,客戶端可以直接寫入糾刪碼資料,因為僅僅只需要幾MB的快取來計算奇偶校驗資訊。缺點是對於位置敏感(locality-sensitive,就是上文提到的有些強依賴data-locality的MapReduce作業會消耗大量的網路資源的情況。)的工作負載效能不會太好,如果執行在條帶塊上。為了更好的執行此類工作負載,可以將條帶檔案轉換為連續佈局,但這幾乎需要重寫整個檔案。

基於此分析,檔案大小是最關鍵的決定因素。如果叢集中儲存的都是大檔案 - 每個檔案至少由6個128MB的block組成,可以滿足RS(6,3)模式下的完整EC組 - 那麼連續佈局是合適的,因為我們可以不用去實現合併多個小檔案到一個EC組。但是如果叢集中儲存的是大量小檔案,從儲存成本和管理上來說的話,條帶化佈局是更好的選擇。

圖5:來自生產叢集的檔案大小直方圖

我們研究了Cloudera最大的三個客戶的HDFS檔案大小分佈,詳細報告可以參考,圖5是對該報告的一個總結。我們有一個重要發現,小檔案(少於一個EC組)的使用基本佔比為36%-97%,表明小檔案問題都比較嚴重。

基於這一發現,我們在HDFS-EC的第一階段,開發主要專注於實現條帶式佈局的EC。

2.2.泛化NameNode中的Block概念

該專案的主要工作在於泛化HDFSblock的基本概念以支援資料條帶化。連續塊佈局被廣泛而深入地嵌入到HDFS內部邏輯中。為了支援條帶佈局,邏輯塊的概念必須與儲存塊的概念分開。前者表示檔案中的邏輯位元組範圍,而後者是儲存在DataNode上的資料塊的基本單位。圖6是邏輯和儲存塊的概念的示例。在該示例中,檔案/tmp/foo在邏輯上被劃分為13個條帶化單元(cell_0到cell_12)。邏輯塊0(圖中的logicalblock 0)表示cell_0~8的邏輯位元組範圍,邏輯塊1(圖中的logical block 1)表示cell_9~12。cell_0,3,6組成儲存塊,該儲存塊將作為單個數據塊儲存在DataNode上。為簡明起見,該圖不包括奇偶校驗塊/單元。

圖6:邏輯和儲存塊

支援此泛化的一種簡單的機制是HDFSNameNode監視其塊對映中的每個儲存塊,該對映從塊ID對映到相應的塊,然後使用另一個對映從邏輯塊轉到其成員儲存塊(member storage block)。但是這意味著小檔案會在NameNode上產生大量記憶體開銷,因為條帶化會導致比備份複製方式更多的儲存塊。

為了減少這種開銷,我們引入了一種新的分層塊命名協議。目前,HDFS根據塊建立時間順序分配塊ID。該協議將每個塊ID分成2~3個部分,如圖7所示。每個塊ID以一個標誌(flag)開始,表示其佈局(連續=0,條帶= 1)。對於條帶塊,ID的其餘部分由兩部分組成:中間部分,ID為邏輯塊,尾部表示邏輯塊中儲存塊的索引。這允許NameNode管理邏輯塊作為其儲存塊的摘要(summary)。可以通過遮蔽索引將儲存塊ID對映到其邏輯塊,當DataNode向NameNode彙報block時必須這麼做。

圖7:分層塊命名協議

基於圖5中三個叢集的HDFS image檔案,我們模擬了啟用了EC後NameNode的記憶體使用情況。結果表明,如果沒有新的分層塊命名協議,條帶化將使NameNode塊對映的大小增加250%440%。使用該協議,條帶化僅將NameNode塊對映增加21%76%。有關記憶體開銷分析的更多詳細資訊,請參考

由於此設計,邏輯塊在NameNode上顯示為一組內部儲存塊。表3總結了與條帶化和EC塊相關的術語。預設的EC策略是使用6個數據塊和3個奇偶校驗塊,以及64KB的條帶化cell大小。我們是根據一些真實叢集的典型的檔案大小來選擇的這個預設值。其他的EC模式,比如Facebook使用HDFS-RAID的(10,4)設定,具有更好的儲存效率,但會導致恢復資料花費更高,並且對叢集中的機架數量有更高的要求。

表3:EC塊相關的術語

支援邏輯塊抽象需要更新NameNode的許多部分。舉一個例子,為了防止資料丟失,HDFS會自動嘗試複製副本數不足的資料。以前該演算法僅考慮剩餘副本的數量,但現在被泛化為還包括EC schema的資訊。其他主要變化包括updating quota,fsck,balancer等。

2.3.客戶端擴充套件

HDFS客戶端的主要I/O邏輯在DFSInputStream和DFSOutputStream中實現。為了支援資料條帶化和EC,我們已經將它們擴充套件為DFSStripedInputStream和DFSStripedOutputStream。擴充套件背後的基本原理是允許客戶端節點並行處理邏輯塊中的多個儲存塊。當與HDFS加密一起使用時,這些擴充套件在加密資料上執行 - 即在加密層下面。

在輸出/寫入路徑上,DFSStripedOutputStream管理一組資料流(data streamers),每個DataNode用於在當前邏輯塊中儲存內部儲存塊。streamers大多是非同步工作的。協調器負責整個邏輯塊的操作,包括結束當前邏輯塊,分配新的邏輯塊,等等。

在輸入/讀取路徑上,DFSStripedInputStream將請求的邏輯位元組資料範圍轉換為儲存在DataNode上的內部儲存塊。然後它並行發出讀取請求。失敗後,它會發出額外的解碼讀取請求。

2.4.DataNode擴充套件

為了避免在客戶端進行資料重建,這個成本往往較高,後臺能夠識別和修復DataNode故障是非常重要的。與以前的複製備份方式一樣,NameNode需要負責跟蹤EC條帶中的缺失塊,並給DataNode分配恢復這些缺失塊的任務。DataNode上的恢復工作由新的ErasureCodingWorker(ECWorker)元件處理,該元件執行以下操作以重建缺少的EC塊:

1.從源節點讀取資料:在ErasureCodingWorker啟動時會初始化一個專用的執行緒池用於從不同的源節點讀取資料塊。基於EC schema,它排程對所有源目標的讀取請求,並確保僅讀取重建所需的最小輸入塊。

2.解碼資料並生成輸出資料:與EC客戶端類似,ECWorker會在Erasure Codec Framework中引入的編解碼器框架完成解碼/編碼工作。

3.將生成的資料塊傳輸到目標節點:解碼完成後,它會將輸出資料封裝到資料包並將它們傳送到目標DataNode。

2.5.編解碼器計算框架

資料編碼/解碼是CPU密集型的,所以在使用糾刪碼技術時也是資源的主要開銷。為了緩解HDFS-EC,我們利用英特爾的開源智慧儲存加速庫(英特爾ISA-L,Intelligent Storage Acceleration Library),通過利用SSE,AVX和AVX2等高階硬體指令集,加速與EC相關的線性代數計算。ISA-L支援所有主要作業系統,包括Linux和Windows。參考

在HDFS-EC中,我們通過兩種形式實現了Reed-Solomon演算法:一種基於ISA-L,另一種基於純Java(適用於沒有所需CPU的系統)。我們比較了這兩種實現的效能,同時比較了Facebook的HDFS-RAID實現的編碼器。本節中的所有測試都使用RS(6,3)。

圖8顯示了基於記憶體的編碼/解碼基準測試的結果。 ISA-L實現比HDFS-ECJava實現快4倍以上,比Facebook HDFS-RAID編碼器快約20倍。根據這個結果,我們強烈建議生產系統部署實施ISA-L加速。

圖8:編碼和解碼效能比較

我們還比較了不同編碼器的端到端的HDFS I/O效能,包括HDFS預設的三副本方式。測試環境是10Gb網路,11個節點(1個NameNode,9個DataNode,1個客戶端節點)。圖9主要包括:1)客戶端將12GB檔案寫入HDFS的吞吐量結果; 2)客戶端從HDFS讀取12GB檔案。在讀取測試中,我們手動殺死了兩個DataNode,因此結果包括解碼開銷。

圖9:HDFS I/O效能比較

如圖9所示,在順序寫入/讀取及讀取基準測試中,吞吐量受到純Java編碼器(HDFS-RAID和我們自己的實現)的極大限制。ISA-L實現比純Java編碼器快得多,因為它具有出色的CPU效率。同時它比三副本方式快2-3倍,因為條帶化佈局允許客戶端並行執行多個DataNode的I/O,從而利用其磁碟驅動器的總吞吐。我們還測試了讀取效能,沒有任何DataNode故障:HDFS-EC比三副本方式快大約5倍。

請注意,應該可以進一步提高效能。使用RS(6,3)佈局,條帶佈局應該能夠實現I/O吞吐量大約6倍的提升,或大約1GB/s的吞吐量。當前效能部分不符合理論上的優化,因為條帶佈局將邏輯順序I/O請求傳播到多個DataNode,這可能會降低本地磁碟驅動器上的順序I/O模式。我們計劃在未來的優化中為客戶端新增更高階的預取(prefetching)和寫緩衝(writebuffering)。

ISA-L的另一個重要優化是支援增量編碼。這意味著應用程式在開始編碼過程之前不必等待所有源資料。這將有可能使HDFS-EC能夠有效地處理慢速寫入應用程式以及追加操作。

3.未來的工作

本文總結了HDFS-EC的第一個開發階段。在HDFS-8031下已經確定並記錄了許多令人興奮的擴充套件和優化。後續的一個主要任務是構建一個通用的EC策略框架,允許系統使用者部署和配置多個編碼模式,如傳統的Reed-Solomon,HitchHiker,LRC等。通過抽象和模組化通用編解碼器邏輯,該框架還將使使用者能夠輕鬆開發新的EC演算法。我們還計劃進一步優化NameNode記憶體消耗並減少資料重建延遲。

為了節省位置敏感型(locality-sensitive,就是前文提到的有些強依賴data-locality的MapReduce作業會消耗大量的網路資源的情況。)工作負載的檔案儲存空間,我們建立了HDFS-EC第二階段(HDFS-8030)以支援具有連續塊佈局的EC。

4.總結

與複製備份方式相比,糾刪碼可以將HDFS的儲存開銷減少大約50%,同時保證相同的資料可用性。這樣可以節省大量在硬體的儲存上的投入,因為使用者現在可以在相同數量的原始儲存上儲存兩倍的資料。

實現HDFS-EC需要在HDFS的許多部分進行改進,同時需要Cloudera,Intel和其他ApacheHadoop社群的開發人員的協作努力才能完成。HDFS-EC的設計通過使用新的分層塊命名協議在NameNode上產生最小的額外開銷(主要是對NameNode的記憶體),並且還利用IntelISA-L中的優化Reed-Solomon事務(routines )來實現奇偶校驗資訊的高效能編碼和解碼。

5.Erasure Coding技術的優劣勢

優勢

糾刪碼技術作為一門資料保護技術,自然有許多的優勢,首先可以解決的就是目前分散式系統,雲端計算中採用副本來防止資料的丟失。副本機制確實可以解決資料丟失的問題,但是翻倍的資料儲存空間也必然要被消耗。這一點卻是非常致命的。EC技術的運用就可以直接解決這個問題。

劣勢

EC技術的優勢確實明顯,但是他的使用也是需要一些代價的,一旦資料需要恢復,它會造成2大資源的消耗:

1.網路頻寬的消耗,因為資料恢復需要去讀其他的資料塊和校驗塊

2.進行編碼,解碼計算需要消耗CPU資源

概況來講一句話,就是既耗網路又耗CPU,看來代價也不小。所以這麼來看,將此技術用於線上服務可能會覺得不夠穩定,所以最好的選擇是用於冷資料叢集,有下面2點原因可以支援這種選擇:

1.冷資料叢集往往有大量的長期沒有被訪問的資料,體量確實很大,採用EC技術,可以大大減少副本數

2.冷資料叢集基本穩定,耗資源量少,所以一旦進行資料恢復,將不會對叢集造成大的影響

出於上述2種原因,冷資料(叢集)無疑是一個很好的選擇。當然如果採購的硬體支援Intel CPU的ISA-L,使用其實也是不錯的,畢竟比三副本的方式還優秀!

作者資訊:

Andrew Wang (Hadoop PMC) and Zhe Zhang are Software Engineers at Cloudera.

Kai Zheng and Uma Maheswara G. (Hadoop PMC) are Software Engineers at Intel.

Vinayakumar B. (Hadoop PMC) is a Software Engineer at Huawei; previously, he worked at Intel.

本文參考:

http://blog.cloudera.com/blog/2015/09/introduction-to-hdfs-erasure-coding-in-apache-hadoop/

https://blog.csdn.net/Androidlushangderen/article/details/51923582

https://blog.csdn.net/androidlushangderen/article/details/50724917

https://mp.weixin.qq.com/s?__biz=MzA5MTc0NTMwNQ==&mid=2650713566&idx=1&sn=ce41e2e0dfbe4889f64e5eb0422ebb95&mpshare=1&scene=1&srcid=1023lMtBMxdoicxjzgeupIyI#rd


為天地立心,為生民立命,為往聖繼絕學,為萬世開太平。

推薦關注Hadoop實操,第一時間,分享更多Hadoop乾貨,歡迎轉發和分享。
在這裡插入圖片描述

原創文章,歡迎轉載,轉載請註明:轉載自微信公眾號Hadoop實操

在這裡插入圖片描述