hadoop的io操作

此文是一篇讀書筆記,由於剛剛接觸,很多知識點沒有深入。很多地方存在不合理之處,望指出,謝謝。深入知識點會後續補上。
老鳥就不用看了;

Hadoop工程下與I/O相關的包如下:
org.apache.hadoop.io
org.apache.hadoop.io.compress
org.apache.hadoop.io.file.tfile
org.apache.hadoop.io.serializer
org.apache.hadoop.io.serializer.avro
除了org.apache.hadoop.io.serializer.avro是用於Avro提供數據序列化操作外,其餘都是用戶Hadoop的I/O操作。

1 I/O操作中的數據檢查
校驗和方式是檢查數據完整性的重要方式。一般會通過對比新舊校驗和來確定數據情況,若兩者不同則說明數據已經損壞。
HDFS會對寫入的所有數據計算校驗和,並在讀取數據時驗證校驗和。
常用的錯誤檢測碼是CRC-32(循環冗餘校驗)。任何大小的數據輸入均計算得到一個32位的整數校驗和。

hadoop採用HDFS作爲默認的文件系統,需要考慮兩方面的數據完整性:
(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接收數據一般有兩種情況:一是客戶從客戶端上傳數據;二是DataNode從其他DataNode上接收數據。當客戶端上傳數據時,Hadoop會根據預定規則形成一條數據管線
圖7-1(Hadoop實戰第二版)是一個典型的副本管線(數據被分爲3)。數據0是原數據,數據1,數據2,數據3是 備份。

數據按管線流動以完成數據的上傳及備份過程。其數據就是先在客戶端這個節點上保存數據,備份1在接收數據的同時也會把接收到的數據發送給備份2所在的機器,若過程順利,三個備份形成的時間相差不多。

DataNode數據存儲步驟:(包括從DataNode和客戶端兩種傳輸方式)
Ⅰ:在傳輸數據的最開始階段,Hadoop會簡單地檢查數據塊的完整性信息;
Ⅱ:依次向各個DataNode傳輸數據,包括數據頭信息、塊信息、備份個數、校驗和等;
Ⅲ:Hadoop不會在數據每流動到一個DataNode時都檢查校驗和,它只會在數據流達到最後一個節點時才檢查校驗和。
2)客戶端讀取DataNode上的數據時
Hadoop會在客戶端讀取DataNode上的數據時,使用DFSClient中的read函數將數據入到用戶的數據緩衝區,然後再檢查校驗和。
3)DataNode後臺守護進程的定期檢查
DataNode會在後臺運行DataBlockScanner,這個程序會定期檢查此DataNode上的所有數據塊。

2 數據恢復
基本思路是:HDFS存儲至少三個相同的數據塊,假設數據塊1,2,3時相同的三個數據塊,
①客戶端讀取數據塊1時,檢測到數據塊1發生了錯誤,首先向namenode報告數據塊1已經損壞;並拋出異常信息;
②namenode將這個數據塊1標記成已損壞,所以namenode不會再分配客戶端去讀取數據塊1,而是分配客戶端去讀取數據塊2或者數據塊3;
③爲了保證正確數據塊1的數量不變,會複製數據塊2或3到datanode的數據塊4中;
④刪除已損壞數據塊1,這樣就保證複本因子的不變。數據塊數量爲3.

在hadoop上進行數據讀操作時,若發現某數據快失效,讀操作涉及的用戶,DataNode和NameNode都會嘗試來恢復數據塊,恢復成功後設置標籤,防止其他角色重複恢復。
1)檢查已恢復標籤
檢查一致的數據塊恢復標記,若已經恢復,則直接跳過恢復階段。
2)統計各個備份數據塊恢復狀態
在這個階段,DataNode會檢查所有出錯數據塊備份的DataNode,查看這些節點上數據塊的恢復情況,將其作爲一條記錄保存在數據塊記錄表中。
3)找出所有正確版本數據塊中最小長度的版本
DataNode會掃描上一階段中保存的數據塊記錄,判斷當前副本是否正在恢復;
是:跳過;
否:判斷是否配置參數設置了恢復需要保存原副本長度:
是:將恢復長度相同的副本加入待恢復隊列;
否:將所有正確的副本加入到待恢復隊列。
4)副本同步
若需要保持副本長度,則直接同步長度相同的副本即可,否則以長度最小的副本同步其他副本。

