hadoop学习笔记(二)hadoop I/O
数据完整性
检测数据是否损坏的常见措施是,在数据第一次引入系统时计算校验和(checksum)。并在数据通过一个不可靠地通道进行传输时再次计算校验和,这样就能发现数据是否损坏。当然校验和也是可能损坏的,由于校验和相对于数据小很多,所以损坏的可能性十分小。
常见的错误检测码是CRC-32(循环冗余校验),任何大小的数据输入均计算得到一个32位的整数校验和。
HDFS的数据完整性
有io.bytes.per.checksum指定字节的数据计算校验和。默认为512个字节,而CRC-32校验和是4个字节,所以存储校验和的而外开销低于1%
每个datanode都持久保存一个校验和日志。datanode会在后台运行一个DataBlockScanner,定期验证datanode上的所有数据块。
通过复制完好的副本修复损坏的数据块。
LocalFileSystem
在客户端执行校验和验证
ChecksumFileSystem
向其他无校验和系统加入校验和。
压缩
好处:减少存储文件的磁盘空间;加速数据在网络和磁盘上的传输。目前有DEFLATE、Gzip、bzip2、LZO和Snappy。其中,bzip2压缩的文件的可切分,LZO在预处理阶段建立索引的情况下也可以实现压缩文件的切分。可切分压缩格式尤其适合MapReduce处理。
codec
实现了压缩-解压缩算法。即一个对CompressionCodec接口的实现,CompressionCodec包含两个方法,createOutputStream()和createInputStream(),分别对输入/输出数据流进行压缩和解压。
通过CompressionCodecFactory推断CompressionCodec:读取压缩文件时,通过压缩文件名推断使用哪个codec。例如以下代码片段:
CompressionCodecFactory factory = new CompressionCodecFactory(conf); CompressionCodec codec = factory.getCodec(inputPath);
为了性能最好使用原生类库来实现压缩和解压缩(相对于内置的java实现)。
压缩和输入分片
应该选择哪种压缩格式呢,对于巨大的、没有存储边界的文件,可以考虑以下选项:
1、存储未经压缩的文件;
2、使用支持切分的压缩格式,如bzip2;
3、在应用中将文件切分成块,并使用任意一种压缩格式为每个数据块建立压缩文件(不论它是否支持切分),在这种情况下要合理地选择数据块的大小,以确保压缩后数据块的大小接近hdfs块的大小;
4、使用顺序文件(SequenceFile 类),它支持压缩和切片。
5、使用Avro数据文件,支持其他多种语言读写。
可以考虑存档格式,但文件不会压缩。
在MapReduce中使用压缩
map阶段产生数据时,对齐进行压缩存盘(可以使用LZO,快速压缩),之后通过网络传输到reducer节点。下面是在作业中启动map任务输出gzip压缩格式的代码:
Configuration conf = new Configuration(); conf.setBoolean("mapred.compress.map.output", true); conf.setClass("mapred.map.output.compression.codec", GzipCodec.class,CompressionCodec.class); Job job = new Job(conf);
序列化
序列化:将结构化对象转化为字节流,以便在网络上传输或写到磁盘进行永久保存。
反序列化:就是将字节流转回结构化对象的过程。(例,磁盘上的字节转为一个对象)
两大领域:进程间通信和永久存储
在hadoop中,多个节点上进程间的通信是通过“远程过程调用”(RPC)实现
RPC序列化特点:紧凑、快速、可扩展、互操作
Hadoop的序列化格式:writable
Writable接口
两个方法:一个将状态写入DataOutPut二进制流,一个正好相反。
RawComparator接口:该接口直接比较数据流中的记录,无需先把数据流反序列化为对象,这样便避免了新建对象的额外开销。
Writable类
Writable类的层次结构
对整型数据编码,可采用定长格式和变长格式(变长格式更节省空间)。
Text:对应于java.lang.String,但有所不同,Text变长,操作少,有时需要将text转为java的String格式。
其他类及接口:不列了...
实现定制的Writable类型
通过定制writable类型可以完全控制二进制表示和排序顺序。
序列化框架
除了Writable,hadoop还允许其他序列化机制,如java serialization(不如writable高效)。
java serialization是序列化图对象的通用机制,有序列化和反序列化开销(really?!,跟图有什么内在的联系,有待进一步探究)
序列化IDL
Apache Thrift和google的Protocol Buffers是两个比较流行的序列化框架,但Mapreduce对其支持有限。
Avro
独立于编程语言的数据序列化系统。用于跨语言编程(这里省略,用到时再查阅)
基于文件的数据结构
SequenceFile、MapFile是为了存储小文件而设计的容器类,将小文件组织起来统一存储。有关这两个类的详细介绍可以参阅:http://blog.csdn.net/javaman_chen/article/details/7241087