hadoop面对大量的小文件处理

小文件在HDFS中

 HDFS块大小默认是128m(hadoop2.x默认是128),若是存储了很多这种小文件每个小文件占了一个block而每个block的文件,目录在namenode里以对像(元数据)形式存储,

就会造成namenode内存占用严重,同时 阅读小文件通常会导致从一个DataNode到DataNode检索每个小文件检索效率极低

在MapReduce中小文件问题

一个Map任务每次能处理一个块的输入,多个小文件对应多个block就需要大量的map任务

解决方法:Hadoop本身提供了几个解决方案,分别为:Hadoop Archive,Sequence file和CombineFileInputFormat
(1) Hadoop Archive
Hadoop Archive或者HAR,是一个高效地将小文件放入HDFS块中的文件存档工具,它能够将多个小文件打包成一个HAR文件,这样在减少namenode内存使用的同时,仍然允许对文件进行透明的访问。
对某个目录/foo/bar下的所有小文件存档成/outputdir/ zoo.har:
hadoop archive -archiveName zoo.har -p /foo/bar /outputdir
当然,也可以指定HAR的大小(使用-Dhar.block.size)。
HAR是在Hadoop file system之上的一个文件系统,因此所有fs shell命令对HAR文件均可用,只不过是文件路径格式不一样,HAR的访问路径可以是以下两种格式:
har://scheme-hostname:port/archivepath/fileinarchive
har:///archivepath/fileinarchive(本节点)
可以这样查看HAR文件存档中的文件:
hadoop dfs -ls har:///user/zoo/foo.har
输出:
har:///user/zoo/foo.har/hadoop/dir1
har:///user/zoo/foo.har/hadoop/dir2
使用HAR时需要两点,第一,对小文件进行存档后,原文件并不会自动被删除,需要用户自己删除;第二,创建HAR文件的过程实际上是在运行一个mapreduce作业,因而需要有一个hadoop集群运行此命令。
此外,HAR还有一些缺陷:第一,一旦创建,Archives便不可改变。要增加或移除里面的文件,必须重新创建归档文件。第二,要归档的文件名中不能有空格,否则会抛出异常,可以将空格用其他符号替换(使用-Dhar.space.replacement.enable=true 和-Dhar.space.replacement参数)。
(2) Sequence file(2.x整合为createWriter)
sequence file由一系列的二进制key/value组成,如果为key小文件名,value为文件内容,则可以将大批小文件合并成一个大文件。
Hadoop-0.21.0中提供了SequenceFile,包括Writer,Reader和SequenceFileSorter类进行写,读和排序操作。如果hadoop版本低于0.21.0的版本,实现方法可参见[3]。
(3)CombineFileInputFormat
CombineFileInputFormat是一种新的inputformat,用于将多个文件合并成一个单独的split,另外,它会考虑数据的存储位置

此外:在数据处理的最前端(预处理、采集)就将小文件合并为大文件然后再上传到hdfs
已经是大量的小文件在HDFS中了,可以使用另一种inputformat来做切片(CombineFileInputformat),它的切片逻辑跟FIleinputformat不同:
它可以将多个小文件从逻辑上规划到一个切片中,这样,多个小文件就可以交给一个maptask了

你可能感兴趣的:(大数据,hadoop)