大資料學習筆記(四)

xxiaoMinGLL發表於2018-01-27

一、HDFS校驗和

使用者希望在儲存和處理資料的時候,不會有任何損失或損壞,HDFS提供兩種校驗:1.校驗和 2.執行後臺程式來檢測資料塊

校驗和
寫入資料節點驗證
讀取資料節點驗證
恢復資料
Localfilesystem類
ChecksumfileSystem類

1.寫入資料節點驗證
Hdfs會對寫入的所有資料計算校驗和,並在讀取資料時驗證校驗和。
後設資料節點負責在驗證收到的資料後,儲存資料及其校驗和。在收到客戶端資料或複製其他datanode的資料時執行。
正在寫資料的客戶端將資料及其校驗和傳送到一系列資料節點組成的管線,管線的最後一個資料節點負責驗證校驗和。

2.讀取資料節點驗證
客戶端讀取資料節點資料也會驗證校驗和,將它們與資料節點中儲存的校驗和進行比較。

每個資料節點都持久化一個用於驗證的校驗和日誌。
客戶端成功驗證一個資料塊後,會告訴這個資料節點,資料節點由此更新日誌。

3.恢復資料
由於hdfs儲存著每個資料塊的備份,它可以通過複製完好的資料備份來修復損壞的資料塊來恢復資料。

4.Localfilesystem類
Hadoop的LocalFileSystem類是用來執行客戶端的校驗和驗證。當寫入一個名為filename的檔案時檔案系統客戶端會在包含檔案塊校驗和的同一目錄內建立一個名為Filename.crc的隱藏檔案。

5.ChecksumfileSystem類
LocalFileSystem類通過ChecksumFileSystem類來完成自己的任務
FileSystem rawFs;
FileSystem checksummedFs=new ChecksumFileSystem(rawFS);
可以通過CheckFileSystem的getRawFileSystem()方法獲取原始檔系統。
當檢測到錯誤,CheckFileSystem類會呼叫reportCheckSumFailure()方法報告錯誤,然後LocalFileSystem將這個出錯的檔案和校驗和移到名為bad_files的資料夾內,管理員可以定期檢查這個資料夾。

二、檔案結構

HDFS和MR主要針對大資料檔案來設計,在小檔案處理上效率低.解決方法是選擇一個容器,將這些小檔案包裝起來,將整個檔案作為一條記錄,可以獲取更高效率的儲存和處理,避免多次開啟關閉流耗費計算資源.hdfs提供了兩種型別的容器 SequenceFile和MapFile

小檔案問題解決方案
在原有HDFS基礎上新增一個小檔案處理模組,具體操作流程如下:
當使用者上傳檔案時,判斷該檔案是否屬於小檔案,如果是,則交給小檔案處理模組處理,否則,交給通用檔案處理模組處理。在小檔案模組中開啟一定時任務,其主要功能是當模組中檔案總size大於HDFS上block大小的檔案時,則通過SequenceFile元件以檔名做key,相應的檔案內容為value將這些小檔案一次性寫入hdfs模組。
同時刪除已處理的檔案,並將結果寫入資料庫。
當使用者進行讀取操作時,可根據資料庫中的結果標誌來讀取檔案。

Sequence file由一系列的二進位制key/value組成,如果key為小檔名,value為檔案內容,則可以將大批小檔案合併成一個大檔案。Hadoop-0.21.0版本開始中提供了SequenceFile,包括Writer,Reader和SequenceFileSorter類進行寫,讀和排序操作。該方案對於小檔案的存取都比較自由,不限制使用者和檔案的多少,支援Append追加寫入,支援三級文件壓縮(不壓縮、檔案級、塊級別)。其儲存結構如下圖所示:


SequenceFile儲存
檔案中每條記錄是可序列化,可持久化的鍵值對,提供相應的讀寫器和排序器,寫操作根據壓縮的型別分為3種
Write 無壓縮寫資料
RecordCompressWriter記錄級壓縮檔案,只壓縮值
BlockCompressWrite塊級壓縮檔案,鍵值採用獨立壓縮方式

