MapReduce關於數據壓縮使用與支持的格式

1.壓縮概述
數據壓縮這是mapreduce的一種優化策略:通過壓縮編碼對mapper或者reducer的輸出進行壓縮,以減少磁盤IO,提高MR程序運行速度(但相應增加了cpu運算負擔)

Mapreduce支持將map輸出的結果或者reduce輸出的結果進行壓縮,以減少網絡IO或最終輸出數據的體積

壓縮特性運用得當能提高性能,但運用不當也可能降低性能

壓縮使用基本原則:

         運算密集型的job,少用壓縮

        IO密集型的job,多用壓縮

2 MR支持的壓縮編碼
2.1下面是MR支持的壓縮格式

注意:LZO和Snappy需要安裝以後才能使用。

2.3同一個文件實際測試壓縮結果

2.4壓縮時間 

可以看出壓縮性能越高,需要的壓縮時間越長,Snappy < LZ4 < LZO < GZIP < BZIP2

1.gzip: 
優點:壓縮比在四種壓縮方式中較高;hadoop本身支持,在應用中處理gzip格式的文件就和直接處理文本一樣;有hadoop native庫;大部分linux系統都自帶gzip命令,使用方便。 
缺點:不支持split。

2.lzo壓縮 
優點:壓縮/解壓速度也比較快,合理的壓縮率;支持split,是hadoop中最流行的壓縮格式;支持hadoop native庫;需要在linux系統下自行安裝lzop命令,使用方便。 
缺點:壓縮率比gzip要低;hadoop本身不支持,需要安裝;lzo雖然支持split,但需要對lzo文件建索引,否則hadoop也是會把lzo文件看成一個普通文件(爲了支持split需要建索引,需要指定inputformat爲lzo格式)。

3.snappy壓縮 
優點:壓縮速度快;支持hadoop native庫。 
缺點:不支持split;壓縮比低;hadoop本身不支持,需要安裝;linux系統下沒有對應的命令。
4.bzip2壓縮 
優點:支持split;具有很高的壓縮率,比gzip壓縮率都高;hadoop本身支持,但不支持native;在linux系統下自帶bzip2命令,使用方便。 
缺點:壓縮/解壓速度慢;不支持native。

2.5 中間壓縮的配置和最終結果壓縮的配置
可以使用Hadoop checknative檢測本機有哪些可用的壓縮方式

[finance@master2-dev ~]$ hadoop checknative
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=100m; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=150m; support was removed in 8.0
19/06/17 15:30:24 WARN bzip2.Bzip2Factory: Failed to load/initialize native-bzip2 library system-native, will use pure-Java version
19/06/17 15:30:24 INFO zlib.ZlibFactory: Successfully loaded & initialized native-zlib library
19/06/17 15:30:25 ERROR snappy.SnappyCompressor: failed to load SnappyCompressor
java.lang.UnsatisfiedLinkError: Cannot load libsnappy.so.1 (libsnappy.so.1: cannot open shared object file: No such file or directory)!
    at org.apache.hadoop.io.compress.snappy.SnappyCompressor.initIDs(Native Method)
    at org.apache.hadoop.io.compress.snappy.SnappyCompressor.<clinit>(SnappyCompressor.java:57)
    at org.apache.hadoop.io.compress.SnappyCodec.isNativeCodeLoaded(SnappyCodec.java:82)
    at org.apache.hadoop.util.NativeLibraryChecker.main(NativeLibraryChecker.java:91)
Native library checking:
hadoop:  true /log/software/hadoop-2.9.1.8/lib/native/Linux-amd64-64/libhadoop.so
zlib:    true /lib64/libz.so.1
snappy:  false 
zstd  :  false 
lz4:     true revision:10301
bzip2:   false 
openssl: true /usr/lib64/libcrypto.so


3.壓縮的使用與配置文件的修改

core-site.xml codecs

從HDFS中讀取文件進行Mapreuce作業,如果數據很大,可以使用壓縮並且選擇支持分片的壓縮方式(Bzip2,LZO),可以實現並行處理,提高效率,減少磁盤讀取時間,同時選擇合適的存儲格式例如Sequence Files,RC,ORC等;

<property>
    <name>io.compression.codecs</name>
    <value>
    org.apache.hadoop.io.compress.GzipCodec,
    org.apache.hadoop.io.compress.DefaultCodec, #zlib->Default
    org.apache.hadoop.io.compress.BZip2Codec,
    com.hadoop.compression.lzo.LzoCodec,
    com.hadoop.compression.lzo.LzopCodec,
    org.apache.hadoop.io.compress.Lz4Codec,
    org.apache.hadoop.io.compress.SnappyCodec,
    </value>
