《大数据课件 11.MapReduce IO操作》由会员分享,可在线阅读,更多相关《大数据课件 11.MapReduce IO操作(61页珍藏版)》请在金锄头文库上搜索。
1、MapReduce IO操作Hadoop IO操作 Hadoop自带一套原子操作用于数据1/0操作。其中有一些技术比Hadoop本身更常用,如数据完整性保持和压缩,但在处理多达好几个TB的数据集时,特别值得关注。其他一些则是Hadoop工其或API,它们所形成的构建模块可用于开发分布式系统,比如序列化操作和在盘(on-disk)数据结构。数据完整性 Hadoop用户肯定都希望系统在存储和处理数据时不会丢失或损坏任何数据。尽管磁盘或网络上的每个I/O操作不太可能将错误引入自己正在读写的数据中,但是如果系统中需要处理的数据量大到Hadoop的处理极限时,数据被损坏的概率还是很高的。 检测数据是否损
2、坏的常见措施是,在数据第一次引入系统时计算校验和(checksum)并在数据通过一个不可靠的通道进行传输时再次计算校验和,这样就能发现数据是否损坏。如果计算所得的新校验和与原来的校验和不匹配,我们就认为数据已损坏。但该技术并不能修复数据,它只能检测出数据错误。(这正是不使用低端硬件的原因。具体说来一定要使用ECC内存。)注意,校验和也是可能损坏的,不只是数据,但由于校验和比数据小得多,所以损坏的可能性非常小。常用的错误检测码是CRC-32(循环冗余校验),任何大小的数据输入均计算得到一个32位的整数校验和。Hadoop数据完整性 校验 HDFS会对写入的所有数据计算校验和,并在读取数据时验证校
3、验和。 校验方式 它针对每个由io.bytes.per.checksum指定字节的数据计算校验和。默认情况下为512个字节,由干CRC-32校验和是4个字节,所以存储校验和的额外开销低于1。Hadoop数据校验过程 datanode datanode负责在收到数据后存储该数据及其验证校验和。它在收到客户端的数据或复制其他datanode的数据时执行这个操作。正在写数据的客户端将数据及其校验和发送到由一系列datanode组成的管线,管线中最后一个datanode负责验证校验和。如果datanode检测到错误,客户端便会收到一个ChecksumException异常,它是IOException异
4、常的一个子类,后者应以应用程序特定的方式来处理,比如重试这个操作。 客户端 客户端从datanode读取数据时,也会验证校验和,将它们与datanode中存储的校验和进行比较。每个datanode均持久保存有一个用于验证的校验和日志(persistent log of checksum verification),所以它知道每个数据块的最后一次验证时间。客户端成功验证一个数据块后,会告诉这个datanode,datanode由此更新日志。保存这些统计信息对于检测损坏的磁盘很有价值。Hadoop数据校验 不只是客户端在读取数据块时会验证校验和,每个datanode也会在一个后台线程中运行一个Da
5、taBlockscanner,从而定期验证存储在这个datanode上的所有数据块。该项措施是解决物理存储煤体上位损坏的有力措施。 由于HDFS存储着每个数据块的复本(replica),因此它可以通过数据复本来修复损坏的数据块,进而得到一个新的、完好无损的复本。基本思路是:客户端在读取数据块时,如果检测到错误,首先向namenode报告已损坏的数据块及其正在尝试读操作的这个datanode,再抛出checksumException异常。namenode将这个数据块复本标记为已损坏,因此,它不会将处理请求直接发送到这个节点,或尝试将这个复本复制到另一个datanode。之后,它安排这个数据块的一
6、个复本复制到另一个datanode,如此一来,数据块的复本因子(replication factor)又回到期望水平。此后,已损坏的数据块复本便被删除。LocalFileSystem Hadoop的LocalFileSystem执行客户端的校验和验证。这意味着在你写入一个名为filename的文件时,文件系统客户端会明确地在包含每个文件块校验和的同一个目录内新建一个名为filename.crc的隐藏文件。就像HDFS一样,文件块的大小由属性io.bytes.per.checksum控制,默认为512个字节。文件块的大小作为元数据存储在crc文件中,所以即使文件块大小的设置已经发生变化,仍然可以
7、正确读回文件。在读取文件时需要验证校验和,并且如果桧测到错误,LocalFileSystem还会抛出一个checksumException异常。校验文件LocalFileSystem 校验和的计算代价是相当低的(在Java中,它们是用本地代码实现的),一般只是增加少许额外的读写文件时间。对大多数应用来说,付出这样的额外开销以保证数据完整性是可以接受的。 也可以禁用校验和计算,特别是在底层文件系统本身就支持校验和的时候。在这种情况下,使用RawLocalFilesystem替代LocalFilesystem。 要想在一个应用中实现全局校验和验证,需要将fs.file.impl属性设置为org.a
8、pache.hadoop.fs.RawLcalFilesystem进而实现对文件URI的重新映射。还有一个可选方案可以直接新建一个RawLocalFileSystem实例。如果你想针对一些读操作禁用校验和,这个方案非常有用。LocalFileSystem 通过Hadoop LocalFileSystem向本地文件系统写入带有校验的文件:利用LocalFileSystem构建本地文件,构建成功后会添加.crc文件获取校验文件信息运行结果LocalFileSystem 通过Hadoop LocalFileSystem向读取该文件时即可实现校验功能,如果校验失败,将会抛出异常ChecksumFile
9、System LocalFileSystem通过ChecksumFilesystem来完成自己的任务,有了这个类,向其他文件系统(无校验和系统)加入校验和就非常简单,因为ChecksumFilesystem类继承自Filesystem类。 一般用法如下:FileSystem rawFs = FileSystem checksummedFs = new ChecksumFileSystem(rawFs);构建一个原生的不带有校验的文件系统接口对象ChecksumFileSystem 源文件系统 底层文件系统称为“源”(raw)文件系统,可以使用ChecksumFileSystem实例的 getR
10、awFileSystem() 方法获取它。ChecksumFileSystem类还有其他一些与校验和有关的有用方法,比如上一个案例中的getChecksumFile()可以获得任意一个文件的校验和文件路径。 校验处理 如果ChecksumFileSystem类在读取文件时检测到错误,会调用自己的reportChecksumFailure()方法。默认实现为空方法,但LocalFileSystem类会将这个出错的文件及其校验和移到同一存储设备上一个名为bad_files的边际文件夹(side directory)中。管理员应定期检查这些坏文件并采取相应的行动。压缩 文件压缩有两大好处 减少存储文
11、件所需要的磁盘空间 加速数据在网络和磁盘上的传输 这两大好处在处理大量数据时相当重要Hadoop压缩 有很多种不同的压缩格式、工具和算法,它们各有千秋: DEFLATE是一个标准压缩算法。标准实现是zlib。没有可用于生成DEFLATE文件的常用命令行工具,因为通常都用gzip格式。gzip文件格式只是在DEFLATE格式上增加了文件头和一个文件尾。.deflate文件扩展名是Hadoop约定的。压缩格式工具算法文件扩展名是否可切分DEFLATE无DEFLATE.deflate否GzipgzipDEFLATE.gz否bzip2bzip2bzip2.bz2是LZOlzopLZO.lzo否LZ4无
12、LZ4.lz4否Snappy无Snappy.snappy否Hadoop压缩 所有压缩算法都需要权衡空间时间:压缩和解压缩速度更快,其代价通常是只能节省少量的空间。 压缩工具都提供9个不同的选项来控制压缩时必须考虑的权衡:选项-1为优化压缩速度,-9为优化压缩空间。 例如,下述命令通过最快的压缩方法创建一个名为file.gz的压缩文件:gzip -1 fileHadoop压缩 不同压缩工具有不同的压缩特性。gzip是一个通用的压缩工具,在空间时间性能的权衡中,居于其他两个压缩方法之间。bzip2的压缩能力强于gzip,但压缩速度更慢一点。尽管bzip2的解压速度比压缩速度快,但仍比其他压缩格式要
13、慢一些。另一方面,LZO、LZ4和Snappy均优化压缩速度,其速度比gzip快一个数量级,但压缩效率稍逊一筹。Snappy和LZ4的解压缩速度比LZO高出很多 “是否可切分”列表示对应的压缩算法是否支持切分(splitable),也就是说,是否可以搜索数据流的任意位置并进一步往下读取数据。可切分压缩格式尤其适合MapReduce。codec codec实现了一种压缩一解压缩算法。 在Hadoop中,一个对CompressionCodec接口的实现代表一个codec。例如,GzipCodec包装了gzip的压缩和解压缩算法。 以下列举了Hadoop实现的codec。压缩格式Hadoop Com
14、pressionCodecDEFLATEpress.DefaultCpress.GzipCpress.Bzip2CodecLZOpress.LzopCodecLZpress.Lz4CodecSpress.SnappyCodec对数据流进行压缩和解压缩 CompressionCodec包含两个函数,可以轻松用于压缩和解压缩数据。 createOutputStream(OutputStream out) 如果要对写入输出数据流的数据进行压缩,可用createOutputStream(OutputStream out)方法在底层的数据流中对需要以压缩格式写入在此之前尚未压缩的数据新建一个Compre
15、ssionOutputStream对象。 createlnputStream(InputStream in) 对输入数据流中读取的数据进行解压缩的时候,则调用createlnputStream(InputStream in)获取CompressionlnputStream,可通过该方法从底层数据流读取解压缩后的数据。对数据流进行压缩和解压缩 CompressionOutputStream和CompressionlnputStream,类似于java.util.zip.DeflaterOutputStream和 java.util.zip.DeflaterInputStream,只不过前两者能够
16、重置其底层的压缩或解压缩方法,对于某些将部分数据流(Section of Data Stream)压缩为单独数据块(Bock)的应用-例如SequenceFile,这个能力是非常重要的。数据压缩 以下的代码展示了如何将原有的MapReduce输入文件内容写入一个压缩后的文件中:写入压缩文件创建Gzip Codec对象将矩形分区排序案例的输入数据内容写入压缩文件构建本地文件接口并创建输出流运行结果文件创建成功打开压缩文件压缩包包含的文件打开文件写入的矩形宽、高信息写入压缩文件运行结果压缩文件的使用 对于大型文件,不要对整个文件使用不支持分割的压缩格式,因为这样会损失本地性优势,从而使降低MapReduce应用的性能。 输入的文件的压缩 如果输入的文件是压缩过的,那么在被MapReduce读取时,它们会被自动解压,根据文件扩展名来决定应该使用哪一个压缩解码器。 MapReduce作业的输出的压缩 如果要压缩MapReduce作业的输出,请在作业配置文件中将press属性设置为true。将pression.codec属性设置为自己打算使用的压缩编码/解码器的类名。压缩文件的使用 map作业输