Hadoop 3.x 之糾删碼技術分析

Shockang 2021-08-15 21:13:49 阅读数:451

本文一共[544]字,预计阅读时长:1分钟~
hadoop 3.x 分析

這是我參與8月更文挑戰的第6天,活動詳情查看:8月更文挑戰

正文

概述

HDFS 為了提高可靠性,采用了“暴力”的三副本技術,這就帶來了存儲成本的問題。業界一直在探索如何降低存儲成本。 傳統的 RAID 技術就被很自然地借鑒過來與 HDFS 相結合。 通過結合 RAID 的 糾删碼(Erasuredcode)技術,存儲成本從原來的 HDFS 默認的3倍降低到1.4倍。 從 Hadoop3.x 開始 HDFS 就已經使用文件糾删碼技術(ErasuredCode)代替三副本機制了。

糾删碼(ErasuredCode/EC)

原理

糾删碼常見的有三類:Reed-Solomen 類、級聯低密度糾删碼和數字噴泉碼。

這裏只簡單介紹下目前廣泛應用的 Reed-Solomen 類糾删碼。

從糾刑碼的基本形態來看,它是N個數據+M個校驗的結構,其中數據和校驗的N和M值都能够按照一定的規則設定。

在1~M個數據塊(數據或校驗均可)損壞的情况下,整體數據仍然可以通過計算剩餘數據塊上的數據得出,整體數據不會丟失,存儲仍然可用。

在這裏插入圖片描述

從圖中可以看出,糾删碼和RAID技術有些類似,一個條帶(Stripe)是由多個數據塊(Strip) 構成的,分為數據塊和校驗塊。

但與 RAID5、 RAID6 不同的是,糾删碼從功能上來看最大的區分特點是校驗和數據的比例可按N+M可調整,並且校驗塊數量不再受限於兩個,典型的如12+4、6+3等。

關於 RAID 技術請參考我的這篇博客——一篇文章搞懂 RAID 技術是什麼

糾删碼的演化:RS→LRC

糾删碼通過技術含量較高的算法,提供和副本近似的可靠性,同時减小了額外所需冗餘設備的數量,提高了存儲設備的利用率。

但糾删碼所帶來的額外負擔主要是計算量和數倍的網絡負載

尤其是在出現硬盤故障後,重建數據將耗費大量的CPU資源,而且計算一個數據塊需要通過網絡讀出N倍的數據並傳輸,所以網絡負載也有數倍甚至數十倍的增加。

從整體來看,若采用糾删碼技術,則能够得到希望的容錯能力和存儲資源利用率,但是需要接受一定的數據重建代價,二者之間需要進行平衡。

那麼,有沒有優化改善的空間呢?

如果仔細分析故障出現的原因,則會很容易發現兩個特征。

  1. 所有的故障都將導致同樣的重建代價,無論是一個盤還是M個盤。
  2. 單個磁盤出現故障的概率遠遠大於多個磁盤同時出現故障的概率,通常在90%以上。

因此,優化的思路自然聚集到更容易出現的單個磁盤故障上來。

如何更有效地處理這種概率較大的事件呢?

最佳的解决方案是分組,把單個磁盤故障的影響範圍縮小到各個組內部,當磁盤出現故障時,在該組內部解决,在恢複過程中讀組內更少的盤,跑更少的網絡流量,從而减小對全局的影響。

LRC

LRC(Locally Repairable Codes)意為局部校驗編碼,其核心思想為:

將校驗塊分為全局校驗塊和局部校驗塊,在故障恢複時分組計算。

以微軟 Azure 的雲存儲(Windows Azure Storage)實現為例:

  1. 它采用LRC(12,2,2)編碼,12個數據塊為一組編碼,並進一步將這12個數據塊平均分為兩個本地組,每個本地組包括6個數據塊,並分別計算出一個局部校驗塊,之後把所有12個數據塊計算出兩個全局校驗塊。
  2. 當發生任何一個數據塊錯誤時,只需將本地組內的數據和校驗塊用於計算,即可恢複出原始數據。
  3. 恢複代價(通過網絡傳輸的數據塊數量)就由傳統RS(124)編碼的12變為6,恢複過程的網絡1O開銷减半,同時空間冗餘率保持不變,仍為(12+2+2)/12=1.33