3 數據壓縮
對於任何大容量的分佈式存儲而言,文件壓縮都是必須的,文件壓縮帶來的好處是:
Ⅰ:減少文件所需的存儲空間;
Ⅱ:加快文件在網絡上或磁盤上的傳輸速率;
hadoop關於文件壓縮的代碼幾乎都在package.org.apache.hadoop.io.compress中。
(1)hadoop對壓縮工具的選擇
數據存儲 <wbr>--- <wbr>hadoop(四)--- <wbr>Hadoop <wbr>I/O操作
壓縮一般是在時間和空間上的一種權衡。一般來說,更長的壓縮時間會接生過更多的空間。不同的壓縮算法之間有一定的區別。
(2)壓縮分割和輸入分割
壓縮分割和輸入分割時很重要的。bzip2支持文件分割,用戶可以分開讀取每塊內容並分別處理之,因此bizip2壓縮的文件可分割存儲
(3)在MapReduce程序中使用壓縮
在MapReduce中使用壓縮非常簡答,只需在它進行Job配置時配置好conf就可以了。
設置map處理後壓縮數據的代碼如下:
JobConf conf = new Jobconf();
conf.setBoolean("mapred.compress.map.output",true);
對一般情況,壓縮總是好的,無論是對最終結果的壓縮還是對map處理後的中間數據進行壓縮。

4 數據的I/O中序列化操作
序列化是將對象轉化爲字節流的方法,或者說用字節流描述對象的方法。與序列化相對的是反序列化,反序列化就是將字節流轉化爲對象的方法。序列化有兩個目的  :
進程間通信;
數據持久性存儲;
hadoop採用RPC來實現進程間通信 。一般而言,RPC的序列化機制有以下特點
緊湊:緊湊的格式可以充分利用帶寬,加快傳輸速度;
快速:能減少序列化和反序列化的開銷;
可擴展性:可以逐步改變,是客戶端與服務器端直接相關 的;
互操作性:支持不同語言編寫的客戶端與服務器交互數據;
在hadoop中,序列化處於核心地位。因爲無論是存儲文件還是計算中傳輸數據,都需要執行序列化過程。hadoop並沒有採用java提供的序列化機制(java object serialization),而是自己重新寫了一個序列化機制Writeables,它具有緊湊,快速的特點,更方便。
(1)Writable類
Writable是hadoop的核心,hadoop通過它定義了hadoop中基礎的數據類型和操作。一般來說,無論是 上傳下載數據還是運行MapReduce程序,無時無刻不需要使用Writable類,
Writeable類中只定義了兩種方法:序列化輸出數據流反序列化輸入數據流
或者這樣分類:將其狀態到DataOutput二進制流(序列化)和從DataInput二進制流取狀態(發序列化);
1)Hadoop的比較器
WritableComparable是Hadoop中的接口類。
在執行MapRedure,我們知道會對key默認的排序輸出,就是WritableComparable的功勞。
2)writable類中的數據類型
java基本類;例如:boolean,byte,int,float,long,double(6個)
其他類
NullWritable:這是一個佔位符,他的序列化長度爲0
BytesWritable和ByteWritable:BytesWritable是一個二進制數據數組的封裝;ByteWritable是二進制數據封裝
Text:hadoop對string類型的重寫,使用標準的UTF-8編碼。可以理解成Java中String類,但有一定的區別,例如索引、可變性等;
ObjectWritable:一種多類型的封裝。
ArrayWritable和TwoArrayWritable:針對數組和二維數組的構建的數據類型。
MapWritable和SortedMapWritable:分別是java.util.Map()和java.util.SortedMap()的實現。
CompressedWritable:保存壓縮數據的 數據結構。
GenericWritable:通用的數據封裝類型。
VersionedWritable:一個抽象的版本檢查類。

(2)實現自己的hadoop數據類型
hadoop可以支持實現自己的數據類型。

5 序列化框架Avro
儘管大部分MapReduce程序使用的是Writeable類型的key和value,但不是強制使用。可以使用任何類型,只要能有一種機制對每個類型進行類型和二進制表示來回轉換。
序列性框架就是解決這種問題,它是用一個Serialization實現來表示,Avro就是一種序列化框架。

6 針對MapReduce的文件類
對於默寫應用,需要特殊的數據結構來存儲自己的數據。針對此需求,hadoop提供了一些更高層次的容器。
hadoop定義了一些文件數據結構以適應Mapreduce編程框架的需要,其中SequenceFile和MapFile兩種類型非常重要。Map輸出的中間結果就是由他們表示的,其中,MapFile是經過排序並帶有索引的SequenceFile.
(1)SequenceFile類
記錄的是key/value對的列表,是序列化之後的二進制文件,因此不能直接查看,可通過命令查看文件內容。
hadoop fs -text MySequenceFile
sequence有三種不同類型的結構:
未壓縮的key/value對;
記錄壓縮的key/value對(只有value被壓縮);
Block壓縮的key/value對;
注:未壓縮和只壓縮value的SequenceFile數據格式,兩種數據格式相同。
(2)MapFile類
MapFile的使用與SequenceFile類似,與SequenceFile生成一個文件不同,這個程序生成一個文件夾。
(3)ArrayFile,SetFile和BloomMapFile
ArrayFile繼承自MapFile,保存的是從Integer到value的映射關係。
SetFile繼承自MapFile,同JAVA的set類似,僅僅是一個key的集合,而沒有任何value。
BloomMapFile在實際使用中發揮的作用和MapFile類似,只是增加了過濾功能。

參考文章:
Hadoop實戰第二版第七章 (未加粗)
hadoop權威指南第三版第四章(加粗)




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章