目的
副本策略開銷很大 -- HDFS 中默認的3復制方案在存儲空間和其他資源(例如,網絡帶寬)上有200% 的開銷。然而,對於 i/o 活動相對較低的溫和和冷數據集,在正常操作中很少訪問額外的塊副本,但仍然消耗與一個副本相同的資源量。
因此,一個自然的改進是使用擦除編碼(EC)來代替副本,它提供了同等級別的容錯能力,而且存儲空間大大減少。在典型的糾刪碼(EC)設置中,存儲開銷不超過50% 。EC 文件的復制因子是無意義的。它總是1,不能通過 -setorp 命令更改。
背景
在存儲系統中,EC 最顯著的用途是廉價磁盤冗余陣列(RAID)。RAID 通過條帶實現 EC,條帶將邏輯上順序的數據(如文件)划分為更小的單元(如位、字節或塊) ,並在不同的磁盤上存儲連續的單元。在本指南的其余部分中,這種條帶狀分布單元稱為striping cell(或cell)。對於原始數據單元的每一條,計算並存儲一定數量的奇偶校驗單元——這個過程稱為編碼。通過基於殘存數據和奇偶校驗單元的解碼計算,可以恢復任意條帶單元上的錯誤。
將 EC 與 HDFS 集成可以提高存儲效率,同時仍然提供與傳統的基於復制的 HDFS 部署相似的數據持久性。例如,一個有6個塊的3 復制文件將消耗6 * 3 = 18個磁盤空間塊。但是對於 EC (6數據,3奇偶校驗)部署,它將只占用9個磁盤空間塊。
架構
在EC的背景下,條帶化具有幾個關鍵優勢。首先,它啟用在線EC(以EC格式實時寫入數據),避免了轉換階段並立即節省了存儲空間。 Online EC還通過並行利用多個磁盤主軸來增加I/O性能。對高並發網絡的集群尤其理想;其次,它將一個小文件分發到多個DataNode,並且不需要將多個文件捆綁到一個編碼組中。這極大地簡化了例如刪除、配額報告以及聯合名稱空間之間遷移等文件操作。
在典型的HDFS群集中,小文件可占總存儲消耗的3/4以上。 為了更好地支持小文件,在第一階段的工作中,HDFS支持帶條帶化的EC。 將來,HDFS也將支持連續的EC設計。有關更多信息,請參見設計文檔和有關HDFS-7285(https://issues.apache.org/jira/browse/HDFS-7285)的討論。
- NameNode擴展
條帶HDFS文件在邏輯上由塊組構成,每個塊組包含一定數量的內部塊。為了減少NameNode對這些塊的內存消耗,引入了新的分層塊命名協議。可以從其任何內部塊的ID推斷出塊組的ID。這允許在塊組而不是塊的級別進行管理。
- 客戶端擴展
客戶端讀取和寫入路徑得到了增強,可以並行處理塊組中的多個內部塊。在輸出/寫入路徑上,DFSStripedOutputStream管理着一組數據流,每個數據節點一個,在當前塊組中存儲一個內部塊。這些流通常異步工作。協調器負責整個塊組的操作,包括結束當前塊組、分配新的塊組等。在輸入/讀取路徑上,DFSStripedInputStream將請求的邏輯字節數據轉換為存儲在DataNodes上的內部塊。然后並行發出讀取請求。當發生故障時,它將發出其他讀取請求以進行解碼。
- 數據節點擴展
數據節點運行附加ErasureCodingWorker(ECWorker)任務,用於后台恢復失敗的糾刪碼塊。 NameNode檢測到失敗的EC塊,然后選擇一個DataNode進行恢復工作。恢復任務以心跳響應方式進行傳遞。此過程類似於采用復制策略恢復丟失的數據塊。重建執行三個關鍵任務:
(1)從源節點讀取數據
使用專用線程池從源節點並行讀取輸入數據。基於EC策略,它計划對所有源數據進行讀取請求,並僅讀取最少數量的輸入塊以進行重建。
(2)解碼數據並生成輸出數據
從新數據和奇偶校驗塊解碼成原始數據。所有丟失的數據和奇偶校驗塊一起解碼。
(3)將生成的數據塊傳輸到目標節點
解碼完成后,恢復的數據塊將傳輸到目標DataNodes。
- 糾刪碼策略
為了適應異步的工作負載,我們允許HDFS集群中的文件和目錄具有不同的復制和糾刪碼策略。糾刪碼策略封裝了如何對文件進行編碼/解碼。每個策略由以下信息定義:
EC模式:這包括EC組(例如6 + 3)中的數據塊和奇偶校驗塊的數量,以及糾刪碼算法(例如Reed-Solomon,XOR)。
條帶單元的大小。 這確定了條帶讀取和寫入的粒度,包括緩沖區大小和編碼工作。
策略被命名為*編解碼器-數據塊數-奇偶校驗塊-單元大小*。當前,支持六種內置策略:RS-3-2-1024k,RS-6-3-1024k,RS-10-4-1024k,RS-LEGACY-6-3-1024k,XOR-2-1- 1024k和復制(REPLICATION)。
復制是一項特殊政策,它只能在目錄上設置,以強制目錄采用3倍復制方案,而不繼承其原始的糾刪碼策略。此策略可以使3x復制方案目錄與糾刪碼目錄交錯。
REPLICATION策略始終處於默認開啟狀態。對於其他內置策略,默認情況下禁用。
與HDFS存儲策略類似,在目錄上設置糾刪碼策略。創建文件后,它將繼承其最近祖先目錄的EC策略。
目錄級EC策略僅影響目錄中創建的新文件。創建文件后,可以查詢其糾刪碼策略,但不能更改。如果將糾刪碼文件重命名為具有其他EC策略的目錄,則該文件將保留其現有的EC策略。將文件轉換為其他EC策略需要重寫該數據。通過復制文件(例如,通過distcp)而不是重命名來做到這一點。
我們允許用戶通過XML文件配置自己的EC策略,該文件必須包含以下三個部分:
\1. 布局版本:這表示EC策略XML文件格式的版本;
\2. 模式:這包括所有用戶定義的EC模式;
\3. 策略:這包括所有用戶定義的EC策略,每個策略都由架構ID和條帶化單元的大小(cellsize)組成。
Hadoop conf目錄中有一個名為user_ec_policies.xml.template的示例EC策略XML文件,用戶可以參考該文件。
- Intel ISA-L
Intel ISA-L代表英特爾智能存儲加速庫。ISA-L是針對存儲應用程序而優化的低級功能的開源集合。它包括針對Intel AVX和AVX2指令集優化的快速塊Reed-Solomon類型糾刪碼。HDFS糾刪碼可以利用ISA-L加速編碼和解碼計算。ISA-L支持大多數主要操作系統,包括Linux和Windows。默認情況下不啟用ISA-L。請參閱以下說明以了解如何啟用ISA-L。
部署方式
集群和硬件配置
糾刪碼在CPU和網絡方面對群集提出了其他要求。
編碼和解碼工作會消耗HDFS客戶端和DataNode上額外的CPU資源。
糾刪碼要求群集中的DataNode最少與配置的EC條帶寬度一樣多。 對於EC策略RS(6,3),這意味着至少需要9個DataNode。
糾刪碼文件分布在整個機架上,以實現機架容錯。這意味着在讀寫條帶化文件時,大多數操作都是在機架上進行的。因此,網絡分帶寬非常重要。
對於機架容錯,具有至少與配置的EC條帶寬度一樣多的機架也很重要。對於EC策略RS(6,3),這意味着最少要有9個機架,理想情況下是10或11個機架,以處理計划內和計划外的中斷。對於機架少於條帶寬度的群集,HDFS無法保持機架容錯,但仍將嘗試在多個節點之間分布條帶化文件以保留節點級容錯。
配置項
默認情況下,dfs.namenode.ec.system.default.policy默認啟用,其他所有內置糾刪碼策略均被禁用。群集管理員可以根據群集的大小和所需的容錯屬性,通過hdfs ec [-enablePolicy -policy
可以通過“dfs.namenode.ec.system.default.policy”配置來設置系統默認EC策略。使用此配置時,如果在“-setPolicy”命令中未傳遞任何策略名稱,則使用默認的EC策略,“dfs.namenode.ec.system.default.policy”默認為“RS-6-3-1024k”。
可以使用以下客戶端和DataNode配置密鑰來配置Reed-Solomon和XOR的編解碼器實現:默認RS編解碼器的io.erasurecode.codec.rs.rawcoders;舊版RS編解碼器的io.erasurecode.codec.rs-legacy.rawcoders;XOR編解碼器的io.erasurecode.codec.xor.rawcoders。用戶還可以使用密鑰來配置自定義編解碼器,例如:io.erasurecode.codec.self-defined-codec.rawcoders。這些鍵的值是帶有備用機制的編碼器名稱列表。這些編解碼器工廠將按照配置值指定的順序加載,直到成功加載編解碼器為止。默認的RS和XOR編解碼器配置首選純Java本地實現。沒有RS-LEGACY本機編解碼器實現,因此默認設置僅為純Java實現。所有這些編解碼器均具有純Java實現。對於默認的RS編解碼器,還有一個本機實現,可利用英特爾ISA-L庫提高編解碼器的性能。對於XOR編解碼器,還支持利用Intel ISA-L庫提高編解碼器性能的本機實現。請參閱“啟用Intel ISA-L”一節以獲取更多詳細信息。RS Legacy的默認實現是純Java,默認RS和XOR的默認實現是使用Intel ISA-L庫的本機實現。
還可以通過以下配置參數來調整DataNode上的糾刪碼后台恢復工作:
(1)dfs.datanode.ec.reconstruction.stripedread.timeout.millis:條帶讀取的超時,默認值為5000毫秒。
(2)dfs.datanode.ec.reconstruction.stripedread.buffer.size:讀取器服務的緩沖區大小,默認值為64KB。
(3)dfs.datanode.ec.reconstruction.threads:Datanode用於后台重建工作的線程數,默認值為8個線程。
(4)dfs.datanode.ec.reconstruction.xmits.weight:EC后台恢復任務與復制塊恢復相比使用的xmit的相對權重,默認值為0.5。設置為0將禁用EC恢復任務的計算權重,即EC任務始終具有1 xmits。糾刪碼恢復任務的xmit被計算為讀取流的數量和寫入流的數量之間的最大值。例如,如果EC恢復任務需要從6個節點讀取並寫入2個節點,則它的xmit值為max(6,2)* 0.5 =3。復制文件的恢復任務始終計為1 xmit。 NameNode利用dfs.namenode.replication.max-streams減去DataNode上的總xmitsInProgress(將來自復制文件和EC文件的xmit組合在一起)來調度恢復任務到此DataNode。
啟用Intel ISA-L
默認RS編解碼器的HDFS本機實現利用Intel ISA-L庫來改善編碼和解碼計算。要啟用和使用Intel ISA-L,需要執行三個步驟。
(1)建立ISA-L庫。請參閱官方網站“https://github.com/01org/isa-l/”以獲取詳細信息;
(2)使用ISA-L支持構建Hadoop。 請參閱源代碼(BUILDING.txt)中“Hadoop的構建說明”中的“Intel ISA-L構建選項”部分;
(3)使用-Dbundle.isal將isal.lib目錄的內容復制到最終的tar文件中。 使用tar文件部署Hadoop。 確保ISA-L在HDFS客戶端和DataNode上可用。
要驗證Hadoop是否正確檢測到ISA-L,請運行hadoop checknative命令。
管理命令
HDFS提供了一個ec子命令來執行與糾刪碼有關的管理命令。
hdfs ec [generic options]
[-setPolicy -path <path> [-policy <policyName>] [-replicate]]
[-getPolicy -path <path>]
[-unsetPolicy -path <path>]
[-listPolicies]
[-addPolicies -policyFile <file>]
[-listCodecs]
[-enablePolicy -policy <policyName>]
[-disablePolicy -policy <policyName>]
[-help [cmd ...]]
以下是有關每個命令的詳細信息。
- [-setPolicy -path
[-policy ] [-replicate]]
在指定路徑的目錄上設置糾刪碼策略。
path:HDFS中的目錄。必填參數。設置策略僅影響新創建的文件,不影響已有文件。
policyName:用於此目錄下文件的糾刪碼策略。如果設置了“dfs.namenode.ec.system.default.policy”配置,則可忽略此參數。EC策略下的path將在配置中設置為默認值。
-replicate:在目錄上應用特殊的REPLICATION策略,強制采用3x復制方案。
-replicate和-policy
- [-getPolicy -path
]
獲取指定路徑下文件或目錄的糾刪碼策略的詳細信息。
- [-unsetPolicy -path
]
取消先前對目錄上調用所設置的糾刪碼策略。如果從祖先目錄繼承了糾刪碼策略,則unsetPolicy是no-op。在沒有顯式策略集的目錄上取消設置策略不會返回錯誤。
- [-listPolicies]
列出在HDFS中注冊的所有(啟用,禁用和刪除)糾刪碼策略。只有啟用的策略才適合與setPolicy命令一起使用。
- [-addPolicies -policyFile
]
添加糾刪碼策略列表。請參閱etc/hadoop/user_ec_policies.xml.template獲取示例文件。單元格的大小在屬性“dfs.namenode.ec.policies.max.cellsize”中定義,默認為4MB。當前,HDFS允許用戶總共添加64個策略,並且添加的策略ID在64到127之間。如果已經添加了64個策略,添加策略將失敗。
- [-listCodecs]
獲取系統中支持的糾刪碼編解碼器和編碼器列表。編碼器是編解碼器的一種實現。編解碼器有不同的實現和類型。編解碼器以列表順序列出。
- [-removePolicy -policy
]
刪除糾刪碼策略。
- [-enablePolicy -policy
]
啟用糾刪碼策略。
- [-disablePolicy -policy
]
禁用糾刪碼策略。
局限性
由於大量的技術挑戰,某些糾刪碼文件不支持一些HDFS操作,如hflush,hsync,concat,setReplication,truncate和append。
- 糾刪碼文件上的append()和truncate()將拋出IOException。
- 如果文件與不同的糾刪碼策略或復制的文件混合使用,則concat()將引發IOException。
- setReplication()對糾刪碼文件不起作用。
- DFSStripedOutputStream上的hflush()和hsync()是空指令。因此,在糾刪碼文件上調用hflush()或hsync()不能保證數據持久化。
客戶端可使用StreamCapabilities API查詢OutputStream是否支持hflush()和hsync()。如果客戶端希望通過hflush()和hsync()進行數據持久化,則當前的補救措施是在非糾刪碼目錄中創建此類文件,例如常規3x復制文件,或者使用FSDataOutputStreamBuilder#replicate()API在糾刪碼目錄中創建3x復制文件。