Erasure code 代替RAID的案例

Microsoft、Google、Facebook的erasure code技術進展及系統分析

http://blog.sina.com.cn/s/blog_999d1f4c0101e160.html


數據規模龐大(目前google、淘寶等存儲的大數據規模以PB爲單位)、大數據增長速度遠超過摩爾定律,如何利用有限存儲資源滿足迅速膨脹的存儲需求成爲大數據時代存儲技術面臨的一項重大挑戰。多副本策略在滿足存儲可靠、優化數據讀性能同時也不可避免地造成存儲資源利用率低的缺陷。erasurecode編碼存儲策略在滿足和多副本同樣可靠性前提下,可以達到更高的存儲資源利用率。
當前,Microsoft、Google、Facebook、Amazon、淘寶等互聯網巨頭早已開始研究erasurecode編碼存儲技術,並將其實用各自主流存儲系統中,本文將分析比較Microsoft、Google、Facebook的erasurecode編碼技術及系統如下:
GoogleRS(6,3)in GFSII (Colossus)
Microsoft、Google、Facebook的erasure <wbr>code技術進展及系統分析
Google GFS II中採用了最基本的RS(6,3)編碼,將一個待編碼數據單元(Data Unit)分爲6個data block,再添加3個parity block,最多可容包括parity blocks在內的任意3個數據塊錯誤。存儲的space overhead爲(6+3)/6 =1.5x.數據恢復的網絡I/O開銷爲:恢復任何一個數據塊需要6次I/O,通過網絡傳輸6個數據block.
Microsoft:erasure code in WAS(Windows Azure Storage)
Microsoft、Google、Facebook的erasure <wbr>code技術進展及系統分析
爲減少數據恢復時的網絡I/O,微軟採用瞭如上LRC編碼策略,其核心思想爲:將校驗塊(parityblock)分爲全局校驗塊(global parity)、局部校驗塊(local reconstructionparity).微軟LRC(12,2,2)編碼將一個待編碼數據塊分爲12個data blocks,並進一步將這12個datablocks平均分爲2個groups,每個group包括6個data blocks.爲每個data group分別計算出一個localparity,以及所有12個data blocks計算出2個globalparities.當發生任何一個數據塊錯誤時,恢復代價由傳統RS(12,4)編碼的12(通過網絡傳輸的數據塊數量),變爲6,恢復過程的網絡I/O開銷減半。Microsoft以上LRC編碼的space overhead爲(12+2+2)/12 = 1.33x
Facebook:從RS(10,4)到LRC(10,6,5)
Microsoft、Google、Facebook的erasure <wbr>code技術進展及系統分析
RS(10,4)編碼是Facebook HDFSRAID的早期編碼方式,如上圖所示。將每個待編碼Data Unit均分爲10個data block,後面添加4個校驗的parities.以上編碼方式的space overhead爲(10+4)/10 =1.4x,發生任何一個數據塊錯誤的恢復代價爲10,即發生任意一個塊錯誤需要10次I/O操作,從網絡傳輸的數據量爲10個數據塊。
同樣爲減少數據恢復的網絡I/O,Facebook於VLDB2013發表名爲“XORing Elephants”的LRC編碼方法如下:
Microsoft、Google、Facebook的erasure <wbr>code技術進展及系統分析
除了在原先的10個data blocks之後添加4個parities外,還將10個datablocks均分爲2組,每組單獨計算出一個局部校驗塊(Parity),將數據恢復代價由原來的10降低爲5.即恢復任何一個數據塊錯誤只需要進行5次網絡I/O,從網絡傳輸5個數據塊。此種編碼方式的spaceoverhead 爲(10+4+2)/10 = 1.6x.
以上erasurecode編碼技術無疑對存儲空間利用率帶來很大提升,但由於引入額外的編碼、解碼運算,對分佈式計算本身會造成一定程度的性能損失。由於當前的編碼技術還未從根本上解決降低性能損失,目前erasurecode還僅適用於對冷數據的離線處理階段。LRC編碼由於減少了網絡I/O傳輸的數據量,參與數據恢復運算的數據量也隨之減半,恢復過程的時間開銷減半,卻是以犧牲可靠性和空間利用率爲代價。如何從根本上降低erasurecode帶來的performanceoverhead,使得編碼存儲技術得以真正大量適用,將爲大數據存儲帶來不容質疑的重大意義。


TFS(Taobao File System) Erasure code實現方案

http://www.linuxlearn.net/news/new/99/7933/

TFS發展至今,集羣部署總容量已超過50PB,機器數量約2700臺。TFS在阿里內部主流部署方式是主集羣內數據塊2個副本,每個主集羣配置兩個備集羣,分別在同城和異地機房,實際上每份數據6個副本,存儲成本非常高,爲了降低TFS存儲成本,我們將Erasre code引入到TFS系統,本文將詳細介紹TFS應用Erasure code的技術方案。

