Hadoop的I/O操作
原文地址: ,歡迎大家訪問。
HDFS的資料完整性
HDFS會對寫入的所有資料計算校驗和,並在讀取資料時驗證校驗和。我們在寫入資料的時候最後一個處理的datanode會去驗證校驗和,如果錯誤的話會丟擲IOException的子異常。且每個datanode都會記錄每次驗證校驗和的日誌,這樣可以方便我們排查錯誤發生的時間。datanode還會主動的定期驗證儲存在該datanode上所有資料的校驗和,當發現錯誤時會向namenode彙報並進行資料修復。
壓縮
codec
我們透過實現CompressionCodec介面來描述我們壓縮-解壓縮演算法,CodepressionCodec裡有兩個方法,分別是createOutputStream(OutputStream out)和createInputStream(InputStream in),前者是對寫入輸出資料流的資料進行壓縮,而後者則是對輸入資料流的資料進行解壓縮。一個CodepressionCodec的實現對應著一種壓縮-解壓縮演算法。
壓縮格式 | 字尾 | 對應的CompressionCodec實現 | 是否可切分 |
---|---|---|---|
DEFALATE | .deflate | org.apache.hadoop.io.compress.DefaultCodec | 否 |
gzip | .gz | org.apache.hadoop.io.compress.GzipCodec | 否 |
bzip2 | .bz2 | org.apache.hadoop.io.compress.BZip2Codec | 是 |
LZ4 | .lz4 | org.apache.hadoop.io.compress.Lz4Codec | 否 |
Snappy | .snappy | org.apache.hadoop.io.compress.SnappyCodec | 否 |
透過CompressionCodecFactory推斷CompressionCodec
CompressionCodecFactory.getCodec()方法可以根據檔案的副檔名來推斷要使用那種CompressionCodec的實現。
@Testpublic void fileDecompressor() throws IOException { FSDataInputStream in = null; try { CompressionCodecFactory factory = new CompressionCodecFactory(configuration); Path inPath = new Path("/test/codec/test.txt.gz"); CompressionCodec codec = factory.getCodec(inPath); in = fs.open(new Path("/test/codec/test.txt.gz")); IOUtils.copyBytes(codec.createInputStream(in), System.out, 4096); } finally { in.close(); } }
程式碼中包含的某些變數的定義我沒有粘過來,如果需要測試的話可以檢視完整的程式碼。
壓縮和輸入分片
DEFALATE、gzip、bzip2、LZO、LZ4、Snappy幾種壓縮格式中,只有bzip2是支援切分的。對於大檔案來說最好不要使用不支援切分整個檔案的壓縮格式,因為這麼做會失去資料的本地特性,大量的網路傳輸進而造成MapReduce應用效率低下。
在MapReduce中使用壓縮
如果MapReduce程式的輸入檔案是壓縮的,那麼MapReduce程式會使用上面透過CompressionCodecFactory推斷CompressionCodec的方式推斷出對應的codec,然後再讀取檔案的時候自動解壓縮檔案。
如果我們想壓縮MapReduce作業的輸入資料的話,則還需要進行相應的配置,具體如何配置我會在後面的文章中進行說明,期待吧。
序列化
序列化指將結構化的物件轉化為位元組流以便在網路上傳輸或寫到磁碟儲存的過程。與之對應的反序列化就是將位元組流轉換成結構化物件的過程。
Writeable介面
Hadoop使用的是自己的序列化格式Writable,緊湊且速度快,但是對Java之外的其他語言並不是很友好。Hadoop本身提供了很多Writable類,Java的基本型別都有被封裝,正對String的Text,BytesWritable,NullWritable,ArrayWritable等等。
實現定製的Writeable
這裡我們定製一個UserWriteable物件,包含了name和address兩個屬性。
public class UserWriteable implements Writable { private String name; private String address; public String getName() { return name; } public UserWriteable setName(String name) { this.name = name; return this; } public String getAddress() { return address; } public UserWriteable setAddress(String address) { this.address = address; return this; } public void write(DataOutput dataOutput) throws IOException { dataOutput.writeChars(name); dataOutput.writeChars(address); } public void readFields(DataInput dataInput) throws IOException { // 先進先出原則,與write方法對應 name = dataInput.readLine(); address = dataInput.readLine(); } }
-
write
將物件的屬性寫入二進位制流(DataOutput)。
-
readFields
從二進位制流(DataInput)中還原物件屬性。
-
為什麼不用Java的序列化機制
該機制與語言密切相關。
太複雜。
作者:名字想好沒
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1834/viewspace-2819766/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【課件整理複習】Hadoop-第7講 Hadoop的I/O操作Hadoop
- 02. I/O 操作
- Python教程:精簡概述I/O模型與I/O操作Python模型
- 流?I/O 操作?阻塞?epoll?
- I/O流以及檔案的基本操作
- 使用Task實現非阻塞式的I/O操作
- 計算機I/O與I/O模型計算機模型
- I/O流
- Java I/OJava
- Linux下的5種I/O模型與3組I/O複用Linux模型
- 使用 iotop 監控哪些程式在進行I/O操作
- 關於I/O
- c++ I/OC++
- 【java】I/O流Java
- Java(8)I/OJava
- JAVA I/O系統Java
- 系統級 I/O
- Google I/O Extend 2018Go
- 網路I/O模型模型
- NodeJs 非同步 I/ONodeJS非同步
- 理解I/O Completion Port
- python 非同步 I/OPython非同步
- Java 非同步 I/OJava非同步
- Linux UIO機制--使用者空間I / O操作方法LinuxUI
- 【面試】I/O 複用面試
- Java™ 教程(命令列I/O)Java命令列
- I/O模型、Libuv和Eventloop模型OOP
- 由Nodejs來說I/ONodeJS
- Linux I/O排程器Linux
- 熟悉常用的Linux操作和Hadoop操作LinuxHadoop
- 從網路I/O模型到Netty,先深入瞭解下I/O多路複用模型Netty
- 如何更改Linux的I/O排程器Linux
- I/O流中的BufferedXXXStream與DataXXXStream、ObjectXXStreamObject
- 如何監測 Linux 的磁碟 I/O 效能Linux
- 登錄檔引起的 I/O 操作發生了不可恢復的錯誤處理辦法
- asynchronous i/o (aio) on HP-UXAIUX
- Linux裡五種I/O模型Linux模型
- IRP(I/O Request Package)詳解Package