1. 程式人生 > >Hadoop資料完整性與CheckSum校驗原理

Hadoop資料完整性與CheckSum校驗原理

一、HDFS資料完整性

使用者肯定都希望系統在儲存和處理資料時,資料不會有任何丟失或損壞。但是,受網路不穩定、硬體損壞等因素,IO操作過程中難免會出現資料丟失或髒資料,難免會出現資料丟失或髒資料,資料傳輸的量越大,出現錯誤的概率就越高。

檢測資料是否損壞的常見措施是,在資料第一次引入系統時計算校驗和(checksum)並存儲,在資料進行傳輸後再次計算校驗和進行對比,如果計算所得的新校驗和和原來的校驗和不匹配,就認為資料已損壞。但該技術並不能修復資料——它只能檢測出資料錯誤。(這正是不使用低端硬體的原因。具體說來,一定要使用ECC記憶體。)注意,校驗和也是可能損壞的,不只是資料,但由於校驗和比資料小得多,所以損壞的可能性非常小。

(1)對本地檔案I/O的檢查
在Hadoop中,本地檔案系統的資料完整性由客戶端負責。重點在於存車讀取檔案時進行校驗和的處理。
具體做法是:每當hadoop建立檔案a時,hadoop就會同時在同一個資料夾下建立隱藏檔案.a.crc,這個檔案記錄了 檔案a的校驗和。針對資料檔案的大小,每512個位元組會生成一個32位的校驗和(4位元組),可以在src/core/core-default.xml中通過修改io.bytes.per.checksum的大小來修改每個校驗和所針對的檔案的大小。

在hadoop中,校驗和系統單獨為一類,org.apache.hadoop.fs.ChecksumFileSystem,當需要校驗和機制時,可以很方便的呼叫它來服務。

(2)對HDFS的I/O資料進行檢查

一般來說,HDFS會在三種情況下檢驗校驗和:

  1. DataNode接收資料後儲存資料前
    DataNode接收資料一般有兩種情況:1.從客戶端上傳資料 2.DataNode從其他DataNode上接收資料。
    當客戶端上傳資料時,正在寫資料的客戶端將資料及其校驗和傳送到由一系列datanode組成的Pipeline管線。Pipeline管線中最後一個datanode負責驗證校驗和。

    DataNode資料儲存步驟:(包括從DataNode和客戶端兩種傳輸方式)
    1.在傳輸資料的最開始階段,Hadoop會簡單地檢查資料塊的完整性資訊;
    2.依次向各個DataNode傳輸資料,包括資料頭資訊、塊資訊、備份個數、校驗和等;
    3.Hadoop不會在資料每流動到一個DataNode都檢查校驗和,只會在資料流達到最後一個節點時才檢查校驗和
    如果在驗證過程中發現有不一致的塊,就會丟擲CheckSumException異常資訊

  2. 客戶端讀取DataNode上的資料時
    Hadoop會在客戶端讀取DataNode上的資料時,使用DFSClient中的read函式先將資料讀入到使用者的資料緩衝區,然後再檢查校驗和。將他們與datanode中儲存的校驗和進行比較
    每個datanode均持久儲存有一個用於驗證的校驗和日誌,所以它知道每個資料塊的最後一次驗證時間
    客戶端成功驗證一個數據塊後,會告訴這個datanode,datanode由此更新日誌

  3. DataNode後臺守護程序的定期檢查
    DataNode會在後臺執行DataBlockScanner,這個程式定期驗證儲存在這個datanode上的所有資料塊(3周)
    該項措施是解決物理儲存媒體上位衰減,位損壞的有力措施。

Hadoop處理損壞資料的機制:

  1. DataNode在讀取block塊的時候會先進行checksum(資料塊校驗和)
    如果client發現本次計算的校驗和跟建立時的校驗和不一致,則認為該block塊已損壞
  2. 客戶端在丟擲ChecksumException之前上報該block資訊給namenode進行標記(“已損壞”)
    這樣namenode就不會把客戶端指向這個block,也不會複製這個block到其他的datanode。
  3. client重新讀取另外的datanode上的block
  4. 在心跳返回時NameNode將塊的複製任務交給DataNode,從完好的block副本進行復制以達到預設的備份數3
  5. NameNode刪除掉壞的block。
  6. DataNode在一個block塊被建立之日起三週後開始進行校驗

如果出於一些原因在操作的時候不想讓hdfs檢查校驗碼

在FileSystem的open()之前通過設定FileSystem的setVerifyCheckSum(false)方法禁用校驗和
或者命令列使用get時候新增選項-ignoreCrc或者直接使用-copyToLocal
    fs.setVerifyChecksum(false)   fs.open(new Path(“”)) // 就不進行校驗檢查了
    Hadoop fs –get –ignoreCrc hdfs://master:9000/a.txt
    Hadoop fs –copyToLocal hdfs://master:9000/a.txt

二、CheckSum校驗原理

Hadoop資料的完整性檢測,都是通過校驗和的比較來完成,在建立新檔案時(也就是在上傳資料到hdfs上時)將校驗和的值和資料一起儲存起來。NameNode會收到來自client、DataNode的檢驗和資訊,根據這兩個資訊來維護檔案的塊儲存及向客戶端提供塊讀取服務。

HDFS會對寫入的所有資料計算校驗和,並在讀取資料時驗證校驗和。
常用的錯誤檢測碼是CRC-32(迴圈冗餘校驗),任何大小的資料輸入均計算得到一個32位的整數校驗和。
在寫入檔案時,hdfs為每個資料塊都生成一個crc檔案。客戶端讀取資料時生成一個crc與資料節點儲存的crc做比對,如果不匹配則說明資料已經損壞了。資料節點在後臺執行一個程式定期(預設為21天)檢測資料,防止物理儲存介質中位衰減而造成的資料損壞。

  1. DataNode在寫入時計算出校驗和,然後每次讀的時候再計算校驗和進行檢驗
    hdfs會為每一個固定長度的資料(一個個資料包)執行一次校驗和
    這個值由io.bytes.per.checksum指定,預設是512位元組。
    因為CRC32是32位即4個位元組,這樣校驗和佔用的空間就會少於原資料的1%。

  2. datanode在儲存收到的資料前會校驗資料的校驗和,比如收到客戶端的資料或者其他副本傳過來的資料。
    如hdfs資料流中客戶端寫入資料到hdfs時的資料流,在管道的最後一個datanode會去檢查這個校驗和
    如果發現錯誤,就會丟擲ChecksumException到客戶端

    從datanode讀資料的時候一樣要檢查校驗和,而且每個datanode還儲存了檢查校驗和的日誌,每次校驗都會記錄到日誌中

  3. 除了讀寫操作會檢查校驗和以外,datanode還跑著一個後臺程序(DataBlockScanner)
    定期校驗存在在它上面的block,因為除了讀寫過程中會產生資料錯誤以外,硬體本身也會產生資料錯誤,比如位衰減(bit rot)