近幾年儲存技術變化之快前所未有,行業正經歷翻天覆地的變化。與此同時,企業的數字化轉型以及使用者資料的暴漲也呼喚新的儲存形態出現。在這種背景下,軟體定義儲存得以快速普及,其中物件儲存作為新的儲存形態成為了海量儲存的首選。海量資料儲存業務中往往有大量的冷資料,這些資料同時對可靠性與成本提出了苛刻的要求,於是各家物件儲存服務商紛紛採用了糾刪碼技術來滿足這樣的要求。
白山一直以來致力於對資料儲存管理的極致追求,熱資料儲存需求促使我們不斷推進邊緣儲存的建設,冷資料儲存需求促使我們對糾刪碼技術的不斷改進。在 2016 年 6月,糾刪碼技術隨同白山雲端儲存一同釋出,開啟了白山EC1.0 時代。與此同時,邊緣儲存也開始發力,為諸多客戶的熱資料儲存提供堅實的基礎設施。
現在,全新設計的白山 EC2.0終於正式登場。在這篇文章中,我們將一同探索 EC2.0 的架構設計,EC 演算法與優化,以及 EC1.0 到 EC2.0 的美妙進化。
糾刪碼叢集架構設計
在白山新一代的糾刪碼儲存中, 我們將許久以來積累的改進, 創新, 沉澱成一行行程式碼, 部署到線上, 包括:
千億檔案的索引設計: 減少 99% 的後設資料壓力
白山的糾刪碼檔案索引分為兩級,第一級指向檔案所在的 block(磁碟上的物理檔案),第二級索引提供具體的 offset size 資訊。
檔案與磁碟空間的生命週期管理在遷移過程中我們使用了靈活可配的熱冷分層演算法,實現了 “位置” “時間” “順序” 三大維度的自主調優:
- 糾刪碼多機房冗餘,機房越多,冗餘係數越低
- 根據檔案建立時間來觸發冷資料遷移
- 基於檔名順序排列,壓縮海量後設資料
自適應檔案級別的冷熱分層
“命名”和”快取” 是計算機領域的兩個終極問題, 一個系統中快取的設計是一個永恆的話題: 如何通過確定的方法, 優化不確定的資料分佈問題. 這個問題的左邊是儲存成本控制, 右邊是讀寫效率的優化; 就像CPU的L1 cache是每個系統工程師必須關注的問題, 分散式儲存中的資料分層也漸漸成為一個成熟的儲存系統必須考慮的問題. 白山以此為重心, 重新思考了資料在分散式系統中的分佈策略, 將傳統上離散的分層策略, 進化成整合冷, 熱, 地域等資訊統一的資料編排演算法.
Silent Data Corruption 對資料的危害與防護
我們使用冗餘的辦法,如副本或糾刪碼來抵禦儲存系統的不穩定因素。然而單憑冗餘策略,不僅不能保障資料安全,可能還會面臨系統雪崩的風險。這類被大多數人忽視,或是不甚瞭解的潛在錯誤無時無刻不在威脅著我們的系統安全。 白山在設計伊始便對 Silent Data Corruption 進行了全面的分析。根據網路控制流,副本資料,糾刪碼資料,資料庫資料的不同特點做了針對性的防禦措施,全面高效的保障資料安全。
大幅度的降低儲存成本的同時提升可靠性
在 EC2.0 的演算法優化基礎上, 白山在同等冗餘度下再次極大提升了資料的修復速度和可靠性。 本篇就以此為核心, 和大家分享白山獨到的糾刪碼演算法的設計和實現.
EC 進化簡史
糾刪碼技術作為提高資料可靠性並減低 TCO 的手段,已成為雲端儲存的標準配置。但糾刪碼方案並不是完美的,其中最主要有以下兩點:
- 糾刪碼編碼引擎實現難度高,大部分公司選擇開源引擎而不是自研,缺乏對質量的把控。可能在使用有 bug 的程式碼而不自知。[1]
- 糾刪碼會倍數級別放大修復開銷,影響系統的穩定性和安全性。 因此,儘管要面對成本與研發精力的巨大投入,白山依然從始至終堅持糾刪碼技術的改進與研發工作。
EC1.0 的演算法設計主要針對上面提到的第二個問題,即修復開銷放大的問題。
EC1.0 相較於傳統的 EC 能減少 50% 的修復開銷。
但為此付出的代價就是會增加一定的冗餘成本。
那麼,我們能不能在成本和修復效能之間實現最佳平衡呢?
對於極致的追求,便是 EC2.0 誕生的搖籃。
RS Codes
糾刪碼中最典型的演算法就是裡德-所羅門碼 (Reed-Solomon Codes)。RS Codes 最早應用於通訊領域,經過數十年的發展,其在儲存系統中得到了廣泛應用,比如光碟中使用 RS Codes進行容錯,防止光碟上的劃痕導致資料不可讀;生活中,我們經常使用的二維碼也利用了 RS Codes 來提高識別成功率。
EC 的基本原理並不複雜,我們只需將原始資料切分成段,計算出比原始資料總量要少的冗餘,並能根據冗餘恢復原始資料,這樣我們就實現了儲存成本降低的目標。 原始資料分組
下面我們以 3+2 (原始資料切分為 3 份,計算 2 份冗餘)為例,展示 RS Codes 的編碼/修復過程。
首先,假設我們擁有一段隨機的原始資料: “0, 1, 211, 3, 77, 88”,我們將它切分成3 組向量(如上圖所示),組成 The Original Data Matrix(原始資料矩陣)。
資料編碼
接下來,我們需要生成一個 Encoding Matrix(編碼矩陣)。編碼矩陣的作用是在編碼過程中,與原始資料相乘,得到編碼後的資料。另外,我們還需要保證編碼矩陣的任意子矩陣可逆,這樣才能幫助我們恢復資料。通過將 The Original Data Matrix 與 The Encoding Matrix 相乘,得到 The Original Data Matrix 與 The Parity Data Matrix(冗餘資料矩陣)。類似這種編碼後,原始資料不變的編碼我們稱之為 Systematic Codes (系統碼),這也是實踐當中應用最廣泛的編碼型別。
修復損壞資料
由於矩陣中的行是線性無關的,當我們丟失了兩個資料塊,也就是刪除了矩陣中的兩行,是不影響等式成立的:
以上就是 RS Codes 基本工作原理的圖解,其修復步驟可以概括如下:1、求 Encoding Matrix 的逆矩陣 e'
2、e'*e = I
3、origina data matrix = e' * valid data matrix
第一次進化:LRC
在 k+m 的 RS Codes 中,修復任一資料塊均需要 k 個資料塊參與,修復放大係數為 k,修復代價高昂,甚至影響了系統的可靠性。在這種背景下,Locally Reconstruction Codes (LRC) 應運而生。
這裡以 6+2+2 為例,看 LRC 是如何工作的:
計算冗餘塊的步驟如下:當LRC中有一個資料損壞時, 恢復開銷僅僅為 50%
在丟失任一原始資料塊的情況下,都能通過 3 個資料塊來進行異或運算來進行修復: 使用 Px 或 Py 進行修復, 而不是原先的需要 6 個資料塊進行 RS 解碼. 而在多數情況下(約95%), 系統內都只需要修復一個資料塊丟失的問題; 因為兩個資料塊同時損壞的概率是單磁碟故障率的平方.
但這樣做,並不滿足 MDS 性質(最大距離可分 Maximum Distance 碼是一種最優容錯編碼方法,即 n= k+m 編碼後的最大可容忍任意m 份資料失效,原始資料也不會丟失。RS Codes 就是 MDS 碼。)。 因此可靠性不如相同冗餘度的 RS Codes
再次進化:EC1.0
在 EC1.0 中: 因此, P0 可以不用實際落盤。相較於傳統的 LRC, Baishan LRC 減少了儲存的冗餘度。高階進化:EC2.0
演算法性質
經過上面的研究與沉澱,我們試圖找到一種更加平衡的演算法,新演算法具備如下性質:
- 滿足 MDS 性質
- 相較於 RS Codes 能減少修復 I/O 開銷
- 支援 SSSE3 AVX2 AVX512 等多種擴充套件指令集
- API 豐富易用
- 程式碼簡潔清晰
由於開源的 RS Codes 引擎 Intel ISA-L 曾導致 OpenStack Swift 出現資料不可修復的 bug[1],在研究之後[3],我們選擇完全自主研發。
極限效能
首先,為了實現高效能引擎(滿足目標 3),我們必須掌握加速有限域運算的技術。 對於任意 1 位元組來說,在 GF(2^8) 內有 256 種可能的值,所以每一個元素對應的乘法表大小為 256 位元組,每次查表僅可以進行一個位元組資料的乘法運算,效率很低:
在論文 《Screaming Fast Galois Field Arithmetic Using Intel SIMD Instructions>》中介紹了將乘法表放入 XMM 暫存器的方法,其中用兩個等式可以概括其精髓:
受限於篇幅,我們將在後續文章展開講解效能優化細節與技巧。有興趣的讀者可以看我們開源的 RS Codes 編碼引擎[4]。這份開原始碼中,我們在保持其高效能的同時(與 Intel ISA-L 相媲美),加強了對程式碼可讀性的提升。需要注意的是:為了支援 AVX512 並使得彙編程式碼使用指令而不是位元組序列,要求 Go 的版本大於等於 1.11 注:- 執行平臺: AWS c5d.large
- 結果 = 10 * 資料分塊尺寸 / 消耗時間
- 數值越大表明效能越好
最終形態
為了取得冗餘成本與修復代價之間的平衡,我們翻閱了許多學術論文。
其中 Beehive 是我們最終考察的編碼方案之一[5]。Beehive 能保證丟失一個甚至多個資料塊的情況下只需要更少的資料來重建丟失塊。論文中給瞭如下例子:
由上圖,我們不難發現 Beehive 顯著減少了修復開銷。但 Beehive 並沒有完全滿足我們對於空間的追求。其儲存效率要低於 RS Codes,因此,Beehive 被我們暫時排除掉了。 在經過更多的學習與研究後,我們得出了一個關於減少修復頻寬編碼系統的基本結論: 要將冗餘資訊蘊含在計算過程當中,通過特定步驟在臨時資訊中找到線索以求減少修復開銷。 根據這個指導思想,我們重新閱讀了論文 《Rethinking Erasure Codes for Cloud File Systems: Minimizing I/O for Recovery and Degraded Reads》。 在 Rotated Reed-Solomon Codes 這一章節中,我們可以發現一種較為簡單的對原始資料切割的演算法,論文中的例子如下:
以這個演算法為基礎,我們對原始資料切割整合,隨後將資訊合併到冗餘塊中。通過這樣的操作,在丟失資料塊的情況下,我們對資料的依賴由 k+m 中的 k 轉為了部分需要 k 部分需要其它整合資料,只要保證剩餘資料所需的組合資料少於 k 份,就可以實現減少修復開銷的目的。
華山論劍
儲存開銷PK
可以明顯發現, EC2.0 具有和 RS 一致的冗餘開銷,在 EC1.0 的基礎之上進一步減少了冗餘成本。修復開銷PK
LRC 與 EC1.0 的修復開銷最小僅為 3, RS 最大為 6,EC2.0 為 4.2效能PK
注: 執行平臺: AWS c5d.large 編碼 & 修復一塊原始資料 (資料在記憶體中) 注:
- 6+3 (4MB 每個資料塊)
- 結果 = 消耗時間 (單位 ms)
- 橫座標(時間)越短效能越好
修復一塊原始資料 (資料在磁碟中) 注:
- 9+4 (360MB 每個資料塊)
- 結果 = 消耗時間 (單位 ms)
結束語
分散式儲存並不是一個新鮮的技術,似乎很難發掘出新東西。但我們相信,如果有耐心,有足夠的工程能力和實踐經驗去做支撐,我們依然可以一小步一小步的去開拓。新一代的糾刪碼只是白山的一個階段性成果,目前,更先進的糾刪碼引擎的開發已在進行中。我們希望能繼續創新,繼續為大家帶來驚喜。
感興趣的朋友,可以掃描下方二維碼,加入“白山雲端儲存技術交流群”,一起碰撞,一起進步。
附錄
- Swift Data Corruption: openstack.nimeyo.com/114966/open…
- Baishan LRC: github.com/baishanclou…
- Vandermonde Matrix: drmingdrmer.github.io/tech/distri…
- Reed-Solomon Codes: github.com/templexxx/r…
- Beehive: Erasure Codes for Fixing Multiple Failures in Distributed Storage Systems
白山簡介
白山雲科技有限公司(簡稱“白山”)是中國首家雲鏈服務提供商,為客戶提供高效資料內容應用與交換的定製化服務。
白山率先在國內引入雲鏈服務(CCX),包括雲分發、雲端儲存、雲聚合。其核心是建立資料的連線,基於客戶對資料內容的高速傳輸、冷熱儲存、應用整合需求,為資料的傳輸、儲存、消費和治理提供全生命週期服務。
自2015年4月成立以來,白山以雲分發為切入點,在雲服務市場上迅速崛起,首款雲分發產品CDN-X引領行業創新。2016年6月,白山釋出雲端儲存CWN-X,作為雲鏈第二款產品,其分級式物件儲存,專注於熱資料的儲存及儲存間的資料轉移,廣受市場好評。 2017年5月,白山推出雲聚合CLN-X,搶先佈局雲後市場,與CDN-X、CWN-X共同構成雲鏈服務體系,助力經濟數字化轉型。
2016年3月,白山美國公司成立,以此為戰略支點,輻射全球市場。目前,白山服務於微軟、央視、小米、美團、中船重工、國美金融等四百餘家行業領先客戶。