在儲存結構上,sequenceFile主要由一個Header後跟多條Record組成,如圖

前三個位元組是一個Bytes SEQ代表著版本號,同時header也包括key的名稱,value class , 壓縮細節,metadata,以及Sync markers。Sync markers的作用在於可以讀取任意位置的資料。
 在recourds中,又分為是否壓縮格式。當沒有被壓縮時,key與value使用Serialization序列化寫入SequenceFile。當選擇壓縮格式時,record的壓縮格式與沒有壓縮其實不盡相同,除了value的bytes被壓縮,key是不被壓縮的。

當儲存的記錄很多時候,可以把一串記錄組織到一起同一壓縮成一塊。
  在Block中,它使所有的資訊進行壓縮,壓縮的最小大小由配置檔案中,io.seqfile.compress.blocksize配置項決定。


一個MapFile可以通過SequenceFile的地址,進行分類查詢的格式。使用這個格式的優點在於,首先會將SequenceFile中的地址都載入入記憶體,並且進行了key值排序,從而提供更快的資料查詢。
與SequenceFile只生成一個檔案不同,MapFile生成一個資料夾。
索引模型按128個鍵建立的,可以通過io.map.index.interval來修改
缺點
1.檔案不支援複寫操作,不能向已存在的SequenceFile(MapFile)追加儲存記錄
2.當write流不關閉的時候,沒有辦法構造read流。也就是在執行檔案寫操作的時候,該檔案是不可讀取的

排序後的SequeneceFile,並且它會額外生成一個索引檔案提供按鍵的查詢.讀寫mapFile與讀寫SequenceFile
非常類似,只需要換成MapFile.Reader和MapFile.Writer就可以了。
在命令列顯示mapFile的檔案內容同樣要用  -text

SequenceFile檔案是用來儲存key-value資料的,但它並不保證這些儲存的key-value是有序的,
而MapFile檔案則可以看做是儲存有序key-value的SequenceFile檔案。
MapFile檔案保證key-value的有序(基於key)是通過每一次寫入key-value時的檢查機制,這種檢查機制其實很簡單,就是保證當前正要寫入的key-value與上一個剛寫入的key-value符合設定的順序,
但是,這種有序是由使用者來保證的,一旦寫入的key-value不符合key的非遞減順序,則會直接報錯而不是自動的去對輸入的key-value排序
mapFile既然是排序和索引後的SequenceFile那麼自然可以把SequenceFile轉換為MapFile使用mapFile.fix()方法把一個SequenceFile檔案轉換成MapFile

三、序列化

hadoop在叢集之間通過通訊和RFC呼叫時需要序列化,而且要求序列化要快,體積小,佔用頻寬小。
java序列化機制計算開銷大,序列化結果體積大,大檔案無法切分,浪費空間,很難對其他語言進行擴充套件應用。
java反序列化過程每次都會建立新的物件,不能複用物件。
hadoop定義了兩個序列化相關介面:writable、comparable。
java.io.Serializable 介面的類是可序列化的,沒有實現此介面的類無法序列化或反序列化。所謂的serializable就是java提供的通用的資料儲存和讀取的介面,這樣子,任何型別只要實現了Serializable介面,就可以被儲存到檔案中,或者作為資料流通過網路傳送到別的地方。也可以用管道來傳輸到系統的其他程式中。這樣子極大的簡化了類的設計。只要設計一個儲存一個讀取功能就能解決上面說得所有問題。
java中的comparable介面可以實現類的比較。這樣類就可以通過sort方法實現排序。
writable是基於DataInput和DataOutput 的簡單高效的可序列化介面。幾乎所有的hadoop可序列化物件都要實現write,readFile兩個方法。
hadoop中IntWritable 把java中的Int型別封裝成了Writable序列化格式。
Text型別
儲存的資料按照UTF-8,類似String,它提供了序列化,反序列化和位元組級別比較的方法。Text類替換了UTF8類。

相關文章