總結

相對於副本而言,糾删碼(Erasure Code)的編碼技術無疑對存儲空間利用率帶來很大提昇,但由於引入額外的編碼、解碼運算,對分布式系統的計算能力和網絡都有一定的額外要求。簡單地理解就是硬件性能要昇級,網絡環境也要昇級,昇級的代價在現階段還是一筆不小的預算。

而由於性能損失的原因,用在本身壓力已經很大、很“熱”的在線存儲系統明顯不是很合適, 所以目前大多數系統還是把Erasure Code用於冷數據的離線處理階段。

LRC編碼由於减少了網絡1O0傳輸的數據量,所以參與數據恢複運算的數據量和重建時間基本上能够縮短一倍,但這是以犧牲可靠性和空間利用率為代價的。

HDFS RAID(Facebook)

  1. HDFS RAID 方案是 Facebook 在 Hadoop0.20-append 分支上做的,為了不引入複雜度,基於 HDFS,沒有修改 HDFS,只支持離線(异步)EC。
  2. RAID Node定期掃描配置發現需要轉換成EC的文件轉換過程可以本地計算,也可以通過 MapReduce 任務來計算。
  3. RAID Node 內部有一個 BlockFixer 線程定期檢查被配置成 EC 的文件路徑,如果文件有丟失或者腐化的 Block,則需要本地重算或者通過 MapReduce Job來重算,然後將生成的 Block 插入文件系統中。
  4. 客戶端方面不需修改任何代碼,只需修改配置,告訴它使用的文件系統是 DistributedRaidFileSystem。
  5. 它封裝了 DFSClient,截獲 DFS Client 的請求,當 DFS Client 拋出 ChecksumException 或者 Block MissingException 時,DRFS 捕獲這些异常,定比特到相應的 Parity File,然後重新計算出丟失的 Block,隨後返回給客戶端。

HDFS RAID 整體結構

HDFS RAID的實現(Facebook的實現)主要是在現有的HDFS上增加了一個包裝 Contrib,如圖所示。之所以不在HDFS上直接修改,原設計者的解釋是HDFS的核心代碼已經够複雜了不想讓它更複雜

在這裏插入圖片描述

  1. 從使用的角度看, HDFS RAID的使用場景主要有兩個:RAID 數據管理和 RAID 數據讀取。
  2. RAID Node是 HDFS RAID 中除 NameNode 和 ResourceManager 之外的第三個 MasterNode,主要用於接收 Client 端的RPC請求和調度各守護線程完成數據的 RAID 化和數據修複、 Parity 文件删除等操作。

RAID 和 unRAID 流程詳解

數據 RAID 化

文件數據的RAID化有兩種場景

  1. 通過 RAID Shell執行 raidFile 命令觸發;
  2. TriggerMonitor 線程周期性地掃描 Policy,根據新的配置信息進行相應的 RAID 化。

損壞數據的恢複

觸發場景
  1. Client 端使用 DRFS 讀取數據發生數據丟失或損壞延長。
  2. RAID Node 上的 BlockIntegrityMonitor,周期性地獲取 Block 數據發現數據异常時
  3. 通過 RAID Shell 執行 fixblock 時
Block 讀取時修複損壞數據的流程
  1. 在 Client 端配置 DRFS 並使用 DFS 作為內置 FS 的情况下,當通過 FS.open 獲取文件 InputStream 時,返回一個 ExtFSDataInputStream 實例。
  2. 通過該 InputStream 讀取數據時,首先通過內置的 DFS 讀取響應的 Block,正常情况下返回需要的數據。
  3. 當內置的 DFS 讀取 Block 時,若跑出 CorruptionException 或 DecomissionException,則會被 ExtFSDataInputStream 捕獲。 通過調用 RaidNode.unRaidCorruptionBlock() 方法來獲取一個恢複的 Block,並從該 Block 讀取數據。
Block Monitor線程修複

