Hadoop的I/O操作

本文详细介绍了Hadoop的I/O操作,包括压缩的Codec、在MapReduce中的使用,以及序列化机制如Writable接口、SequenceFile和MapFile。文章探讨了压缩的好处,如减少存储空间和加速数据传输,并解释了Hadoop中不同类型的Codec。同时,文章还深入讨论了Hadoop的序列化,如Writable接口和WritableComparable接口,以及它们在进程间通信和永久存储中的应用。此外,文章还介绍了SequenceFile和MapFile这两种基于文件的数据结构,用于高效存储和处理二进制数据。
摘要由CSDN通过智能技术生成

Hadoop的I/O操作

一、压缩

文件压缩有两大好处:

  • 减少存储文件所需要的磁盘空间
  • 加速数据在网络和磁盘上的传输

在Hadoop中更是如此。

Codec

Codec是压缩-解压缩算法的一种实现,在Hadoop中用CompressionCodec(接口)的实现代表一个Codec,常见的实现类有DefaultCdec(implements CompressionCodec),GzipCodec(extends DefaultCodec ),BZip2Codec,LzopCodec,Lz4Codec,SnappyCodec分别对应相应的压缩-解压算法。
1)CompressionCodec要对写入输出数据流的数据进行压缩,用到函数

CompressionOutputStream createOutputStream(OutputStream out) throws IOException;

Demo:

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;

public class StreamCompressor {

    public static void main(String[] args) throws Exception{
        String codeClassName = args[0];
        Configuration configuration = new Configuration();
        Class<?> className = Class.forName(codeClassName);
        CompressionCodec codec = (CompressionCodec)ReflectionUtils.newInstance(className, configuration);
        CompressionOutputStream outputStream = codec.createOutputStream(System.out);
        IOUtils.copyBytes(System.in, outputStream, 4096,false);

        outputStream.flush();
    }
}

用GzipCodec压缩"Text"并用gunzip解压缩,命令行中输入

echo "Text" | hadoop StreamCompressor org.apache.hadoop.io.compress.GzipCodec \| gunzip

2)CompressionCodec要对输入数据流中数据进行读取时进行解压缩,用到函数

 CompressionInputStream createInputStream(InputStream in) throws IOException;

CompressionOutputStream 和 CompressionInputStream 重置底层的压缩和解压缩方法,可以将部分数据流压缩为单独的数据块(BLOCK),在下面介绍的SequenceFile的格式中有应用。

通过CompressionCodecFactory推断CompressionCodec
Demo代码:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.CompressionCodecFactory;

import java.io.InputStream;
import java.io.OutputStream;

public class FileDecompressor {
    
    public static void main(String[] args) throws Exception{
        String uri = args[1];
        Path inputPath = new Path(uri);
        Configuration configuration = new Configuration();
        CompressionCodecFactory factory = new CompressionCodecFactory(configuration);
        //getCodec()拿到Codec
        CompressionCodec compressionCodec = factory.getCodec(inputPath);
        //拿到codec之后用工厂的静态方法removeSuffix()去除后缀形成输出文件名,如file.gz得到的解压缩文件名就为file
        String outputUri = CompressionCodecFactory.removeSuffix(uri,compressionCodec.getDefaultExtension());
        InputStream in = null;
        OutputStream out = null;
        FileSystem fs = FileSystem.get(configuration);
        try{
            in = compressionCodec.createInputStream(fs.open(inputPath));
            out = fs.create(new Path(outputUri));
            IOUtils.copyBytes(in, out, configuration);
        }finally {
            IOUtils.closeStream(out);
            IOUtils.closeStream(in);
        }
    }
    
}

CodecPool
用到原生库(native,可以提高压缩与解压缩的性能)并且需要重复压缩与解压缩时可以用到CodecPool,通过返回compressor在不同数据流之间来回复制数据。

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.compress.CodecPool;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.CompressionOutputStream;
import org.apache.hadoop.io.compress.Compressor;
import org.apache.hadoop.util.ReflectionUtils;

public class PooledStreamCompressor {

    public static void main(String[] args) throws Exception{
        String codecClassName = args[0];
        Class<?> codecClass = Class.forName
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值