異步編碼,對用戶透明

目前已經應用Erasure code的分佈式文件系統裏,HDFS、Windows Azure等系統採用異步編碼的方式,寫流程和數據編碼流程完全解耦;而GPFS、pangu(阿里雲的分佈式文件系統)等系統則是採用實時編碼的方式,在數據寫入時進行編碼。

TFS與GFS、HDFS等系統類似,以數據塊(block,通常爲64MB)爲單位管理存儲的數據。不同的是,HDFS等系統主要針對大文件存儲,一個文件包含多個數據塊,寫文件時通常是大塊數據的連續寫入,可以選擇在寫文件時對數據進行編碼;而TFS主要針對小文件存儲,多個小文件存儲到一個數據塊裏,寫文件時通常是是小塊數據的隨機寫入,導致TFS很難對寫入的文件進行實時編碼。

基於TFS的寫入特性,我們選擇類似HDFS-RAID的異步編碼方案,由nameserver(NS)在後臺控制編碼,以數據塊爲單位,每次選擇K個數據塊,編碼出M個校驗塊,這K+M個塊在TFS裏稱爲一個編組,編組的元信息持久化存儲在tair(阿里的開源KV存儲系統)裏,編組裏不超過M個塊的丟失(或失效),都能通過編組內任意K個正常的塊計算恢復回來。

enter image description here

如上圖所示K=4、M=2,D1-D4原來各有2個副本,總共2個副本,能容忍1個副本失效;在對數據塊D1-D4進行編碼後,生成P1、P2兩個校驗塊,編碼完成後D1-D4多餘的副本會被刪除掉,[D1、D2、D3、D4、P1、P2]構成一個編組,總共6個副本,能容忍2個副本失效(理論安全性更高);經過編組後,存儲成本下降了25%。

從存儲安全性以及空間利用率等因素考慮,編組選擇數據塊時必須滿足如下條件:

1. 機架安全,K+M的塊必須分佈在不同機架
2. 數據塊必須已經寫滿,避免空間浪費
3. 數據塊內刪除文件數低於一定比例(如5%),減少存儲空間的浪費
4. 數據塊超過一定時間沒被訪問過(如1個月),儘量只對冷數據進行編碼

TFS採用上述異步編碼方案,編組過程由服務器端控制,對用戶完全透明;用戶仍使用原來的API來讀寫文件,他們並不知道寫入的數據在服務器端會被進行編碼,這就使得我們在應用Erasure code時,並不需要應用升級程序來配合。

編碼方案可擴展

在編碼方案選擇上,HDFS、Windows Azure等都選擇了Reed Solomon(Azure後來使用LRC來優化數據恢復),TFS也選擇了Reed Solomon,並使用了開源的Jerasure庫;在容錯性上,TFS最初確定編組容忍2個塊失效,即編組內校驗塊的數量爲2(M=2);而在數據塊數量上,綜合存儲成本、編組恢復開銷、實時恢復性能等因素,將數據塊數量確定爲4(K=4)。

在工程實現時,我們將編碼方案、數據塊及校驗塊數量等都是可配置的,作爲編組元信息的一部分持久化存儲,這麼做使得後期都編碼方案做優化非常方便;在應用Erasure code過程中,我們可以隨時修改編碼方案、以及容錯參數等,一旦配置被修改,新產生的編組就會應用新的編碼方案。

編組及恢復流程

TFS在對數據塊進行Erasure code編碼時,最大的難題是對數據塊索引文件的處理;TFS的每個數據塊都對應一個索引文件,用於快速定位文件在數據塊內的位置,如下圖所示,索引文件大小在幾十KB左右。

enter image description here

最直觀的方法是對數據塊的索引也進行Erasure code編碼,將索引編碼生成的數據作爲校驗塊的索引存儲,如下圖所示

enter image description here

上述做法,雖然直觀簡單,但有個致命的問題,就是當編組內某個數據塊D1失效時,如果要訪問這個數據塊裏的某個文件(TFS裏稱爲退化讀),首先要讀取編組內K份索引文件數據,恢復出D1的索引,然後在D1的索引裏查找出文件在數據塊內的位置及大小信息(offset、size);再從編組裏選擇K個塊,讀取出每個塊[offset,offset + size]部分的數據,恢復出待讀取文件的數據,返回給客戶端。

從上述過程可以看出,即使退化讀一個很小的文件,也要讀取K份索引的完整數據,開銷非常大,使得退化讀的response time達到不可接受的地步。爲了減小退化讀時的開銷,我們的做法是不對索引文件進行編碼,而是以副本的機制存儲索引文件,如下圖所示,將每個數據塊的索引,都存儲一份副本到每個校驗塊的索引文件裏。

