HDFS小文件是指文件远远小于HDFS配置的block文件大小的文件。在HDFS上中block的文件目录数、或增删改查操作等都是存储在内存中,以对象的方式存储,每个对象约占150byte。若大量的小文件存储占用一个block,则会占用大量NameNode内存。而集群存储文件的多少,由NameNode管理,
常见方案
- 小文件上传时合并上传
- Hadoop Archive方式
- Sequence file方式
小文件上传时合并上传
将本地的小文件合并,上传到HDFS
本地存在多个小文件,需要上传到HDFS,HDFS的appendToFile命令可以实现多个本地文件合并上传HDFS。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| cd /home/hadoop
[hadoop@node01 ~]$ cat world1.txt aaa bbb ccc ddd eee fff hhh [hadoop@node01 ~]$ cat world.txt aaa bbb ccc ddd eee fff hhh
[hadoop@node01 ~]$ hdfs dfs -appendToFile world1.txt world.txt /tmp/world.txt
[hadoop@node01 ~]$ hdfs dfs -cat /tmp/world.txt aaa bbb ccc ddd eee fff hhh aaa bbb ccc ddd eee fff hhh
|
下载HDFS的小文件到本地,合并成一个大文件
HDFS 存在多个小文件,下载合并到本地生成一个大文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| [hadoop@node01 ~]$ hdfs dfs -mkdir /baihe [hadoop@node01 ~]$ hdfs dfs -copyFromLocal world.txt /baihe [hadoop@node01 ~]$ hdfs dfs -copyFromLocal world1.txt /baihe
[hadoop@node01 ~]$ hdfs dfs -getmerge /baihe/ local_largefile.txt
[hadoop@node01 ~]$ ll 总用量 12 -rw-r--r--. 1 hadoop hadoop 56 5月 30 14:45 local_largefile.txt -rw-rw-r--. 1 hadoop hadoop 28 5月 27 01:32 world1.txt -rw-rw-r--. 1 hadoop hadoop 28 5月 27 01:29 world.txt [hadoop@node01 ~]$ tail -f -n 200 local_largefile.txt aaa bbb ccc ddd eee fff hhh aaa bbb ccc ddd eee fff hhh
|
合并HDFS上的小文件
1
| [hadoop@node01 ~]$ hdfs dfs -cat /baihe/* | hdfs dfs -appendToFile - /tmp/hdfs_largefile.txt
|
特殊说明:此类型处理方法,数据量非常大的情况下可能不太适合,最好使用MapReduce来合并。
Hadoop Archive方式
Hadoop Archive或者HAR,是一个高效地将小文件放入HDFS块中的文件存档工具,它能够将多个小文件打包成一个HAR文件,这样在减少namenode内存使用的同时,仍然允许对文件进行透明的访问。
1 2
| [hadoop@node01 ~]$ hadoop archive archive -archiveName <NAME>.har -p <parent path> [-r <replication factor>]<src>* <dest>
|
- -archiveName .har 指定归档后的文件名
- -p 被归档文件所在的父目录
- * 归档的目录结构
- 归档后存在归档文件的目录.
- 可以通过参数
-D har.block.size
指定HAR的大小
创建归档文件
1 2 3 4 5 6 7 8 9 10 11 12
| hadoop fs -lsr /test/in drwxr-xr-x - root supergroup 0 2015-08-26 02:35 /test/in/har drwxr-xr-x - root supergroup 0 2015-08-22 12:02 /test/in/mapjoin -rw-r--r-- 1 root supergroup 39 2015-08-22 12:02 /test/in/mapjoin/address.txt -rw-r--r-- 1 root supergroup 129 2015-08-22 12:02 /test/in/mapjoin/company.txt drwxr-xr-x - root supergroup 0 2015-08-25 22:27 /test/in/small -rw-r--r-- 1 root supergroup 1 2015-08-25 22:17 /test/in/small/small.1 -rw-r--r-- 1 root supergroup 1 2015-08-25 22:17 /test/in/small/small.2 -rw-r--r-- 1 root supergroup 1 2015-08-25 22:17 /test/in/small/small.3 -rw-r--r-- 1 root supergroup 3 2015-08-25 22:27 /test/in/small/small_data
hadoop archive -archiveName 0825.har -p /test/in/ small mapjoin /test/in/har
|
查看归档文件内容
1 2
| hdfs dfs -lsr /test/in/har/myhar.har hdfs dfs -lsr har:///test/in/har/myhar.har
|
解压归档文件
1 2
| hdfs dfs -mkdir -p /test/in/har/myhar.har hdfs dfs -cp har:///test/in/har/myhar.har
|
删除har文件必须使用rmr命令,rm是不行的
1
| hdfs dfs -rmr /test/in/har/myhar.har
|
特殊说明:
- 存档文件的源文件及目录都不会自动删除,需要手动删除
- 存档过程实际是一个MapReduce过程,所以需要hadoop的MapReduce支持,以及启动yarm集群
- 存档文件本身不支持压缩
- 存档文件一旦创建便不可修改,要想从中删除或增加文件,必须重新建立存档文件
- 创建存档文件会创建原始文件的副本,所以至少需要有与存档文件容量相同的磁盘空间
- 使用 HAR 作为MR的输入,MR可以访问其中所有的文件。但是由于InputFormat不会意识到这是个归档文件,也就不会有意识的将多个文件划分到单独的Input-Split中,所以依然是按照多个小文件来进行处理,效率依然不高
Sequence file
sequence file 由一系列的二进制key/value 组成,如果为key 小文件名,value 为文件内容,则可以将大批小文件合并成一个大文件。
CombineFileInputFormat 是一种新的inputformat,用于将多个文件合并成一个单独的split,另外,它会考虑数据的存储位置。