</property>


mapred-site.xml (switch+codec)

<property>
             #支持壓縮
    <name>mapreduce.output.fileoutputformat.compress</name>
    <value>true</value>
</property>
            #壓縮方式
<property>
    <name>mapreduce.output.fileoutputformat.compress.codec</name>
    <value>org.apache.hadoop.io.compress.BZip2Codec</value>
</property> 


中間壓縮:中間壓縮就是處理作業map任務和reduce任務之間的數據,對於中間壓縮,最好選擇一個節省CPU耗時的壓縮方式(快)。hadoop壓縮有一個默認的壓縮格式,當然可以通過修改mapred.map.output.compression.codec屬性,使用新的壓縮格式,這個變量可以在mapred-site.xml 中設置。Map輸出作爲Reducer的輸入,需要經過shuffle這一過程,需要把數據讀取到一個環形緩衝區,然後讀取到本地磁盤,所以選擇壓縮可以減少了存儲文件所佔空間,提升了數據傳輸速率,建議使用壓縮速度快的壓縮方式,例如Snappy和LZO.

<property>
         <name>mapred.map.output.compression.codec</name>
         <value>org.apache.hadoop.io.compress.SnappyCodec</value>
         <description> This controls whether intermediate files produced by Hive
         between multiple map-reduce jobs are compressed. The compression codec
         and other options are determined from hadoop config variables
         mapred.output.compress* </description>
</property>

 
最終壓縮:可以選擇高壓縮比,減少了存儲文件所佔空間,提升了數據傳輸速率 。進行歸檔處理或者鏈接Mapreduce的工作(該作業的輸出作爲下個作業的輸入),壓縮可以減少了存儲文件所佔空間,提升了數據傳輸速率,如果作爲歸檔處理,可以採用高的壓縮比(Gzip,Bzip2),如果作爲下個作業的輸入,考慮是否要分片進行選擇。

mapred-site.xml 中設置
<property>
    <name>mapreduce.output.fileoutputformat.compress.codec</name>
    <value>org.apache.hadoop.io.compress.BZip2Codec</value>
</property>


5 hadoop源碼壓縮文件的讀取

Hadoop自帶的InputFormat類內置支持壓縮文件的讀取,比如TextInputformat類,在其initialize方法中:

 

 public void initialize(InputSplit genericSplit,
                         TaskAttemptContext context) throws IOException {
    FileSplit split = (FileSplit) genericSplit;
    Configuration job = context.getConfiguration();
    this.maxLineLength = job.getInt(MAX_LINE_LENGTH, Integer.MAX_VALUE);
    start = split.getStart();
    end = start + split.getLength();
    final Path file = split.getPath();
 
    // open the file and seek to the start of the split
 
    final FileSystem fs = file.getFileSystem(job);
    fileIn = fs.open(file);
    //根據文件後綴名創建相應壓縮編碼的codec
    CompressionCodec codec = new CompressionCodecFactory(job).getCodec(file);
    if (null!=codec) {
 
      isCompressedInput = true;  
 
      decompressor = CodecPool.getDecompressor(codec);
           //判斷是否屬於可切片壓縮編碼類型
 
      if (codec instanceof SplittableCompressionCodec) {
 
        final SplitCompressionInputStream cIn =
          ((SplittableCompressionCodec)codec).createInputStream(
            fileIn, decompressor, start, end,
            SplittableCompressionCodec.READ_MODE.BYBLOCK);
                    //如果是可切片壓縮編碼,則創建一個CompressedSplitLineReader讀取壓縮數據
 
        in = new CompressedSplitLineReader(cIn, job,
            this.recordDelimiterBytes);
        start = cIn.getAdjustedStart();
        end = cIn.getAdjustedEnd();
        filePosition = cIn;
      } else {
 
                   //如果是不可切片壓縮編碼,則創建一個SplitLineReader讀取壓縮數據,並將文件輸入流轉換成解壓數據流傳遞給普通SplitLineReader讀取
 
        in = new SplitLineReader(codec.createInputStream(fileIn,
            decompressor), job, this.recordDelimiterBytes);
        filePosition = fileIn;
      }
 
    } else {
 
      fileIn.seek(start);
            //如果不是壓縮文件,則創建普通SplitLineReader讀取數據
      in = new SplitLineReader(fileIn, job, this.recordDelimiterBytes);
      filePosition = fileIn;
    }


具體關於壓縮的使用可以參考hive中的使用演示:Hive中壓縮使用詳解與性能分析

發佈了253 篇原創文章 · 獲贊 80 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章