RAID Node 上的 BlockIntegrityMonitor 線程會通過文件檢查工具檢查系統中沖突或失效的數據,然後通過 BlockCopier 和 BlockFixer 線程周期性地對這些數據進行修複。

在 Local模式下,修複過程在 RaidNode 上執行;而在 Dist 模式下,修複過程通過提交Job的方式交由集群完成。

HDFS-7285

  1. 集成 EC 在 HDFS 中

HDFS-7285 和 HDFS RAID 不同,它將編碼過程集成到 HDFS 內部,需要對整個 HDFS 內部實現進行改造,包括 DataNode、 NameNode及 DFS Client。該方案同時支持在線和離線 EC。

  1. 小結:HDFS-7285 比 HDFS RAID 更全面、性能更好,在線 EC 可以立即降低存儲成本。

Ozone

HDFS是應用級的塊存儲,為了支持非文件性質的系統數據, Hortonworks 改進了HDFS,將塊存儲和對象存儲融合,提出 Ozone,將HDFS從文件系統擴展到更複雜的企業應用。

過去,HDFS架構將元數據管理與數據存儲分離成兩個相互獨立的層。

文件數據存儲在包含有上千個存儲服務器(節點)的存儲層,而元數據存儲在文件元數據層。

HDFS的這種分離方式使得應用直接從存儲磁盤讀寫數據時能够獲得很高的吞吐量擴展空間。

Ozone使得HDFS塊存儲層能够進一步支持非文件性質的系統數據,而HDFS的文件塊架構也將支持存儲鍵值和對象。

與HDFS的名稱空間元數據類似, Ozone的元數據系統也基於塊存儲層, 但是 Ozone的元數據將被動態分配,支持大量的 Bucket Space。

Hortonworks認為,HDFS將自然進化成一個完整的企業大數據存儲系統,而 Ozone也將以 Apache 項目(HDFS-7240)的方式開源。

vSAN

HDFS是根據 Google 的論文啟發而發明的塊存儲,但是 HDFS 應該理解為應用級的存儲,程序完全構建在 OS 普通用戶態空間裏,存儲的可靠性靠“暴力”的三副本來保證。

訪問 HDFS 需要使用專門的接口,因此 HDFS 只適合在 Hadoop 領域使用簡單的塊存儲軟件,並沒有存儲很多企業特性, 如快照、重複數據消除等。

傳統的存儲都構築在專門的SAN硬件上,通信接口也采用SAS等存儲專有接口,專有服務器帶來的成本高、擴展性差等缺陷越來越不被客戶所接受。

隨著分布式技術的發展,一些專門做存儲的廠商自然而然地想到用通用服務器來做存儲,於是就有了一系列解决方案,最有名的是 Vmware的Virtual SAN。

Hadoop 3.x 文件糾删碼技術

在EC背景下,striping 有幾個關鍵優勢。

首先,它啟用了在線EC(立即以EC格式寫入數據),避免了轉換階段,並立即節省存儲空間。

在線EC還通過並行利用多個磁盤主軸來提高順序I/O性能;這在具有高端網絡的集群中尤為可取。

其次,它自然地將一個小文件分發給多個DataNodes,並消除了將多個文件捆綁到單個編碼組中的必要性。這大大簡化了文件操作,如删除、配額報告和聯邦命名空間之間的遷移。

在典型的HDFS集群中,小文件可以占總存儲消耗的四分之三以上。為了更好地支持小文件,在第一階段的工作中,HDFS支持帶條紋的EC。

未來HDFS還將支持連續的EC布局。有關更多信息,請參閱HDFS-7285的設計文檔和討論。

NameNode擴展

Striped HDFS 文件在邏輯上由塊組組成,每個塊組包含一定數量的內部塊。

為了减少這些額外塊的NameNode內存消耗,引入了一種新的分層塊命名協議。

塊組(block group)的ID可以從其任何內部塊的ID推斷。

這允許在塊組而不是塊級別進行管理。

客戶端擴展

客戶端讀寫路徑被增强,以並行處理塊組中的多個內部塊。

在輸出/寫入路徑上,DFSStripedOutputStream 管理一組數據流,每個數據節點一個,在當前塊組中存儲一個內部塊。

