第四章之Hadoop I/O
數據的完整性
檢測數據是否損壞的常見措施是:在數據第一次引入系統的時候計算校驗和(checksum),并在數據通過一個不可靠的通道進行傳輸時候再次計算校驗和,這樣就能發現數據是否損壞。如果新的校驗和和原來的校驗和不匹配,我們就認為數據已經損壞。常用的數據檢測碼是:CRC-32(循環冗余校驗)
HDFS的數據完整性
datanode負責驗證收到的數據后存儲數據及其校驗和,它在收到客戶端的數據或復制期間其他datanode的數據時候執行這個操作。正在寫數據的客戶端將數據極其校驗和發送到由一些列datanode組成的管線,管線中的最后一個datanode負責驗證校驗和。如果datanode檢測到錯誤,客戶端變收到一個ChecksumException異常。
客戶端從datanode讀取數據的時候,也會驗證校驗和,將他們與datanode中存儲的校驗和進行比較。每個datanode均持久保存有一個用戶驗證的校驗和日志(persistent log of checksum verification),so他知道每個數據塊最后一次的驗證時間。客戶端成功驗證一個數據塊以后,會告訴這個datanode,datanode由此更新日志。不只是客戶端在讀取數據的時候會驗證校驗和,每個datanode也會在一個后臺線程中運行DataBlockScanner,從而定期驗證存儲在這個datanode上的所有數據塊。
?
LocalFileSystem
Hadoop的LocalFileSystem執行客戶端的校驗和驗證。LocalFileSystem通過ChecksumFileSystem來完成自己的任務,有了這個類,向其他文件系統加入校驗和就非常簡單。
壓縮
文件壓縮有兩大好處:可以減少存儲文件所需要的磁盤空間,可以加速數據在網絡和磁盤上的傳輸。需要處理大量數據的時候,這兩大好處是相當重要的。
gzip是一個通用的壓縮工具。
codec實現了一種壓縮--解壓縮算法。
通過CompressionCodec對數據流進行壓縮和解壓縮
?
壓縮和輸入分片
在考慮如何壓縮將由MapReduce處理的數據的時候,理解這些壓縮格式是否支持切分(splitting)是非常重要的。gzip并不支持文件切分。
?
在MapReduce中使用壓縮
如果輸入的文件是壓縮的,那么在根據文件擴展名推斷出相應的codec后,MapReduce會在讀取文件時候自動解壓縮文件。
想要對MapReduce作業的輸出進行壓縮操作,應在配置過程中,把mapred.output.compress屬性設置為true和mapred.output.compression.codec
對Map任務輸出進行壓縮
盡管MapReduce應用讀寫的是未經過壓縮的數據,但是如果對map階段的中間輸入進行壓縮,也可以獲得不少好處。由于map任務的輸出需要寫到磁盤并通過網絡傳輸到reducer節點,所以如果使用LZO這樣的快速壓縮方式,是可以獲得性能提升的,因為需要傳輸的數據減少了。
?
序列化
所謂序列化(serialization)是指將結構化對象轉化為字節流,以便在網絡上傳輸或者寫到磁盤進行永久存儲。
反序列化(deserialization)是指講字節流轉回結構化對象的逆過程。
序列化在分布式數據處理的兩大領域經常出現:進程間通信和永久存儲。
在Hadoop中,系統中多個節點上進程間的通信是通過“遠程過程調用RPC”實現的,RPC協議將消息序列成二進制流之后發送到遠程節點,遠程節點接著將二進制流反序列化為原始信息。
Hadoop使用自己的序列化格式:Writable,它格式緊湊,速度快,但很難用java以外的語言進行擴展和使用。
Writable接口:
writable接口定義了兩個方法:一個講其狀態寫到DataOutput二進制流,另一個從DataInput二進制流讀取其狀態。
?
Writable集合類
在org.apache.hadoop.io包中,有4個Writable集合類:ArriyWritable,TwoDArrayWritable,MapWritable,SortedMapWritable
?
序列化框架
盡管大多數MapReduce程序使用的都是Writable類型的鍵和值,但這并不是MapReduce強制使用的,事實上可以使用任何類型,只要有一中機制能對每個類型進行類型與二進制的表示的來回切換。
為了支持這一個機制,Hadoop有一個針對可替換序列框架(serialization framework)的API
?
Avro
Apache Avro 是一個獨立于編程語言的數據序列化系統,該項目旨在解決Hadoop中Writable類型的不足:缺乏語言的可移植性。
為什么要有一個新的數據序列化系統?與Apache Thrift和Google ?的 Protocol Buffers相比,Avro有獨特的特性,
Avro數據是用語言無關的模式定義的,但是與其他系統不同的是,Avro的代碼生成是可選的,這意味著你可以對遵循指定模式的數據進行讀寫操作,即使再次之前代碼,從來沒有見過這個特殊的數據模式,為此,Avro假設數據模式總是存在的。Avro模式通常使用JSON編寫,而數據通常用二進制格式編碼,但也有其他選擇。
?
基于文件的數據結構
對于某些應用而言,需要特殊的數據結構來存儲自己的數據,對于基于MapReduce的數據處理,講每個二進制數據的大對象(blob)融入自己的文件中并不能實現很高的擴展性,所以針對上述情況Hadpp開發了一組更高層次的容器。
SequenceFile ?
考慮到日志文件,其中每一條日志記錄是一行文本,如果想記錄二進制類型,純文本是不合適的。這種情況下,Hadoop的SequenceFile類非常合適,因為上述類提供了二進制鍵/值對的永久存儲的數據結構。當作為日志文件的存儲格式的時候,你可以自己選擇鍵,比如由LongWritable類型表示的時間戳,以及值可以是Writable類型,用于表示日志記錄的數量。
SequenceFiles同樣可以作為小文件的容器,而HDFS和MapReduce是針對大文件進行優化的,所以通過SequenceFile類型將小文件包裝起來,可以獲得更高效率的存儲和處理。
SequenceFile的寫操作,通過createwriteer()靜態方法可以創建SequenceFile對象,并返回SequenceFile.Writer實例。存儲在SequenceFile中的鍵和值并不一定需要是Writable類型,任一可以通過Serialization類實現序列化和反序列化的類型均可以被使用。一旦擁有SequenceFile.Writer實例,就可以通過append()方法在文件末尾附加鍵/值對。寫完之后,可以調用close()方法。
SequenceFile讀取操作。從頭到尾讀取順序文件的過程是創建SequenceFile.Reader實例后反復調用next()方法迭代讀取記錄的過程。讀取的是哪條記錄與你使用的序列化框架相關。如果是Writable類型,那么通過鍵/值作為參數的next()方法可以將數據流中的下一條鍵值對讀入變量中。
?
排序和合并順序文件
MapReduce是對多個順序文件進行排序(或者合并)最有效的方法,MapReduce本身具有并行執行能力,并且可以由你指定reducer的數量(該數決定著輸出分區數),例如,通過指定一個reducer,可以得到一個輸出文件。通過MapReduce實現排序/歸并的另一種方法是是用SequenceFile.Sorter類中的sort()方法和merge()方法。
?
順序文件的格式
順序文件由文件頭和最后的一條或者多條記錄組成,順序文件的前三個字節為SEQ,緊隨其后的一個字節表示順序文件的版本號。文件頭還包括其他一些字段,包括鍵和值相應類的名稱,數據壓縮細節,用戶定義的元數據,以及同步標志。
?
MapFile ?
MapFile是已經排序的SequenceFile,他已經加入用于搜索鍵的索引。
寫入MapFile ?類似與SequenceFile的寫入。讀取也是一樣類似。在MapFile中搜索就相當于在索引和排過序的SequenceFile中搜索,所以可以把Sequence轉換為MapFile。
轉載于:https://www.cnblogs.com/honkcal/archive/2012/07/28/2612638.html
總結
以上是生活随笔為你收集整理的第四章之Hadoop I/O的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux性能测试 KSysguard工
- 下一篇: hlp文件怎么打开 打开HLP文件的方法