Hadoop权威指南---I/O操作

目录

Hadoop的I/O操作 

1、数据完整性 

1.1、HDFS的数据完整性 

1.2、 LocalFileSystem 和 ChecksumFileSystem 

2、 压缩 CompressionCodec

2.1、 codec:Hadoop中对常用压缩解压缩算法的实现

2.2、 压缩和输入分片

2.3、 在MapReduce中使用压缩

​3、 序列化 Writable

3.1 Writable接口 

3.2 Writable类

3.3 实现定制的Writable集合

3.4 序列化框架

4、 基于文件的数据结构 

4.1 关于SequenceFile

4.2 关于MapFile

4.3 其他文件格式和面向列的格式


Hadoop的I/O操作 

1、数据完整性 

数据在进过网络io传输或者磁盘io时有可能会损坏,因此一般通过计算校验和来确定传输数据是否被损坏。校验和checksum也有可能会损坏,但是因为其数量很小,出现损坏的几率很小。

1.1、HDFS的数据完整性 

简单来说,在客户端往datanode写数据的时候也会发生校验和,和datanode节点接收到的数据计算得到的校验和对比,如果不一致会报错给客户端,如果一致,在datanode节点每个数据块下也会保存一个数据块的校验和文件;当客户端读取数据块时也会读取校验和文件,然后和自己通过数据块计算的校验和对比,看看数据块是否被损坏。并且持久化DataNode节点的校验和文件会实时更新最后客户端的访问时间,好用于统计该文件块什么时候开始损坏的。

1.2、 LocalFileSystem 和 ChecksumFileSystem 

ChecksumFileSystem 继承自FileSystem

Path getChecksumFile(Path file)方法可以获取任意一个文件的校验和路径
public abstract class ChecksumFileSystem extends FilterFileSystem {}
public class FilterFileSystem extends FileSystem {}

 

2、 压缩 CompressionCodec

压缩文件的两大好处:

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

2.1、 codec:Hadoop中对常用压缩解压缩算法的实现

1)、通过CompressionCodec 对数据流进行压缩和解压缩

简单来说就是需要对输出流进行压缩的时候调用createOutputStream来包装一个输出流,解压缩的时候调用createInputStream来包装一个输入流

public interface CompressionCodec {
    CompressionOutputStream createOutputStream(OutputStream var1) throws IOException;

    CompressionOutputStream createOutputStream(OutputStream var1, Compressor var2) throws IOException;

    Class<? extends Compressor> getCompressorType();

    Compressor createCompressor();

    CompressionInputStream createInputStream(InputStream var1) throws IOException;

    CompressionInputStream createInputStream(InputStream var1, Decompressor var2) throws IOException;

    Class<? extends Decompressor> getDecompressorType();

    Decompressor createDecompressor();

    String getDefaultExtension();

    public static class Util {
        public Util() {
        }

        static CompressionOutputStream createOutputStreamWithCodecPool(CompressionCodec codec, Configuration conf, OutputStream out) throws IOException {
            Compressor compressor = CodecPool.getCompressor(codec, conf);
            CompressionOutputStream stream = null;

            try {
                stream = codec.createOutputStream(out, compressor);
            } finally {
                if (stream == null) {
                    CodecPool.returnCompressor(compressor);
                } else {
                    stream.setTrackedCompressor(compressor);
                }

            }

            return stream;
        }

        static CompressionInputStream createInputStreamWithCodecPool(CompressionCodec codec, Configuration conf, InputStream in) throws IOException {
            Decompressor decompressor = CodecPool.getDecompressor(codec);
            CompressionInputStream stream = null;

            try {
                stream = codec.createInputStream(in, decompressor);
            } finally {
                if (stream == null) {
                    CodecPool.returnDecompressor(decompressor);
                } else {
                    stream.setTrackedDecompressor(decompressor);
                }

            }

            return stream;
        }
    }
}
public abstract class CompressionOutputStream extends OutputStream {
    protected final OutputStream out;
    private Compressor trackedCompressor;
。。。
}
public abstract class CompressionInputStream extends InputStream implements Seekable {
    protected final InputStream in;
    protected long maxAvailableData = 0L;
    private Decompressor trackedDecompressor;
。。。
}

2)、通过CompressionCodecFactory的getCodec方法推断文件使用的压缩类型类CompressionCodec

其中支持通过文件的扩展名来判断使用的压缩算法类,通过输入文件的路径path

 3)、压缩解压缩的原生类库

 4)、CodecPool是一个静态工厂类

类似于数据库连接池、线程池的概念,主要是重用Compressor和Decompressor对象

2.2、 压缩和输入分片

支持切分的压缩算法bzip2

2.3、 在MapReduce中使用压缩


3、 序列化 Writable

3.1 Writable接口 

public interface Writable {
    void write(DataOutput var1) throws IOException;

    void readFields(DataInput var1) throws IOException;
}

其中:

  • write方式是执行序列化操作的,把writeable对象自己写入到输出流中,然后转化为字节数组;
  • readFields是执行反序列化的,把字节数组封装到输入流中,然后根据输入流来构建writeable对象;

Writable接口的序列化 :把一个Writable对象序列化为字节数组

Writable接口的反序列化 :把字节数组中的数据反序列化为一个Writable对象

WritableComparable和comparator

public interface WritableComparable<T> extends Writable, Comparable<T> {
}

public class WritableComparator implements RawComparator, Configurable {}

3.2 Writable类

1)、Writable的基本类型封装

2)、text类型(其也实现了序列化接口Writable)

对比Text和IntWritable类型

public class Text extends BinaryComparable implements WritableComparable<BinaryComparable> {}
public class IntWritable implements WritableComparable<IntWritable> {}

text是针对UTF-8序列的Writable类,一般可以认为是java的String的Writable等价(一般作为MapReduce的Key)

3)、BytesWritable

4)、NullWritable

 

5)、ObjectWritable和GenericWritable

6)、Writable的集合类

3.3 实现定制的Writable集合

 

3.4 序列化框架

 

public class WritableSerialization extends Configured implements Serialization<Writable> {}
public interface Serialization<T> {
    boolean accept(Class<?> var1);

    Serializer<T> getSerializer(Class<T> var1);

    Deserializer<T> getDeserializer(Class<T> var1);
}

4、 基于文件的数据结构 

4.1 关于SequenceFile

顺序文件:以key:value形式的文本文件???

4.2 关于MapFile

4.3 其他文件格式和面向列的格式

参考:

Hadoop权威指南.大数据的存储与分析.第4版---第5章 Hadoop的I/O操作

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值