數據流大多异步工作。協調員(coordinator)負責整個塊組的操作,包括結束當前塊組、分配新的塊組等。

在輸入/讀取路徑上,DFSStripedInputStream 將請求的數據邏輯字節範圍轉換為存儲在 DataNodes 上的內部塊。

然後,它並行發布讀取請求。失敗後,它會發出額外的讀取請求進行解碼。

DataNode擴展

DataNode運行一個額外的 ErasureCodingWorker(ECWorker)任務,用於後臺恢複失敗的 Erasure 編碼塊。

失敗的EC塊由NameNode檢測,然後選擇數據節點進行恢複工作。恢複任務作為心跳響應傳遞。

這個過程類似於複制的塊在失敗時如何複制。

重建時將執行三項關鍵任務

  1. 從源節點讀取數據:使用專用線程池從源節點並行讀取輸入數據。基於EC策略,它將讀取請求調度到所有源目標,並只讀取用於重建的最小輸入塊數。
  2. 解碼數據並生成輸出數據:從輸入數據解碼新數據和奇偶校驗塊。所有缺失的數據和奇偶校驗塊一起解碼。
  3. 將生成的數據塊傳輸到目標節點:解碼完成後,恢複的塊將傳輸到目標數據節點。

文件糾删碼策略

為了適應异構的工作負載,我們允許 HDFS 集群中的文件和目錄具有不同的複制和糾删碼策略。

糾删碼策略封裝了如何對文件進行編碼/解碼。

每個策略由以下信息定義:

  1. EC模式:這包括EC組中的數據和奇偶校驗塊的數量(例如6+3),以及編解碼器算法(例如Reed-Solomon,XOR)。
  2. striping cell 的大小:這决定了條紋讀寫的粒度,包括緩沖區大小和編碼工作。

策略被命名為 codec-num data blocks-num parity blocks-cell size 。

目前,支持五種內置策略:RS-3-2-1024k、RS-6-3-1024k、RS-10-4-1024k、RS-LEGACY-6-3-1024k、XOR-2-1-1024k。

默認的複制方案也受支持。它只能設置在目錄上,以强制目錄采用3倍複制方案,而不是繼承其祖先的糾删碼策略。此策略使3倍複制方案目錄與糾删碼目錄交織成為可能。

複制總是啟用的。在所有EC策略中,默認情况下啟用RS(6,3)。

與HDFS存儲策略類似,糾删碼策略設置在目錄上。創建文件時,它將繼承其最近祖先目錄的EC策略。

目錄級EC策略僅影響目錄內創建的新文件。創建文件後,可以查詢其删除編碼策略,但不能更改。

如果删除編碼文件重命名為具有不同EC策略的目錄,則該文件將保留其現有EC策略。

將文件轉換為不同的EC策略需要重寫其數據;通過複制文件(例如通過distcp)而不是重命名來做到這一點。

關於 distcp 請參考我的這篇博客——distcp 是什麼?如何在兩個 HDFS 集群之間傳輸數據?

我們允許用戶通過XML文件定義自己的EC策略,該文件必須包括以下三個部分:

  1. 布局版本:這錶示EC策略XML文件格式的版本。
  2. 模式:這包括所有用戶定義的EC模式。
  3. 策略:這包括所有用戶定義的EC策略,每個策略由模式ID和 striping cell(單元大小)的大小組成。

一個名為 user_ec_policies.xml.template 的EC策略XML文件示例比特於Hadoop conf目錄中,用戶可以引用。

英特爾 ISA-L

英特爾ISA-L代錶英特爾智能存儲加速庫。

ISA-L是為存儲應用程序設計的優化低級函數的開源集合。

它包括為英特爾 AVX 和 AVX2 指令集優化的快速 Reed-Solomon 類型糾删碼。

HDFS 糾删碼可以利用ISA-L來加速編碼和解碼計算。

ISA-L支持大多數主要操作系統,包括Linux和Windows。

默認情况下,ISA-L不啟用。

版权声明:本文为[Shockang]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/08/20210815211248099Q.html