分散式系統下的糾刪碼技術之Erasure Code
Erasure Code(簡稱EC,也稱擦除碼或糾刪碼)是1組資料冗餘和恢復演算法的統稱。本教程以Vandermonde矩陣的Reed-Solomon來解釋EC原理。
術語定義:
- dj-資料塊;
- yi-通過資料塊計算得來,作為資料冗餘的校驗塊;
- uj-丟失的、需要恢復的資料塊;
- k-資料塊數量;
- m-校驗塊數量。
本教程包括:
- 分散式系統的可靠性問題: 冗餘與多副本——提出EC需要解決的問題;
- EC的基本原理——用到中學數學知識, 舉“栗子”的方式直觀解釋EC演算法,希望對分散式儲存領域增加了解的同學,可只閱讀該部分;
- EC編碼矩陣的幾何解釋——解釋EC編碼矩陣的原理和含義,希望深入瞭解EC數學原理的讀者, 可從此部分開始;
- EC解碼過程: 求解n元一次方程組;
- 新世界: 伽羅華域 [Galois-Field] GF(7)
- EC使用的新世界 [Galois-Field] GF(256)
(以上兩節介紹EC在計算機上的應用方法) - 實現——對工程實踐方面感興趣的同學可參考;
- 分析——需要規劃儲存策略的架構師可參考。
本文將對1-4章節進行介紹,5-8章節將在白山微信公眾號(baishancloud)持續推送。
分散式系統的可靠性問題: 冗餘與多副本
在分散式系統中,可靠性問題是首要問題。2000多年前古埃及人在羅塞塔石碑上重複三次記錄同一資訊,為後世破譯托勒密五世登基詔書提供了高可靠性;同樣,伺服器宕機、光纖挖斷、洪水淹沒機房也會發生,資料要達到工業可用的可靠性需要對資料進行多副本儲存,且多個副本應分佈在不同伺服器、機架、機房才能真正實現高可靠。
副本數一般為3:
3副本結合當前經驗磁碟損壞率(年損壞率7%),大約可達到11個9以上的工業可接受的可靠性。
例如:有2塊資料d1和d2,為了達到高可靠性,需每個資料複製3份,並存放在不同伺服器以保證足夠分散。儲存位置如下:
(d1 ,d1 ,d1 )
(d2,d2,d2)
...
第n列的d1,d2儲存在第n個伺服器上(n=1,2,3)
在3副本策略下, 總儲存冗餘度為300%;空間浪費為200%
有時為降低成本, 只儲存2副本, 此時冗餘度為200%,浪費1倍空間。
能否用較少冗餘,實現同樣較高的可靠性,成為分散式儲存一個重要研發方向。這就是本文介紹的EC需要解決的問題。
EC的基本原理
例子1: 實現k+1的冗餘策略(大概需要小學3年級的數學知識)
Q:有3個自然數,能否通過記錄第4個數字,使任意一個數字丟失時都可被找回?
很簡單,只需記錄這3個數字的和。
假設3個數字是:d1,d2,d3
再儲存一個數:y1=d1+d2+d3
儲存過程:儲存這4個數字:d1,d2,d3,y1
資料丟失找回時:
如果 d1,d2,d3 中任意一個丟失, 如 d1丟失, 可通過 d1=y1−d2−d3 找回;
如果 y1丟失,可通過 y1=d1+d2+d3找回;
在上述簡單的系統中,共儲存4份資料,有效資料3份、冗餘133%;可靠性與2副本儲存策相近:最多允許丟失1份資料;
可靠性目前還只是差不多,並不完全一樣,“第八節:分析”中將詳細討論可靠性的計算。討論可靠性時,一般資料丟失風險沒有量級差異, 就可認為是較為接近的。
上述例子原理與RAID-5基本相同。RAID-5對k個(一般11個左右)資料塊求1份校驗和的資料塊並存儲,允許1塊(資料塊或校驗塊)丟失後可找回。(當然在工程上,RAID-5的計算與自然數求和略有差異,後面將繼續說明。)
以上這種求和冗餘策略,就是EC的核心思路。
後續章節將繼續深入,逐步把上述求和冗餘推廣成生產環境下可用的儲存策略,同時也會逐步引入更多數學知識來完善。
例子2: 實現k+m的冗餘策略
(1)再增加1個校驗塊,變成k+2
栗子1中,我們通過增加1份冗餘,實現了與2副本相近的可靠性(允許丟失1塊資料)。那與3副本差不多的可靠性如何實現呢(允許丟失2塊資料)?
Q:有3塊資料:d1,d2,d3,可否再儲存2個冗餘的校驗塊(共5塊),使整個系統丟失任意2份資料時都能找回?
k+1求和策略,實際是給所有資料塊和校驗塊建立方程d1+d2+d3=y1, 來描述整體關係。
現在,如果增加可丟失的資料塊數,簡單將y1儲存2次並不夠。
假設計算2個校驗塊:
d1+d2+d3=y1
d1+d2+d3=y2
(y1=y2)
儲存過程:儲存 d1,d2,d3,y1,y2
恢復資料:如果 d1,d2 都丟失(用u1,u2表示),下面關於u1,u2的線性方程有無窮多解:
u1+u2+d3=y1
u1+u2+d3=y2
所以需要設計計算第2個校驗塊y2的方法,使d1,d2丟失時方程組有解。
相對簡單直接的思路是:計算y2時,為每個資料dj增加1個不同的係數,如:
計算y1時,對每個數字乘以1, 1, 1, 1 …
計算y2時,對每個數字乘以1, 2, 4, 8 …
d1+d2+d3=y1
d1+2d2+4d3=y2
儲存過程:儲存 d1,d2,d3,y1,y2
資料恢復:如果d1,d2丟失(用 u1,u2表示),可使用d3,y1,y2建立關於u1,u2的二元一次方程組:
u1+u2=y1−d3
u1+2u=y2−4d3
這種新增係數計算校驗塊的方式,就是RAID-6的基本工作方式:
RAID-6在k個數據塊之外再多儲存2個校驗資料,當系統丟失2塊資料時,就可以找回丟失資料。
k+2冗餘策略通過166%的冗餘,實現了與三副本300%冗餘幾乎相同的可靠性。(具體可靠性計算參見“第8節:分析”。)
(2)實現k+m 的冗餘
要實現與4副本差不多的可靠性,我們需要更多冗餘(再增加一個校驗塊y3):
y3的計算需要再為所有dj選擇1組不同的係數,如1,3,9,27…保證資料丟失時,得到的三元一次方程組可解:
d1+d2+d3=y1
d1+2d2+4d3=y2
d1+3d2+9d3=y2
通過不斷增加不同係數,可實現任意k+m的EC冗餘儲存策略。
以上是有理數下EC演算法介紹,接下來將討論係數選擇的依據。
EC是更具通用性的演算法,RAID-5和RAID-6都是EC的子集,因實現成本(主要為計算的開銷)較高,RAID-5和RAID-6在單機的可靠性實現中佔主流地位。
但隨著儲存量不斷增大,百PB級儲存已不能稱之為很極端的場景了。RAID-6資料丟失的風險在大資料量級的場景中越來越明顯,於是在雲端儲存(大規模儲存)領域,能支援更多冗餘校驗塊的EC成為主流。
EC編碼矩陣的幾何解釋
EC 可這樣理解:為恢復丟失的資料,需預先計算出幾個數值(校驗塊),校驗塊和資料塊構成1個整體,並具備所有資料塊的特徵,可配合其他資料找回丟失的資料塊。
(1)k=2,為2個數據塊生成冗餘校驗塊
假設有2個數據塊 d1,d2,需要計算2個校驗塊y1,y2,。
我們可通過1個直線方程,實現資料的冗餘備份和恢復:
y=d1+d2x
這條直線包含所有資料塊dj的資訊:
任何一組 d1,d2的值確定唯一一條直線;任意一條直線也對應唯一一組d1,d2。
資料可靠性問題轉化成:儲存足夠多直線資訊,需要時找回這條直線,然後再提取直線方程的係數來找回最初儲存的資料塊 d1,d2。
而儲存足夠多的資訊,最直接的方法是記錄這條直線上幾個點的座標。兩點確定一條直線,只要拿到直線上2個點的座標,就能確定直線方程,從而確定係數d1,d2。
按照這樣的思路,我們重新用直線方程描述資料冗餘生成和資料恢復的過程:
- 生成冗餘:在直線上取2個點, 記錄點的座標。(取x=[1, 2, 3…],則只需記錄y的值);
- 恢復資料:通過已知過直線的2點確定直線方程。
d1,d2,y1,y2,這4個數據中,任意丟失2個,都可以通過等式關係 y=d1+d2⋅x恢復。
丟失1個數據塊時可只用 y1的方程;
丟失2個數據塊時需解二元一次方程組;
若y1或 y2丟失, 則通過重新取點的方式恢復。
我們可以在直線上取任意多個點,但恢復時最多隻需要2個。這個例子實現了2+m的冗餘策略。
(2)k=3, 4, 5…時資料塊的冗餘
直線方程只需2個值確定,但如果用描點方式為更多資料塊生成冗餘資料,則需要使用高次的曲線,記錄更多資料。
例如:二次曲線拋物線 y=ax2+bx+c需要3個值確定,同時也需要拋物線上3個點的座標找回這條拋物線。
- 通過高次曲線生成冗餘資料
如果有k個數據塊,可將k個數據作為係數,定義1條關於x的高次曲線:
生成m個冗餘資料:
取m個不同的x值(1, 2, 3…m),記錄這條曲線上m個不同點的座標:(1,y1),(2,y2)…(m,ym);儲存所有資料塊d1,d2…dk和所有校驗塊y1,y2…ym。
恢復資料:
當資料丟失時,平面直角座標系上m個點可唯一確定1條m-1次冪的關於x的曲線。確定這條曲線,就能找回它的係數,即資料塊d1,d2…dk。
以上就是EC演算法的幾何解釋:通過曲線上的點確定曲線的過程。
- 從曲線方程得到係數矩陣
在曲線上取點的過程中,可直接為x取自然數(1, 2, 3…)來計算y的值;
y1=d1+d2⋅1+d3⋅12+..+dk⋅1k−1
y2=d1+d2⋅2+d3⋅22+..+dk⋅2k−1
y3=d1+d2⋅3+d3⋅32+..+dk⋅3k−1...
把上面等式寫成矩陣的形式,可得到EC校驗塊的生成矩陣Generator-Matrix:
y1,y2…ym為校驗塊的資料,矩陣中為係數。
這就是著名的Vandermonde 矩陣。
Vandermonde矩陣只是EC中一種係數的選擇方式,其他常用的係數矩陣還有 Cauchy 矩陣等。
EC解碼過程:求解n元一次方程組
現在我們知道,EC 就是:
有1組數字: d1,d2,d3…dk,另外記錄m個校驗用的數字y1,y2,y3…ym,使這k+m個數字中任意丟失m個,都能從剩下的k箇中恢復所有k+m個數字。
EC生成校驗塊的過程稱之為EC編碼,當資料丟失需要找回時,使用EC解碼過程。
如上面章節所說,EC編碼過程是編碼矩陣(Vandermonde)和資料塊列相乘:
解碼過程如下:
假設有q(q≤m)個數字丟失,在上述編碼矩陣中選擇 y1,y2..yq,組成的一次方程組,求解丟失的資料。
例如:d2,d3丟失(u2,u3表示), 因為只丟失2塊資料,只需2個校驗塊來恢復資料:
該矩陣表示的方程組有2個未知數u2,u3,解方程即可得到這2塊丟失的資料。
- Vandermonde 矩陣保證方程組有解
對於k+m的EC來說,任意丟失m個數據塊都可將其找回。
Vandermonde矩陣保證了任意m行m列組成的子矩陣都是線性無關的,構成的方程有確定解。
Vandermonde的行列式的值為:
只要αi都不同,則 Vandermonde 矩陣的行列式就不為0,矩陣可逆,方程有唯一解。
容易證明,Vandermonde矩陣任意m×m的子矩陣可保證永遠有唯一解。
以上我們討論了EC在有理數範圍內全部內容,但尚不能直接應用於計算機的程式碼開發商。
作者:張炎潑,白山雲合夥人兼研發副總裁,曾就職於新浪、美團雲等。目前主要負責白山雲科技物件儲存研發、資料跨機房分佈和修復問題解決等工作。以實現100PB級資料儲存為目標,其帶領團隊完成全網分佈儲存系統的設計、實現與部署工作,將資料“冷”“熱”分離,使冷資料成本壓縮至1.2倍冗餘度。