複製成本昂貴 - HDFS 中預設的 3 倍複製配置在儲存空間和其他資源(例如網路頻寬)上有 200% 的開銷。然而,對於 I/O 活動相對較低的溫暖和冷資料集,在正常作業期間很少會存取額外的區塊複本,但仍會消耗與第一個複本相同的資源量。
因此,一個自然的改進是使用抹除編碼 (EC) 取代複製,它以更少的儲存空間提供相同程度的容錯能力。在典型的抹除編碼 (EC) 設定中,儲存空間開銷不超過 50%。EC 檔案的複製因子沒有意義。它永遠是 1,且無法透過 -setrep 命令變更。
在儲存系統中,EC 最顯著的用途是廉價磁碟陣列 (RAID)。RAID 透過分區來實作 EC,它將邏輯上順序的資料(例如檔案)分割成較小的單位(例如位元、位元組或區塊),並將連續的單位儲存在不同的磁碟上。在本指南的其餘部分中,這個分區分配單位稱為分區儲存格(或儲存格)。對於每個原始資料儲存格分區,會計算並儲存一定數量的奇偶儲存格 - 這個過程稱為編碼。任何分區儲存格上的錯誤都可以透過根據倖存資料和奇偶儲存格進行解碼計算來復原。
整合 EC 與 HDFS 可提升儲存效率,同時仍提供與傳統基於複製的 HDFS 部署類似的資料耐用性。例如,一個 3 倍複製且有 6 個區塊的檔案將耗用 6*3 = 18 個區塊的磁碟空間。但使用 EC(6 個資料、3 個奇偶)部署時,它只會耗用 9 個區塊的磁碟空間。
在 EC 的架構中,條帶化有幾個重要的優點。首先,它能啟用線上 EC(立即以 EC 格式寫入資料),避免轉換階段並立即節省儲存空間。線上 EC 也透過平行使用多個磁碟主軸來提升順序 I/O 效能;這在具有高效能網路的叢集特別理想。其次,它會自然地將小檔案分佈到多個資料節點,並消除將多個檔案綑綁成單一編碼群組的必要性。這大幅簡化了檔案作業,例如刪除、配額報告以及在聯合命名空間之間遷移。
在典型的 HDFS 叢集中,小檔案可能佔總儲存量超過 3/4。為了更好地支援小檔案,在工作的這個第一階段,HDFS 支援條帶化的 EC。未來,HDFS 也將支援連續的 EC 配置。請參閱設計文件和 HDFS-7285 上的討論,以取得更多資訊。
NameNode 擴充 - 條帶化的 HDFS 檔案在邏輯上由區塊群組組成,每個區塊群組都包含一定數量的內部區塊。為了減少 NameNode 記憶體消耗,因此引入了新的階層式區塊命名協定。區塊群組的 ID 可以從其任何一個內部區塊的 ID 推論出來。這允許在區塊群組層級進行管理,而不是在區塊層級。
客戶端擴充 - 客戶端的讀寫路徑已增強,以便平行處理區塊群組中的多個內部區塊。在輸出/寫入路徑上,DFSStripedOutputStream 管理一組資料串流器,每個串流器對應一個在目前區塊群組中儲存內部區塊的資料節點。串流器大多數是異步工作的。一個協調器負責整個區塊群組上的作業,包括結束目前的區塊群組、配置新的區塊群組,等等。在輸入/讀取路徑上,DFSStripedInputStream 將請求的資料邏輯位元組範圍轉換為儲存在資料節點上的內部區塊範圍。然後,它平行發出讀取請求。在發生故障時,它會發出額外的讀取請求進行解碼。
資料節點擴充 - 資料節點會執行額外的 ErasureCodingWorker (ECWorker) 任務,以背景復原已損毀的擦除編碼區塊。損毀的 EC 區塊是由 NameNode 偵測到的,然後 NameNode 會選擇一個資料節點來執行復原工作。復原任務會作為心跳回應傳遞。這個程序類似於在發生故障時如何重新複製已複製的區塊。重建會執行三個主要任務
讀取來源節點的資料:輸入資料使用專用執行緒池從來源節點平行讀取。根據 EC 政策,它會排定所有來源目標的讀取要求,並僅讀取重建所需的最小輸入區塊數目。
解碼資料並產生輸出資料:從輸入資料解碼新的資料和奇偶區塊。所有遺失的資料和奇偶區塊會一起解碼。
將產生的資料區塊傳輸至目標節點:解碼完成後,會將復原的區塊傳輸至目標資料節點。
抹除編碼政策為了容納異質工作負載,我們允許 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
架構也受支援。它只能設定在目錄上,以強制目錄採用 3x 複製架構,而不是繼承其祖先的抹除編碼政策。此政策讓 3x 複製架構目錄與抹除編碼目錄交錯排列。
REPLICATION
始終啟用。在所有 EC 政策中,RS(6,3) 預設啟用。
與 HDFS 儲存政策類似,抹除編碼政策設定在目錄上。建立檔案時,它會繼承其最近祖先目錄的 EC 政策。
目錄等級的 EC 政策只會影響在目錄中建立的新檔案。建立檔案後,其抹除編碼政策可以查詢,但無法變更。如果抹除編碼檔案重新命名為具有不同 EC 政策的目錄,檔案會保留其現有的 EC 政策。將檔案轉換為不同的 EC 政策需要重新寫入其資料;透過複製檔案(例如透過 distcp)而不是重新命名檔案來執行此動作。
我們允許使用者透過 XML 檔案定義自己的 EC 政策,該檔案必須具有下列三個部分
layoutversion:這表示 EC 政策 XML 檔案格式的版本。
schemas:這包括所有使用者定義的 EC 架構。
政策:這包括所有使用者定義的 EC 政策,且每項政策都包含架構 ID 和分割儲存格 (cellsize) 的大小。
範例 EC 政策 XML 檔案,命名為 user_ec_policies.xml.template,位於 Hadoop conf 目錄中,使用者可以參考。
Intel ISA-L Intel ISA-L 代表 Intel Intelligent Storage Acceleration Library。ISA-L 是針對儲存應用程式設計的最佳化低階函式開放原始碼集合。它包含針對 Intel AVX 和 AVX2 指令集最佳化的快速區塊 Reed-Solomon 型態抹除碼。HDFS 抹除編碼可以利用 ISA-L 來加速編碼和解碼運算。ISA-L 支援大多數主要作業系統,包括 Linux 和 Windows。ISA-L 預設未啟用。請參閱以下說明,了解如何啟用 ISA-L。
抹除編碼對叢集的 CPU 和網路提出額外需求。
編碼和解碼工作會消耗 HDFS 儲存體和資料節點上的額外 CPU。
抹除編碼至少需要叢集中與組態 EC 分割區寬度一樣多的資料節點。對於 EC 政策 RS (6,3),這表示至少需要 9 個資料節點。
抹除編碼的檔案也會跨機架分散,以提供機架容錯能力。這表示在讀取和寫入分割檔案時,大多數作業都是機架外作業。因此,網路二分頻寬非常重要。
對於機架容錯能力,擁有足夠數量的機架也很重要,如此一來,平均而言,每個機架所儲存的區塊數量不會超過 EC 校驗區塊的數量。計算此數量的公式為 (資料區塊 + 校驗區塊) / 校驗區塊,無條件進位。對於 EC 政策 RS (6,3),這表示至少需要 3 個機架(計算方式為 (6 + 3) / 3 = 3),理想情況下則需要 9 個或更多機架,以處理計畫內和計畫外中斷。對於機架數量少於校驗儲存格數量的叢集,HDFS 無法維持機架容錯能力,但仍會嘗試將分割檔案分散到多個節點,以維持節點層級的容錯能力。因此,建議設定具有類似資料節點數量的機架。
預設情況下,所有內建的抹除編碼政策均已停用,除了在 dfs.namenode.ec.system.default.policy
中定義的政策,預設情況下已啟用。叢集管理員可透過 hdfs ec [-enablePolicy -policy <policyName>]
指令,根據叢集大小和所需的容錯屬性,啟用一組政策。例如,對於有 9 個機架的叢集,RS-10-4-1024k
等政策將無法保留機架層級容錯,而 RS-6-3-1024k
或 RS-3-2-1024k
可能會更合適。如果管理員僅關心節點層級容錯,只要叢集中至少有 14 個資料節點,RS-10-4-1024k
仍會合適。
可透過「dfs.namenode.ec.system.default.policy」設定,設定系統預設 EC 政策。有了這個設定,當在「-setPolicy」指令中未傳遞政策名稱作為引數時,將會使用預設 EC 政策。
預設情況下,「dfs.namenode.ec.system.default.policy」為「RS-6-3-1024k」。
Reed-Solomon 和 XOR 的編解碼器實作可以使用下列用戶端和 DataNode 組態金鑰進行組態:io.erasurecode.codec.rs.rawcoders
(預設 RS 編解碼器)、io.erasurecode.codec.rs-legacy.rawcoders
(舊版 RS 編解碼器)、io.erasurecode.codec.xor.rawcoders
(XOR 編解碼器)。使用者也可以使用組態金鑰組態自訂編解碼器,例如:io.erasurecode.codec.self-defined-codec.rawcoders
。這些金鑰的值是編碼器名稱清單,並有後備機制。這些編解碼器工廠會按照組態值指定的順序載入,直到成功載入編解碼器為止。預設 RS 和 XOR 編解碼器組態優先使用原生實作,而非純 Java 實作。沒有 RS-LEGACY 原生編解碼器實作,因此預設只有純 Java 實作。所有這些編解碼器都有純 Java 實作。對於預設 RS 編解碼器,也有原生實作,它利用 Intel ISA-L 函式庫來提升編解碼器的效能。對於 XOR 編解碼器,也支援原生實作,它利用 Intel ISA-L 函式庫來提升編解碼器的效能。請參閱「啟用 Intel ISA-L」區段,以取得更多詳細資訊。RS Legacy 的預設實作是純 Java,而預設 RS 和 XOR 的預設實作是使用 Intel ISA-L 函式庫的原生實作。
也可以透過下列組態參數調整 DataNode 上的背景復原工作
dfs.datanode.ec.reconstruction.stripedread.timeout.millis
- 條紋讀取逾時。預設值為 5000 毫秒。dfs.datanode.ec.reconstruction.stripedread.buffer.size
- 讀取器服務的緩衝區大小。預設值為 64KB。dfs.datanode.ec.reconstruction.threads
- Datanode 用於背景復原工作的執行緒數目。預設值為 8 個執行緒。dfs.datanode.ec.reconstruction.xmits.weight
- 與複製區塊復原比較,EC 背景復原任務使用的 xmits 相對權重。預設值為 0.5。設定為 0
以停用計算 EC 復原任務的權重,也就是說,EC 任務永遠有 1
個 xmits。抹除編碼復原任務的 xmits 計算為讀取串流數與寫入串流數之間的最大值。例如,如果 EC 復原任務需要從 6 個節點讀取並寫入 2 個節點,則它的 xmits 為 max(6, 2) * 0.5 = 3
。複製檔案的復原任務總是算作 1
個 xmit。NameNode 使用 dfs.namenode.replication.max-streams
減去 DataNode 上的總 xmitsInProgress
,而 DataNode 結合了複製檔案和 EC 檔案的 xmits,以排程復原任務到這個 DataNode。HDFS 原生實作的預設 RS 編碼器利用 Intel ISA-L 函式庫來改善編碼和解碼計算。若要啟用並使用 Intel ISA-L,有三個步驟。
-Dbundle.isal
將 isal.lib
目錄的內容複製到最終的 tar 檔案中。使用 tar 檔案部署 Hadoop。請確定 HDFS 客戶端和 DataNode 上有 ISA-L。若要驗證 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>] [-removePolicy -policy <policyName>] [-verifyClusterSetup -policy <policyName>...<policyName>] [-help [cmd ...]]
以下是每個指令的詳細資料。
[-setPolicy -path <path> [-policy <policyName>] [-replicate]]
在指定路徑的目錄上設定抹除編碼政策。
path
:HDFS 中的目錄。這是強制性參數。設定政策只會影響新建立的檔案,不會影響現有的檔案。
policyName
:要使用在這個目錄下檔案的抹除編碼政策。如果設定了「dfs.namenode.ec.system.default.policy」組態,則可以省略這個參數。路徑的 EC 政策會設定為組態中的預設值。
-replicate
套用目錄上的預設 REPLICATION
架構,強制目錄採用 3x 複製架構。
-replicate
和 -policy <policyName>
是可選參數。它們不能同時指定。
[-getPolicy -path <path>]
取得在指定路徑的文件或目錄的抹除編碼政策的詳細資料。
[-unsetPolicy -path <path>]
取消先前呼叫 setPolicy
在目錄上設定的抹除編碼政策。如果目錄從祖先目錄繼承抹除編碼政策,unsetPolicy
是一個空操作。取消未設定明確政策的目錄上的政策不會傳回錯誤。
[-listPolicies]
列出在 HDFS 中註冊的所有(已啟用、已停用和已移除)抹除編碼政策。只有已啟用的政策適合與 setPolicy
指令搭配使用。
[-addPolicies -policyFile <file>]
新增使用者定義的抹除編碼政策清單。請參閱 etc/hadoop/user_ec_policies.xml.template 以取得範例政策檔案。最大儲存格大小在屬性「dfs.namenode.ec.policies.max.cellsize」中定義,預設值為 4MB。目前 HDFS 允許使用者總共新增 64 個政策,且新增的政策 ID 介於 64 到 127 之間。如果已新增 64 個政策,新增政策會失敗。
[-listCodecs]
取得系統中支援的抹除編碼編解碼器和編碼器的清單。編碼器是編解碼器的實作。編解碼器可以有不同的實作,因此有不同的編碼器。編解碼器的編碼器會以備用順序列出。
[-removePolicy -policy <policyName>]
移除使用者定義的抹除編碼政策。
[-enablePolicy -policy <policyName>]
啟用抹除編碼政策。
[-disablePolicy -policy <policyName>]
停用抹除編碼政策。
[-verifyClusterSetup -policy <policyName>...<policyName>]
驗證叢集設定是否支援所有已啟用的抹除編碼政策。如果指定選用參數 -policy,驗證叢集設定是否支援指定的政策。
由於技術上的重大挑戰,某些 HDFS 作業,例如 hflush
、hsync
、concat
、setReplication
、truncate
和 append
,不支援抹除編碼檔案。
append()
和 truncate()
會擲回 IOException
。concat()
將會擲出 IOException
。setReplication()
在抹除編碼檔案上是 no-op。hflush()
和 hsync()
在 DFSStripedOutputStream
上是 no-op。因此,在抹除編碼檔案上呼叫 hflush()
或 hsync()
無法保證資料是持久的。用戶端可以使用 StreamCapabilities
API 查詢 OutputStream
是否支援 hflush()
和 hsync()
。如果用戶端希望透過 hflush()
和 hsync()
達到資料持久性,目前的補救措施是在非抹除編碼目錄中建立 3x 複製檔案,或使用 FSDataOutputStreamBuilder#replicate()
API 在抹除編碼目錄中建立 3x 複製檔案。