Hadoop IO的操作意义:基于海量数据集的完整性和压缩性,Hadoop提供了用于分布式系统的API,包括序列化操作以及底层的数据结构。
1.HDFS数据完整性
目的:保证用户在存储和处理数据时,数据不会有任何的丢失和损坏。
(1)校验和
检测数据的常见措施:在数据第一次引入系统时计算校验和(checksum),在数据通过不可靠的通道进行传输时再次计算校验和,这样就能发现数据是否损坏。
如果新校验和和原来的校验和不匹配,就认为数据有损坏。
A . HDFS的数据完整性:
HDFS对写入的数据计算校验和,并在读取时验证校验和。
写入数据节点验证:数据节点负责在验证收到的数据后,存储数据及其校验和,在收到客户端数据或复制其他DataNode的数据时执行。正在写数据的客户端将数据及其校验和发送到一系列数据节点组成的管线,管线的最后一个数据节点负责验证校验和。
读取数据节点验证:客户端读取数据节点数据也会验证校验和,将其和数据节点中存储的校验和进行比较。每个数据节点都会持久化一个用于验证的校验和日志,所以它知道每个数据块的最后一次验证时间。当客户端成功验证一个数据块之后,数据节点就会更新日志。
B . 恢复数据
因为Hdfs中能够存储了每个数据块的副本,因此可以通过复制完好的数据副本来修复损坏的数据块。
C . LocalFileSystem类
该类执行客户端的校验和验证。这就意味着,当你写入一个名为filename的文件时,文件系统客户端会明确的在包含每个文件块校验和的同一目录内新建一个名为filename.crc的隐藏文件
D . ChecksumFileSystem类
ChecksumFileSystem类继承自FileSystem类,一般用法为:
FileSystem rawFs = ...
FileSystem checksummedFs = new ChecksumFileSystem ( rawFs ) ;
其中的方法有:
getRawFileSystem ( ) :用于获得任意一个文件的校验和文件路径。
reportChecksumFailure ( ) :在读取文件时,若检测到错误,就会调用此方法报告错误,然后LocaclFileSystem将出错的文件和校验和移到bad_files的文件夹内,管理员会定期检查这个文件夹。
(2)运行后台进程来检测数据块
数据节点后台有一个进程DataBlockScanner,定期验证存储在这个数据节点上的所有数据项,该项措施解决物理存储媒介上的损坏。工作流程如图:
2.文件结构
HDFS主要是针对大数据文件来设计的,在小文件处理上效率低。解决方法就是选择一个容器,将小文件包装起来,将整个文件作为一条记录。hdfs提供了两种类型的容器:SequenceFile和MapFile。
SequenceFile:
sequence File由一系列的二进制key/value组成,如果key为小文件名,value为文件内容,则可以将大批小文件合并成一个大文件。Hadoop-0.21.0版本开始提供了SequenceFile,包括Writer,Reader和SequenceFileSorter类进行写,读和排序操作。该方案对于小文件存取都比较自由,不限制用户和文件的多少,支持Append追加写入,支持三级文档压缩(不压缩、文件级、块级别)、其存储结构如图:
SequenceFile存储:
文件中每条记录是可序列化、可持久化的键值对,提供相应的读写器和排序器,写操作根据压缩的类型分为3种:
—Write无压缩写数据
—RecordCompressWriter记录级压缩文件,只压缩值
—BlockCompressWrite块级压缩文件,键值采用独立压缩方式
在存储结构上,sequenceFile主要由一个header后跟多条record组成,如图:
MapFile:
一个MapFile可以通过SequenceFile的地址,进行分类查找的格式。使用这个格式的优点在于,首先会将SequenceFile的地址都加载到内存中,并且进行key值排序,从而提供更快的数据查找。
与SequenceFile只生成一个文件不同,MapFile生成一个文件夹。
缺点:
1)文件不支持复写操作,不能向已存在的SequenceFile追加存储记录
2)当write流不关闭时,没有办法构造read流。也就是在执行文件写操作时,该文件是不可读取的。
3.数据类型
(1)序列化
序列化serialization:是指将结构化对象转化为字节流,以便写到磁盘进行永久存储或者在网络上传输。
在hadoop中,系统中多个节点上进程间的通信是通过“远程过程调用”(remote procedure call,RPC)实现的,而且要求系列化要快,且体积小,占用带宽小。Hadoop定义了两个序列化相关接口:writable和comparable。
Hadoop使用自己的序列化格式Writable,它格式紧凑,速度快,但很难用java以外的语言进行扩展或使用。
writable接口:基于datainput和dataoutput的简单高效可序列化接口,就是org.apache.hadoop.io.writable接口,几乎所有的hadoop可序列化对象都必须实现这个接口有来哥哥方法:Write,readFiles。
以IntWritable为例,它把java的int类型封装成了Writable序列化格式:
可以通过set ( )设置它的值,new IntWritable().set(100);或者 new IntWritable(100)
实现序列化需要继承接口,接口方法有重要的三个,例如:
A implements Writable,com..{
write ( DataInputStream ) DataInputStream
readFiles ( )
comparaTo ( B b )
}
当A继承了该接口,就可以在hadoop上进行存储操作。
4.hadoop压缩
通过压缩,减少存储文件所需空间,还可以降低其在网络上传输的时间。
本地库:
因为hadoop使用java开发,但是有些需求和操作并不适合java,所以引入了本地库native。
本地库native是为了大量的数据读写快速,可以高效执行某些操作,如使用gzip压缩解压时,使用本地库比使用java要时间短。
压缩格式:
A. Gzip:优点:是压缩率高,速度快
缺点:不支持split,当文件压缩在128M内都可以用gzip
B. Izo:优点:压缩速度快,支持split,支持native
缺点:hadoop本身不支持,需要安装,比gzip压缩率低
C. Snappy:优点:高速,压缩率合理,支持native
缺点:hadoop不支持,Linux没有对应的命令安装
D. Bzip2:优点:支持split,压缩率比gzip高,hadoop支持,Linux自带命令
缺点:不支持native,压缩解压速度慢