【示例】对某个目录/foo/bar下的所有小文件存档成/outputdir/zoo.har:
hadoop archive -archiveName foo.har -p /foo/bar /outputdir
当然,也可以指定HAR的大小(使用-Dhar.block.size)。
HAR是在Hadoop file system之上的一个文件系统,因此所有fs shell命令对HAR文件均可用,只不过是文件路径格式不一样,HAR的访问路径可以是以下两种格式:
# scheme-hostname格式为hdfs-域名:端口,如果没有提供scheme-hostname,它会使用默认的文件系统。这种情况下URI是这种形式:
har://scheme-hostname:port/archivepath/fileinarchive
har:///archivepath/fileinarchive
可以这样查看HAR文件存档中的文件:
hdfs 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参数)。
- 不支持修改
- Sequence file由一系列的二进制key/value组成,如果为key小文件名,value为文件内容,则可以将大批小文件合并成一个大文件。
- Hadoop-0.21.0中提供了SequenceFile,包括Writer,Reader和SequenceFileSorter类进行写,读和排序操作。如果hadoop版本低于0.21.0的版本。
和 HAR 不同的是,这种方式还支持压缩。该方案对于小文件的存取都比较自由,不限制用户和文件的多少,但是 SequenceFile 文件不能追加写入,适用于一次性写入大量小文件的操作。也是不支持修改的。
4)开启JVM重用CombineFileInputFormat是一种新的inputformat,用于将多个文件合并成一个单独的split,在map和reduce处理之前组合小文件。
有小文件场景时开启JVM重用;如果没有产生小文件,不要开启JVM重用,因为会一直占用使用到的task卡槽,直到任务完成才释放。
JVM重用可以使得JVM实例在同一个job中重新使用N次,N的值可以在Hadoop的mapred-site.xml文件中进行配置。通常在10-20之间。
<property>
<name>mapreduce.job.jvm.numtasks</name>
<value>10</value>
<description>How many tasks to run per jvm,if set to -1 ,there is no limit</description>
</property>
5)合并本地的小文件,上传到 HDFS(appendToFile )
6)合并 HDFS 的小文件,下载到本地(getmerge)将本地的多个小文件,上传到 HDFS,可以通过 HDFS 客户端的 appendToFile 命令对小文件进行合并。
三、HDFS小文件问题处理实战操作1)通过Hadoop Archive(HAR)方式进行合并小文件可以通过 HDFS 客户端的 getmerge 命令,将很多小文件合并成一个大文件,然后下载到本地。
在本地准备2个小文件:
cat >user1.txt<<EOF
1,tom,male,16
2,jerry,male,10
EOF
cat >user2.txt<<EOF
101,jack,male,19
102,rose,female,18
EOF
将文件put上hdfs
hdfs dfs -mkdir -p /foo/bar
hdfs dfs -put user*.txt /foo/bar/
进行合并
# 【用法】hadoop archive -archiveName 归档名称 -p 父目录 [-r <复制因子>] 原路径(可以多个) 目的路径
# 合并/foo/bar目录下的文件,输出到/outputdir
hadoop archive -archiveName user.har -p /foo/bar /outputdir
# 执行该命令后,原输入文件不会被删除,需要手动删除
hdfs dfs -rm -r /foo/bar/user*.txt
查看 yarn 任务:http://local-168-182-110:8088/
查看har文件
# 查看har合并文件
hdfs dfs -ls /outputdir/user.har
hdfs dfs -ls ///outputdir/user.har
hdfs dfs -ls hdfs://local-168-182-110:8082/outputdir/user.har
# 查看har里的文件
hdfs dfs -ls har:/outputdir/user.har
hdfs dfs -ls har:///outputdir/user.har
hdfs dfs -ls har://hdfs-local-168-182-110:8082/outputdir/user.har