上一篇文章《談談網絡通訊中的 ACK、NACK 和 REX》簡單介紹了網絡通訊中的丟包重傳的相關理論和方法,本文則準備介紹下對抗網絡丟包的另外一種常見的手段 FEC 所涉及到的核心基礎知識。微信
名詞解釋網絡
FEC:Forward Error Correction,前向糾錯app
FEC 是一種經過在網絡傳輸中增長數據包的冗餘信息,使得接收端可以在網絡發生丟包後利用這些冗餘信息直接恢復出丟失的數據包的一種方法。ide
FEC 的基礎理論:異或ui
異或的規則編碼
兩個值不相等則爲 1,相等則爲 0;雲計算
0 ^ 0 = 0 1 ^ 1 = 0 0 ^ 1 = 1 1 ^ 0 = 1
注:按位異或 ^,則是把兩個數轉換爲二進制,按位進行異或運算。spa
異或的特性code
恆等律:X ^ 0 = X 歸零律:X ^ X = 0 交換律:A ^ B = B ^ A 結合律:A ^ (B ^ C) = (A ^ B) ^ C
注:能夠經過數學方法推導證實,咱們這裏只須要記住這些規則便可,後面有大量的應用。對象
XOR 的應用案例
有了這些 XOR 的基礎理論,咱們看看它是怎麼應用到實際中的 「校驗」 和 「糾錯」 的。
奇偶校驗(Parity Check)
判斷一個二進制數中 1 的數量是奇數仍是偶數(應用了異或的 恆等律 和 歸零律):
// 例如:求 10100001 中 1 的數量是奇數仍是偶數 // 結果爲 1 就是奇數個 1,結果爲 0 就是偶數個 1 1 ^ 0 ^ 1 ^ 0 ^ 0 ^ 0 ^ 0 ^ 1 = 1
這條性質可用於奇偶校驗(Parity Check),每一個字節的數據都計算一個校驗位,數據和校驗位一塊兒發送出去,這樣接收方能夠根據校驗位粗略地判斷接收到的數據是否有誤。
磁盤陣列-RAID5
使用 3 塊磁盤(A、B、C)組成RAID5 陣列來存儲用戶的數據,把每份數據切分爲 A、B 兩部分,而後把 A xor B 的結果做爲 C ,分別寫入 A、B、C 三塊磁盤。最終,任意一塊磁盤出錯,都是能夠經過另外兩塊磁盤的數據進行恢復的。
實現原理:應用了異或的 恆等律 和 結合律
c = a ^ b a = a ^ (b ^ b) = (a ^ b) ^ b = c ^ b b = (a ^ a) ^ b = a ^ c
基於 XOR 的 FEC
假設網絡通訊有 N 個 packet 須要發送,那麼,能夠相似上述 RAID5 的策略,每 2 個 packet 生成一個 FEC packet,這樣,連續的 3 個 packet 的任意一個 packet 丟失,都能經過另外 2 個恢復出來的。
但考慮到每 2 個 packet 就產生 1 個 fec packet,冗餘度可能有點高(比較浪費帶寬),咱們可否每 3 個或者每 N 個 packet 再產生一個 fec packet 呢?固然能夠,咱們以每 3 個 packet(A、B、C) 產生 1 個 fec packet(D)爲例來推導一下:
d = a ^ b ^ c a = a ^ (b ^ b) ^ (c ^ c) = (b ^ c) ^ (a ^ b ^ c) = b ^ c ^ d b = (a ^ a) ^ b ^ (c ^ c) = (a ^ c) ^ (a ^ b ^ c) = a ^ c ^ d c = (a ^ a) ^ (b ^ b) ^ c = (a ^ b) ^ (a ^ b ^ c) = a ^ b ^ d
由上述公式推導便可知道,這 4 個 packet,任意丟失 1 個 packet,都可以由其餘 3 個 packet 恢復出來。
對象存儲-EC糾刪碼
一些互聯網雲計算公司提供的對象存儲服務,都會宣稱本身具備極高的數據可靠性,使用瞭如三副本技術、EC 糾刪碼技術等等,後者大體方案如圖所示:
圖中採用的是 8+4 的糾刪碼策略(即:原始數據切割爲 8 份,計算出 4 份冗餘信息),將這 12 份分別存儲在 不一樣機櫃的 12 臺不一樣節點上,即便同一時刻出現多臺節點(至多 4 臺)損壞或不可訪問,只要有很多於 8 個節點可用,數據便可恢復。
不知道你們看出來點什麼沒有?相比於上面基於 N 個 packet 產生 1 個 FEC packet 的方案,這種 K + M 的糾刪碼策略具備更好的扛丟失能力,總結下來就是:
經過 K個有效數據,產生 M 個 FEC 冗餘包,這 K + M 個數據,任意丟失 M 個數據,都能把 K 個有效數據恢復出來。
其實這種方案,最先也是應用於網絡傳輸領域的,只不過被借用到存儲領域來提升磁盤的利用率。要實現這種 K + M 的 FEC 策略,使用簡單的 XOR 異或來推導比較難,須要藉助矩陣相關的計算,實現方案有不少種,下面簡單介紹下最著名和經常使用的 Reed-solomon codes。
Reed-Solomon Codes
裏德-所羅門碼(Reed-solomon codes,簡稱 RS codes),利用該原理實現的 FEC 策略,一般也叫作 RS-FEC。網上關於它的介紹特別多,本文就不詳細展開了,僅簡單以示意圖的形式給出大體的原理:
RS codes 編碼過程
大體原理以下:假設有效數據有 K 個,指望生成 M 個 FEC 數據
1. 把 K 個有效數據組成一個單位向量 D
2. 生成一個變換矩陣 B:由一個 K 階的單位矩陣 和一個 K * M 的範德蒙特 矩陣(Vandemode)組成
3. 兩個矩陣相乘獲得的矩陣 G,即包含了 M 個冗餘的 FEC 數據
RS codes 解碼過程
假設數據 D1,D4,C2 丟失了,則取對應行的範德蒙矩陣的逆 * 沒有丟失的數據矩陣,則能夠恢復出原始的數據矩陣。
大體原理以下:假設數據 D1,D4,C2 丟失了
1. 對矩陣 B 和 D,分別取沒有丟失的行構成 B‘ 和 G’
2. 根據以下公式,便可計算恢復出有效數據向量 D
B' x D = G' ->>> D = B' 的逆 x G'
參考文章
小結
關於網絡通訊中 FEC 的基礎知識點就分享到這裏了,若有疑問的小夥伴歡迎來信 lujun.hust@gmail.com 交流。另外,也歡迎你們關注個人新浪微博 @盧_俊 或者 微信公衆號 @Jhuster 獲取最新的文章和資訊。