BZip2Codec壓縮、Reduce端壓縮控制……Hadoop整合壓縮知識點來了

csdn雲計算 發佈 2020-03-06T20:23:19+00:00

>codecClass = Class.forName; CompressionCodec codec = ReflectionUtils.newInstance); FileOutputStream fos = new FileOutputStre

作者 | Tai_Park

責編 | Carol

來源 | CSDN 博客

封圖 | CSDN付費下載於東方 IC


今天來聊聊 Hadoop 的壓縮。


壓縮:原始數據通過壓縮手段產生目標數據,要求輸入和輸出的內容是一樣的(大部分),但體積是不一樣的。


對於單機用戶來說,磁碟空間的限制導致了文件壓縮的需求;對於Hadoop用戶來說,由於DataNode的限制,也要對HDFS上的數據進行壓縮。壓縮的目的是減少存儲在HDFS上的數據所占用的空間(磁碟的角度),提升網絡的傳輸效率(網絡的角度)。對於分布式計算框架來說,Shuffle是一個主要的技術瓶頸。


大數據處理流程基本上是輸入==>處理==>輸出,舉例來說,在離線處理方面,Spark可以HDFS==>Spark==>HDFS,在實時處理方面,Spark Streaming可以Kafka==>Spark Streaming==>RDBMS。壓縮可以使用在輸入時,也可以使用在處理時(比如map作為中間狀態,它的輸出可以壓縮以減少Shuffle的量),輸出時。


MR在進行壓縮數據處理時,不需要手工去處理。但是MR執行過程中,是需要一個動作進行數據壓縮、解壓的,MR根據後綴名進行處理。在處理壓縮、解壓的過程中,是有CPU資源的消耗的。如果集群本來CPU使用率很高,就會對其他作業產生影響,不建議使用壓縮。


常見的壓縮格式有GZIP、BZIP2、LZO、SNAPPY。選擇壓縮格式要從壓縮比、壓縮速度考慮。不同的壓縮格式對應不同的codec。


BZip2Codec壓縮

package com.bigdata.compression;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.io.IOUtils;import org.apache.hadoop.io.compress.CompressionCodec;import org.apache.hadoop.io.compress.CompressionOutputStream;import org.apache.hadoop.util.ReflectionUtils;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;public class CompressionApp {    public static void main(String[] args) throws Exception{        String filename = "ip.txt";        String method = "org.apache.hadoop.io.compress.BZip2Codec";        compress(filename,method);    }    private static void compress(String filename, String method) throws Exception{        FileInputStream fis = new FileInputStream(new File(filename));        Class<?> codecClass = Class.forName(method);        CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, new Configuration());        FileOutputStream fos = new FileOutputStream(new File(filename + codec.getDefaultExtension()));        CompressionOutputStream cos = codec.createOutputStream(fos);        IOUtils.copyBytes(fis,cos,1024*102485);        cos.close();        fos.close();        fis.close();    }}
  1. 讀取輸入流
  2. 通過類名反射出對應的codec
  3. 寫出輸出流
  4. 通過IOUtils.copyBytes寫出去


壓縮前後對比:



BZip2Codec解壓

private static void decompression(String filename) throws Exception{        CompressionCodecFactory factory = new CompressionCodecFactory(new Configuration());        CompressionCodec codec = factory.getCodec(new Path(filename));        CompressionInputStream fis = codec.createInputStream(new FileInputStream(new File(filename)));        FileOutputStream fos = new FileOutputStream(new File(filename) + ".decoded");        IOUtils.copyBytes(fis,fos,1024*102485);        fos.close();        fos.close();        fis.close();    }

解壓前後對比:


Map端壓縮控制

mapred-default.xml中有mapreduce.map.output.compress參數,控制map輸出時的壓縮,mapreduce.map.output.compress.codec控制壓縮類型。

代碼層面可以用:

configuration.setBoolean("mapreduce.map.output.compress",true);configuration.setClass("mapreduce.map.output.compress.codec",BZip2Codec.class,CompressionCodec.class);

進行設置即可。

若要在配置層面更改,core-site.xml需要加上:

<property>    <name>io.compression.codecs</name>    <value>        org.apache.hadoop.io.compress.GzipCodec,        org.apache.hadoop.io.compress.DefaultCodec,        org.apache.hadoop.io.compress.BZip2Codec,        org.apache.hadoop.io.compress.SnappyCodec    </value></property>

mapred-site.xml添加:

mapreduce.map.output.compress=truemapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.BZip2Codemapreduce.output.fileoutputformat.compress=truemapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.BZip2Code

配置文件修改完重啟Hadoop即可。


Reduce端壓縮控制

mapred-default.xml中有mapreduce.output.fileoutputformat.compress參數,控制reduce端輸出時的壓縮,

mapreduce.output.fileoutputformat.compress.codec控制壓縮類型。

設置同上。

你還有什麼 Hadoop 整合壓縮相關知識點?歡迎評論告訴我們 ~

關鍵字: