hadoop深入研究——HDFS數據完整性

本文轉自https://blog.csdn.net/lastsweetop/article/details/9159067

數據完整性

IO操作過程中難免會出現數據丟失或髒數據,數據傳輸得量越大出錯得機率越高。校驗錯誤最常用得辦法就是傳輸前計算一個校驗和,傳輸後計算一個校驗和,兩個校驗和如果不相同就說明數據存在錯誤,比較常用得錯誤校驗碼是CRC32.

hdfs數據完整性

hdfs寫入的時候計算出校驗和,然後每次讀的時候再計算校驗和。要注意的一點是,hdfs每固定長度就會計算一次校驗和,這個值由io.bytes.per.checksum指定,默認是512字節。因爲CRC32是32位即4個字節,這樣校驗和佔用的空間就會少於原數據的1%。1%這個數字在hadoop中會經常看到。以後有時間會整理一份hadoop和1%不得不說的故事。
datanode在存儲收到的數據前會校驗數據的校驗和,比如收到客戶端的數據或者其他副本傳過來的數據。想一下前面的文章hadoop深入研究:(三)——hdfs數據流中客戶端寫入數據到hdfs時的數據流,在管道的最後一個datanode會去檢查這個校驗和,如果發現錯誤,就會拋出ChecksumException到客戶端。
客戶端從datanode讀數據的時候一樣要檢查校驗和,而且每個datanode還保存了檢查校驗和的日誌,客戶端的每一次校驗都會記錄到日誌中。
除了讀寫操作會檢查校驗和以外,datanode還跑着一個後臺進程(DataBlockScanner)來定期校驗存在在它上面的block,因爲除了讀寫過程中會產生數據錯誤以外,硬件本身也會產生數據錯誤,比如說位衰減(bit rot)。
如果客戶端發現有block壞掉呢,會怎麼恢復這個壞的塊,主要分幾步:
1.客戶端在拋出ChecksumException之前會把壞的block和block所在的datanode報告給namenode
2.namenode把這個block標記爲已損壞,這樣namenode就不會把客戶端指向這個block,也不會複製這個block到其他的datanode。
3.namenode會把一個好的block複製到另外一個datanode
4.namenode把壞的block刪除掉
如果出於一些原因在操作的時候不想讓hdfs檢查校驗碼,在調用FileSystem的open方法前調用setVerityCheckSum方法,並設爲爲false即可,命令行下可以使用-ignoreCrc參數。

實現

LocalFileSystem繼承自ChecksumFileSystem,已經實現了checksum功能,checksum的信息存儲在與文件名同名的crc文件中,發現錯誤的文件放在bad_files文件夾中。如果你確認頂層系統已經實現了checksum功能,那麼你就沒必要使用LocalFileSystem,改爲用RowLocalFileSystem。可以通過更改fs.file.impl=org.apache.hadoop.fs.RawLoacalFileSystem全局指定,也可以通過代碼直接實例化。
[java] view plain copy
  1. Configuration conf=...  
  2.        FileSystem fs=new RawLocalFileSystem();  
  3.        fs.initialize(null, conf);  
如果其他的FileSystem想擁有checksum功能的話,只需要用ChecksumFileSystem包裝一層即可:
[java] view plain copy
  1. FileSystem rawFs=...  
  2.         FileSystem checksummedFs=new ChecksumFileSystem(fs){} ;  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章