enter image description here

索引以副本機制存儲後,校驗塊索引佔的存儲空間變大K倍,但因爲索引文件很小,增加存儲開銷基本可以忽略;帶來的好處是,退化讀文件時,選擇任意一個校驗塊,就能從校驗塊的索引裏查找到文件在數據塊內的位置信息,接下來就可以選擇編組內任意K個塊來讀取需要的數據,恢復出待讀取的文件,返回給客戶端。

很顯然,通過將索引以副本的形式存儲起來後,退化讀的開銷小了很多,少了K次讀取索引文件的網絡及IO開銷、以及恢復索引的計算開銷。下圖黃色部分展示了當D1失效時,要讀取D1裏的某個文件時需要讀取的數據。(黃色的D1 index只會查詢到,並不會讀取整個索引文件)

enter image description here

當某個塊失效時,退化讀該塊內的文件時,TFS只會恢復被訪問文件的數據,儘快返回給客戶端,而不會在此時恢復整個塊的數據,因爲數據塊的恢復時間遠超出客戶端能接受的response time。

失效數據塊的恢復由NS在後臺控制完成,跟文件讀寫流程也是完全解耦的。以D1失效爲例,當NS檢測到D1失效後,如果等待一定時間(規避短時間內可恢復故障的影響)D1仍然處於失效狀態,NS會發起一個恢復D1的任務,具體流程如下:

1. 從D1所屬編組裏選擇一個Master DS(某個塊所在的dataserver),將編組信息發送該DS,讓其負責恢復D1的數據。
2. Master DS從編組裏任意選擇K個正常的塊,比如D2、D3、D4、P1,用於恢復D1的數據。
3. Master DS從D2、D3、D4、P1讀取數據,計算恢復出D1的數據。
4. Master DS從P1或P2讀取D1的索引,恢復D1的索引。
5. Master DS向NS彙報恢復D1完成。

NS選擇master DS時,會選擇編組裏某個狀態正常的塊所在的DS,保證至少一個塊的數據讀取會在本地完成,節省恢復時的網絡開銷。

文件更新的弱一致性

在引入Erasure code前,TFS支持文件更新,但不保證更新後的一致性,內部有部分應用能接受不一致的語義,使用了更新接口,但頻率不高,佔總共寫請求的0.5%不到。

在應用Erasure code後,對於沒有編組的數據塊,更新的流程保持不變;但對於已經編組的數據塊,如果修改了數據塊的數據,必須重新計算校驗塊響應部分的數據,並在校驗塊上進行更新,如下圖所示,這整個過程必須做成一個事務,要麼不做、要麼都做,否則如果出現部分成功的情況,會影響到其他塊的恢復。比如某次更新D1上的文件,D1上成功,P1也更新成功,但P2失敗,接下來如果D2失效,如果選中P1、P2來回復D2,則恢復出來肯定是錯誤的。

enter image description here

引入事務機制對於TFS來說成本過高,爲了解決上述問題,我們對已編組數據塊上的文件更新做特殊處理,使用跟索引文件一樣的處理方式,對更新的文件以多副本的形式進行存儲,方案如下圖所示。D1、D2、D3、D4、P1、P2構成一個編組,假設要更新D1上的某個文件,首先將文件數據追加到D1數據塊的末尾(圖中update的黃色部分),並更新D1的索引,同時在每個校驗塊的末尾追加更新的文件數據,並更新D1在各個校驗塊裏的索引信息。由於被更新過的文件特殊性,實際上在恢復失效塊時,對於塊內被更新過的文件,是直接從校驗塊上讀取恢復的。

enter image description here

這樣設計導致已編組的數據塊上更新的並文件不能享受Erasure code帶來的成本降低,但基於更新文件總量不大這一前提(實際上,我們一直在推動應用盡量不使用更新接口),加上已經編組的數據塊通常是很冷的數據,發生更新的可能性更小,所以總體影響不大。

未來工作

目前,TFS線上服務已經開啓了Erasure code功能,NS正逐步把滿足條件的數據塊進行編碼,生成校驗塊,同時刪除掉已編組數據塊的多餘副本,隨着編碼的不斷進行,集羣的存儲容量正在逐步下降。

接下來,我們會逐步對Erasure code的應用進行各項優化工作,主要包括:

1. 對編碼的性能進行優化,如使用更優的編碼算法、使用硬件加速編碼等。
2. 優化塊失效時的恢復時間,降低恢復時系統總體的網絡和磁盤的開銷。
3. 優化對冷數據的統計,儘可能讓Erasure code只應用在冷數據上,降低塊失效的影響。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章