快乐学习
前程无忧、中华英才非你莫属!

Hadoop系统IO详解

一、通过distcp并行复制(hadoop系统之间的高级复制技术

前面的HDFS访问模型都集中于单线程的访问。例如通过指定文件通配,我们可以对一部分文件进行处理,但是为了高效,对这些文件的并行处理需要新写一个程序。Hadoop有一个叫distcp(分布式复制)的有用程序,能从Hadoop的文件系统并行复制大量数据

      应用场景: distcp一般用于在两个HDFS集群中传输数据。如果集群在Hadoop的同一版本上运行,就适合使用hdfs方案:

        实战命令: % hadoop distcp hdfs://namenode1/foo  hdfs://namenode2/bar

这将从第一个集群中复制/foo目录(和它的内容)到第二个集群中的/bar目录下,所以第二个集群会有/bar/foo目录结构。如果/bar不存在,则新建一个。我们可以指定多个源路径,并且所有的都会被复制到目标路径。源路径必须是绝对路径。

默认情况下,distcp会跳过目标路径已经有的文件,但可以通过提供的-overwrite选项进行覆盖。也可以用-update选项来选择只更新那些修改过的文件。

注意:使用-overwrite和-update中任意一个(或两个)选项会改变源路径和目标路径的含义。这可以用一个例子清楚说明。如果改变先前例子中第一个集群的子树/foo下的一个文件,就能通过运行对第二个集群的改变进行同步:

% hadoop distcp -update hdfs://namenode1/foo hdfs://namenode2/bar/foo

目标路径需要末尾这个额外的子目录/foo,因为源目录下的内容已被复制到目标目录下。(如果熟悉rsync,你可以想像-overwrite或-update项对源路径而言,如同添加一个隐含的斜杠。)

如果对discp操作不是很确定,最好先对一个小的测试目录树进行尝试

有很多选项可以控制分布式复制行为,包括预留文件属性,忽略故障和限制复制的文件或总数据的数量。运行时不带任何选项,可以看到使用说明。

distcp是作为一个MapReduce作业执行的,复制工作由集群中并行运行的map来完成。这里并没有reducer。每个文件都由一个单一的map进行复制,并且distcp通过将文件分成大致相等的文件来为每个map数量大致相同的数据。

map的数量是这样确定的。通过让每一个map复制数量合理的数据以最小化任务建立所涉及的开销,是一个很好的想法,所以每个map的副本至少为256 MB。(除非输入的总大小较少,否则一个map就足以操控全局。)例如,1 GB的文件会被分成4个map任务。如果数据很大,为限制带宽和集群的使用而限制映射的数量就变得很有必要。map默认的最大数量是每个集群节点(tasktracker)有20个。例如,复制1000 GB的文件到一个100个节点的集群,会分配2000个map(每个节点20个map),所以平均每个会复制512 MB。通过对distcp指定-m参数,会减少映射的分配数量。例如,-m 1000会分配1000个map,平均每个复制1 GB。

如果想在两个运行着不同版本HDFS的集群上利用distcp,使用hdfs协议是会失败的,因为RPC系统是不兼容的。想要弥补这种情况,可以使用基于HTTP的HFTP文件系统从源中进行读取。这个作业必须运行在目标集群上,使得HDFS RPC版本是兼容的。使用HFTP重复前面的例子:

% hadoop distcp hftp://namenode1:50070/foo hdfs://namenode2/bar

注意,需要在URI源中指定名称节点的Web端口。这是由dfs.http.address的属性决定的,默认值为50070。

保持HDFS集群的平衡

向HDFS复制数据时,考虑集群的平衡相当重要。文件块在集群中均匀地分布时,HDFS能达到最佳工作状态。回顾前面1000 GB数据的例子,通过指定-m选项为1,即由一个单一的map执行复制工作,它的意思是,不考虑速度变慢和未充分利用集群资源,每个块的第一个副本会存储在运行map的节点上(直到磁盘被填满)。第二和第三个副本分散在集群中,但这一个节点并不会平衡。通过让map的数量多于集群中节点的数量,我们便可避免这个问题。鉴于此,最好首先就用默认的每个节点20个map这个默认设置来运行distcp。

然而,这也并不总能阻止一个集群变得不平衡。也许想限制map的数量以便一些节点可以被其他作业使用。若是这样,可以使用balancer工具(参见第10章)继续改善集群中块的分布.

二、Hadoop存档(解决hadoop系统处理小文件的缺点

       概念:通过工具合并多个文件为一个大文件为存档文件。

       目标:减少大量的小文件耗尽namenode内存中大部分的内存。

 

       比较容易混淆的概念:例如:一个1MB的文件已大小为128MB的块存储,使用的是1MB的磁盘空间 ,而不是128MB.

      2.1 通过archive方式创建HAR文件。

     

        存档实战命令:%>hadoop archive  -archiveName  files.har  /my/files  /my (需要在MapReduce集群上使用它)

        files.har:存档文件的名称 。       /my/files:输入    /my :输出

       让我们看看这个存档文件时怎么创建的:

% hadoop fs-ls / my

Found 2 items

drwxp-xp-x tom supergroup 0 2017-03-11 19 13 /my/files

dpwxr-xr-x tom supergroup 0 2017-03-11 9 1913 /my/files. Har

% hadoop fs-ls / my/files. Har

Found 3 items

-rw-r--r-_10 tom supepgroup  2017-03-11 19 13 /my/files.har/_index

-rw-r--r--10 tom supergroup   2017-03-11 19 13 /my/files.har/_masterindex

-rw-r-_r-_1 tom supergroup  2017-03-11 19 13 /my/files.har/part-0

这个目录列表显示了HAR文件的组成部分两个索引文件以及部分文件的集合。

的集合——本例中只有一个。

引用HAR文件(两种方式):hadoop fs  -lsr har:///my/files.har/my/files/dir

                                       hadoop fs  -lsr har://hdfs-localhost:8020/my/files.har/my/files/dir

 

         删除HAR文件:hadoop fs -rmr /my/files.har

  

  2.2  Hadoop解决小文件总结:

对于小文件问题,Hadoop本身也提供了几个解决方案,分别为:Hadoop Archive,Sequence file和CombineFileInputFormat。

(1) Hadoop Archive

hadoop Archive或者HAR,是一个高效地将小文件放入HDFS块中的文件存档工具,它能够将多个小文件打包成一个HAR文件,这样在减少namenode内存使用的同时,仍然允许对文件进行透明的访问。

使用HAR时需要两点,第一,对小文件进行存档后,原文件并不会自动被删除,需要用户自己删除;第二,创建HAR文件的过程实际上是在运行一个mapreduce作业,因而需要有一个hadoop集群运行此命令。

该方案需人工进行维护,适用管理人员的操作,而且har文件一旦创建,Archives便不可改变,不能应用于多用户的互联网操作。

(2) Sequence file

sequence file由一系列的二进制key/value组成,如果为key小文件名,value为文件内容,则可以将大批小文件合并成一个大文件。

Hadoop-0.21.0中提供了SequenceFile,包括Writer,Reader和SequenceFileSorter类进行写,读和排序操作。

该方案对于小文件的存取都比较自由,不限制用户和文件的多少,但是SequenceFile文件不能追加写入,适用于一次性写入大量小文件的操作。

(3)CombineFileInputFormat

CombineFileInputFormat是一种新的inputformat,用于将多个文件合并成一个单独的split,另外,它会考虑数据的存储位置。

三、Hadoop的IO操作篇

       

Hadoop自带一套原子操作用于数据I/O。其中一些技术,如数据完整性保持和压缩,对于处理多达数个TB的数据时,特别值得关注。另外一些Hadoop工具或API,所形成的构建模块可用于开发分布式系统,比如序列化操作和on-disk数据结构。

本篇的内容主要有以下几点:

(1)通过检验和保证数据完整性

      

1、在数据的流转过中,HDFS通过“校验和”,来检验数据完整性,如果发现损坏,则新建一个replica,删除损坏的部分,是数据块的复本保持在期望的水平。

2、datanode节点本身也会在一个后台线程中运行一个DataBlockScanner,从而定期验证本节点的所有数据块。

3、Hadoop的LocalFileSystem执行客户端的校验和验证,在写入数据时,会新建一个名为.filename.crc的文件,用于校验

4、如果底层文件系统本身已经有了校验机制,则可以使用一个不需要检验的文件系统RawLocalFileSystem:

       

(2)Hadoop压缩

     文件压缩有两大好处,减少存储文件书所需要的磁盘空间,并加速数据在网络和磁盘上的传输。

     在处理大数据的时候,选择一款合适的压缩算法是非常重要的!

  

使用哪种压缩格式与具体应用相关。是希望运行速度最快,还是更关注降低存储开销?通常,需要为应用尝试不同的策略,并且为应用构建一套测试标准,从而找到最理想的压缩格式。

对于巨大、没有存储边界的文件,如日志文件,可以考虑如下选项:

     1、存储未经压缩的文件

     2、使用支持切分的存储格式,如bzip2

     3、在应用中切分文件成块,然后压缩。这种情况,需要合理选择数据库的大小,以确保压缩后数据近似HDFS块的大小

     4、使用顺序文件(Sequence File),它支持压缩和切分

     5、使用一个Avro数据文件,改文件支持压缩和切分,就像顺序文件一样,但增加了许多编程语言都可读写的优势

          对于大文件来说,不应该使用不支持切分整个文件的压缩格式,否则将失去数据的本地特性,进而造成MapReduce应用效率低下。

     (3)Hadoop序列化-Writable

    

序列化,是将结构化对象转换为字节流,以便传输或存储。反序列化,是指字节流转回结构化对象的逆过程。

序列化在分布式数据处理的两大领域经常出现:进程间通信和永久存储。

Hadoop使用自己的序列化格式Writable,它格式紧凑,速度快,但很难用Java以外的语言进行扩展或使用。因为Writable是Hadoop的核心,大多数MapReduce程序的键和值都会使用它。

为什么不用Java Object Serialization?

Doug Cutting这样解释:“为什么开始设计Hadoop的时候我不用Java Serialization?因为它看起来太复杂,而我认为需要有一个非常精简的机制,可以用于精确控制对象的读和写,因为这个机制是Hadoop的核心。使用Java Serialization后,虽然可以获得一些控制权,但用起来非常纠结。不用RMI也处于类似的考虑。高效、高性能的进程间通信是Hadoop的关键。我觉得我们需要精确控制连接、延迟和缓冲的处理方式,然而RMI对此无能为力。”

Doug认为Java序列化不满足序列化的标准:精简、快速、可扩展、互操作。

精简:Writable不把类名写到数据流,它假设客户端知道会收到什么类型,结果是这个格式比Java序列化更加精简,同时支持 随机存取和访问,因为流中的每一条记录均独立于其他记录。

高效:Writable对象可以(并且通常)重用,对于MapRe作业(主要对只有几个类型的大量对象进行序列化和反序列化),不需要为新建对象分配空间而得到的存储节省是非常可观的

   (4)Hadoop顺序文件-即文件序列化

              顺序文件,即流式文件,二进制文件。Hadoop开发了一组对象,来处理顺序文件。

 

   (5)Avro

Apache Avro是一个独立于编程语言的数据序列化框架。该项目是由Doug Cutting创建的,旨在解决Hadoop中Writable类型的不足:缺乏语言的可移植性。

       本篇不介绍这个框架,可以参阅官方网址:http://avro.apache.org 。

  

     HadoopIO概念详解: http://blog.csdn.net/puma_dong/article/details/24173333   -----来源于Hadoop权威指南

        

      

      Hadoop 源码阅读之io篇: http://blog.csdn.net/burningsheep/article/details/8162139  -----来源CSDN--Hadoop专题

     

打赏
赞(0) 打赏
未经允许不得转载:同乐学堂 » Hadoop系统IO详解

特别的技术,给特别的你!

联系QQ:1071235258QQ群:710045715

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

error: Sorry,暂时内容不可复制!