[zZ]HDFS-RAID使用Erasure Code來實現HDFS的數據冗余


From: http://yanbohappy.sinaapp.com/?p=106 Thx a lot:)

目前的HDFS中數據是靠三備份triplication來保證冗余的。顯然這只是一個簡單有效的方法而不是一個非常elegant的方法。三備份浪費了大量存儲空間,在集群規模較小的時候可能還不是那么明顯,但是對於大規模集群就比較明顯了。如果按照1GB存儲空間的成本是1$來算,如果數據規模是5TB,那么兩備份(10TB)和三備份(15TB)的成本差距只有5000$;而如果數據規模到了5PB的話,兩備份和三備份的成本差距就有5,000,000$。目前在GFS/HDFS普遍采用的三副本策略設計的初衷是由於commodity hardware在三副本的情況下可以保證不丟失數據。

在高端存儲上普遍采用的RAID機制是一種數據冗余策略。比較常見的RAID-5通過奇偶校驗的方法,能容忍磁盤陣列中任意1塊存儲設備失效而不丟失數據,但是需要一定的額外存儲空間來存放校驗數據。

那么在HDFS中能否使用類似的策略在不降低存儲可靠性的前提下降低存儲副本數目呢?Google在GFS2(即Colossus)系統中使用了Reed Solomon Erasure Code實現了成本更低的可靠存儲。Microsoft的Azure平台也使用了類似的Erasure Code技術來降低存儲成本。Facebook在開源Hadoop的基礎上也實現了一套基於Erasure Code的RAID方案(http://wiki.apache.org/hadoop/HDFS-RAID)。

Hadoop-hdfs-raid現在是對現有Hadoop的一個包裝,而不是把這部分代碼嵌入到現有的Hadoop代碼里,因為那樣會增加代碼的復雜度和不穩定性。從hadoop-2.0開始,它將要作為一個單獨的project存在,社區也加大了這一部分的開發力度。目前這一部分功能主要是Facebook在維護。Dhruba在今年的Hadoop Summit 2012中的一個關於HDFS的workshop(http://www.meetup.com/Hadoop-Contributors/events/60841502/)中談到了hdfs-raid在Facebook內部運行的情況。

存放在HDFS上的數據分為熱數據和冷數據兩種。熱數據一般是存放三備份,因為這些數據經常會被用到,所以多備份除了高效冗余外還能起到負載均衡的作用。對於冷數據,並一定要在HDFS里面保存3個副本。Dhruba介紹了兩種不同的RAID方案,對於不太冷的數據塊A/B/C,通過XOR方式產生parity數據塊,原來的數據塊A/B/C各保留2個replica,parity數據塊也有兩個replica,這樣,replica系數就從3減小到了2.6(理論值)。 對於很冷的數據,方案更加激進,由10個數據塊通過Reed Solomon算法生成4個parity file,對於原來的數據塊,只保留一個replica,parity數據塊有2份replica,這樣,replica系數就降到了1.2。那么這個過程是怎么做的呢?

整個hdfs-raid分為兩部分:RaidNode和DRFS(Distributed Raid File System)。

RaidNode:

(1)啟動一個RPC Server,接受RPC請求執行相應的命令。RPC對應的協議是RaidProtocol。集群管理員可以通過RaidShell給RaidNode發送命令。

(2)生成一個ConfigManager,通過讀取raid.xml配置文件,獲取用戶指定的Policy。一般一個Policy對應一個文件或者目錄,包括這個目錄下什么樣的文件會觸發RAIDing操作(例如srcReplication是3的文件,modTimePeriod為3600000表示最后一次修改時間在1個小時之前的文件才會被作為RAIDing的備選);這些文件采用何種編碼方式(XOR或者Reed Solomon);編碼之后parity file和meta file將要存放幾個備份(targetReplication和metaReplication)等。

(3)然后就是會啟動多個線程:BlockFixer線程用於定期掃描看是否有數據塊corruption然后執行修復;TriggerMonitor線程按照raid.xml配置的各種策略定期檢查相應的文件,然后執行encoding操作生成parity file;PurgeMonitor線程用於刪除已經廢棄的parity file;HarMonitor線程定期把parity file小文件按照Har的形式合並,減少NameNode元數據存儲的壓力。

DRFS(Distributed Raid File System):

DRFS是蓋在HDFS client之上的一層,截獲應用對HDFS client的調用。例如用戶訪問某塊數據,DRFS會調用HDFS client去NameNode/DataNode獲取數據,如果返回數據正常那么OK;如果讀取的過程中遇到corrupted data,那么DRFS client截獲HDFS client返回的 BlockMissingException,然后接管這個文件的讀取流,通過parity file恢復丟失的數據塊,然后返回給應用程序。所以整個數據塊恢復的過程對應用程序是透明的。而且DRFS client在讀取到corrupted data block然后恢復之后只是傳給了應用程序,並不會把數據恢復到HDFS中,而BlockFixer和通過RaidShell觸發的recoverFile操作會把修復好的塊復原到HDFS中。

整個流程講清楚之后,就要看看具體的實現。目前在RaidNode計算encoding和decoding的過程主要有兩種方法:

(1)LocalRaidNode:在RaidNode本地計算parity塊,因為計算parity塊是一個計算密集型任務,所以這種方法的可擴展性受到限制。

(2)DistributedRaidNode:通過MapReduce任務的形式把Job分布到不同的節點上來計算parity塊。

同樣對於BlockFixed也有兩種對應的方法:

(1)LocalBlockFixer: 在RaidNode本地decoding計算修復corrupted data塊。

(2)DistBlockFixer: 通過分布式MR任務的形式decoding

Erasure Code

EC是用來encoding和decoding的算法。在目前的Hadoop中有兩種實現:XOR和Reed Solomon。XOR只能允許丟失一塊數據,而RS可以容忍丟失多塊。目前的RS是采用(10,4)策略實現的,即10個數據塊生成4個parity file,那么可以容忍丟失4塊數據。

目前Erasure Code也是分布式存儲領域的研究重點,<<Rethinking Erasure Codes for Cloud File Systems:Minimizing I/O for Recovery and Degraded Reads>>-FAST2012和<<Erasure Coding in Windows Azure Storage>>-ATC2012是關於如何把Erasure Code用到現在的雲存儲中最新的兩篇頂級會議的文章,可能會給我們如何改進hdfs-raid有所啟發。

https://issues.apache.org/jira/browse/HDFS-3544 也在考慮一種新的數據塊恢復方法,因為在現有方法中,以(10,4)的RS編碼為例,如果發現某一塊數據丟失,那么需要另外10塊數據來恢復這個數據塊,那么在數據中心內部就會產生大量的網絡流量,可能會影響正常的Job運行。所以這個jira提出了使用http://arxiv.org/pdf/1109.0264.pdf 所提出的Simple Regenerating Codes來通過少量的存儲空間浪費來換取大量的帶寬資源的節省。

最后我聯想到一個問題,就是現在的雲計算數據中心是基於commodity hardware搭建的,數據中心各個server之間的通信是通過以太網來連接的,那么在各個server之間的控制流和數據流就是通過同一條物理網絡連接的,那么這樣必然會導致網絡爭用。而控制流要求低延遲,數據流要求高吞吐。GFS的paper里提到Google數據中心是控制流和數據流分別使用不同的物理網絡,我到沒聽說現在實際部署的Hadoop集群中是兩種流分開的,不知道為什么大家沒這么做?成本?復雜性?還是現階段沒有必要呢?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM