MR案例:小文件处理方案
HDFS被设计来存储大文件,而有时候会有大量的小文件生成,造成NameNode资源的浪费,同时也影响MapReduce的处理效率。有哪些方案可以合并这些小文件,或者提高处理小文件的效率呢?
1). 所有HDFS小文件数据导出到本地单个文件后,再存入HDFS
[root@ncst ~]# hadoop fs -ls /test/in/small/
Found items
-rw-r--r-- root supergroup -- : /test/in/small/small.
-rw-r--r-- root supergroup -- : /test/in/small/small.
-rw-r--r-- root supergroup -- : /test/in/small/small.
1.1). 利用hadoop fs -cat或hadoop fs -text命令,将所有内容导出到本地文件,然后put到HDFS即可。如:
[root@ncst test]# hadoop fs -cat /test/in/small/small.* > small_data
[root@ncst test]# hadoop fs -put small_data /test/in/small/
1.2). 或者使用管道:
[root@ncst test]# hadoop fs -cat /test/in/small/small.* | \
> hadoop fs -put - /test/in/small/small_data
最后删除原有文件,注意避免删除新上传的FlumeData1,通过模糊匹配的方式即可
shell> hadoop fs -rm -skipTrash /test/in/small/small.*
总结:
- 这个合并方案适用于文件格式一致,文件合并顺序不敏感(或者按照文件名为序)的场景,例如这里收集的日志信息,每一条都是一样的格式,每一条记录本身有生成时间信息,所以不依赖与在文件中的位置。
- 如果文件中使用数字用于命名,而期望以数字顺序而不是字符串顺序进行合并,会遇到如下问题:-text包含-cat的功能,-cat只能针对平面文件,而-text可以处理压缩(compressed)和顺序(sequence)文件。
- 问题:1,10,100,1000,11,110.将这些数字进行排列。如果按照字符串顺序,是1,10,100,1000,11,110,而我们知道数字的期望顺序是1,10,11,100,110,1000。
- 这里的一个参考方法可以如下:hadoop fs -text [0-9]_fileName.txt [0-9][0-9]_fileName.txt [0-9][0-9[0-9]_fileName.txt | hadoop fs -put – targetFilename.txt 以此类推实现更多位数的数字排序。
- 如果可以的话,使用数字前补零的命名方式(如000009),使得所有文件名称长度一致,可以使得字符顺序与数字的顺序一致。
2). 调用现有API方法 或 自行开发
本质上,这种方案还是先把数据内容读到客户端,再写入到HDFS。
2.1). org.apache.hadoop.fs.FileUtil.copyMerge()方法将指定目录下的所有文件拷贝、合并到一个文件。copyMerge()可以在不同FileSystem中移动,通过deleteSource标识来指定是否删除,如果设定为true,则会删除整个srcDir目录。而conf的传入其实只是为了获取 io.file.buffer.size 的设置。而 addString 则是在合并时,每个文件后添加的字符串。
/** Copy all files in a directory to one output file (merge). */
public static boolean copyMerge(FileSystem srcFS, Path srcDir,
FileSystem dstFS, Path dstFile,
boolean deleteSource,
Configuration conf, String addString) throws IOException {
//检查hdfs上输出路径是否存在
dstFile = checkDest(srcDir.getName(), dstFS, dstFile, false); if (!srcFS.getFileStatus(srcDir).isDirectory())
return false; OutputStream out = dstFS.create(dstFile); try {
FileStatus contents[] = srcFS.listStatus(srcDir);
Arrays.sort(contents);
for (int i = 0; i < contents.length; i++) {
if (contents[i].isFile()) {
InputStream in = srcFS.open(contents[i].getPath());
try {
IOUtils.copyBytes(in, out, conf, false);
if (addString!=null)
out.write(addString.getBytes("UTF-8")); } finally {
in.close();
}
}
}
} finally {
out.close();
}
//是否删除原有文件
if (deleteSource) {
return srcFS.delete(srcDir, true);
} else {
return true;
}
}
2.2). 参考copyMerge()的写法,自定义合并程序。如下例,在本FileSystem中将srcDir下的所有文件写入同一个文件dstFile,而删除则是针对被合并的文件而不是整个目录。
public boolean dirMergeToFile(String srcDir, Path dstFile, boolean deleteSource){
boolean rtcd = true;
try {
Configuration conf = new Configuration();
FileSystem fs = FileSystem. get(conf);
Path sDir = new Path(srcDir);
Path dFile = dstFile;
if (!fs.getFileStatus(sDir).isDirectory()) {
System. out.println(sDir.getName() + " is not a directory!");
return false ;
}
OutputStream out = null;
try {
//排除隐藏的文件,即以.开头。
FileStatus contents[] = fs.listStatus(sDir);
if(contents.length == 0){
return true ;
}
if (fs.exists(dFile)) {
System. out.println(dFile.getName() + " exists!");
return false ;
}
out = fs.create(dFile);
Arrays.sort(contents);
for (int i = 0; i < contents.length; i++) {
if (contents[i].isFile()) {
InputStream in = fs.open(contents[i].getPath());
try {
IOUtils.copyBytes(in, out, conf, false );
} finally {
in.close();
}
if (deleteSource && !fs.delete(contents[i].getPath(), false)) {
rtcd = false;
}
}
}
} finally {
if (out != null)
out.close();
}
return rtcd;
} catch (IOException e) {
System. out.println(e.getMessage());
return false ;
}
}
3). Hadoop自带方案Hadoop Archive
hadoop archive 命令运行MapReduce job来并行处理输入文件,将小文件的内容合并形成少量大文件,然后再利用 index 文件,指出小文件在大文件中所属的坐标,以此来减少小文件的数量。Hadoop Archives生成归档文件格式为HAR。详见解读:Hadoop Archive
4). Sequence File
Sequence File由一系列二进制的键值对组成,其中key为小文件的名字,value的File Content。创建Sequence File的过程可以使用MapReduce Job完成。Sequence Files也是splittable的,所以 MapReduce 可以break them into chunks,并且分别被独立的处理。和HAR不同的是,这种方式还支持压缩。block压缩在许多情况下都是最好的选择,因为它将多个records压缩到一起,而不是一个record一个压缩。详见MR案例:小文件合并SequeceFile
5). CombineFileInputFormat类
CombineFileInputFormat是Hadoop自带的多文件合并处理方案。指定输入目录,将其下的大量小文件进行合并分片,达到减少map任务数量的目的。详细见解读:CombineFileInputFormat类
MR案例:小文件处理方案的更多相关文章
- Hadoop小文件存储方案
原文地址:https://www.cnblogs.com/ballwql/p/8944025.html HDFS总体架构 在介绍文件存储方案之前,我觉得有必要先介绍下关于HDFS存储架构方面的一些知识 ...
- MR案例:小文件合并SequeceFile
SequeceFile是Hadoop API提供的一种二进制文件支持.这种二进制文件直接将<key, value>对序列化到文件中.可以使用这种文件对小文件合并,即将文件名作为key,文件 ...
- Hadoop经典案例(排序&Join&topk&小文件合并)
①自定义按某列排序,二次排序 writablecomparable中的compareto方法 ②topk a利用treemap,缺点:map中的key不允许重复:https://blog.csdn.n ...
- Hadoop案例(六)小文件处理(自定义InputFormat)
小文件处理(自定义InputFormat) 1.需求分析 无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案.将多个小文件合并 ...
- MaxCompute小文件问题优化方案
小文件背景知识 小文件定义 分布式文件系统按块Block存放,文件大小比块大小小的文件(默认块大小为64M),叫做小文件. 如何判断存在小文件数量多的问题 查看文件数量 desc extended + ...
- JAVA实用案例之文件导出(JasperReport踩坑实录)
写在最前面 想想来新公司也快五个月了,恍惚一瞬间. 翻了翻博客,因为太忙,也有将近五个多月没认真总结过了. 正好趁着今天老婆出门团建的机会,记录下最近这段时间遇到的大坑-JasperReport. 六 ...
- 百亿级小文件存储,JuiceFS 在自动驾驶行业的最佳实践
自动驾驶是最近几年的热门领域,专注于自动驾驶技术的创业公司.新造车企业.传统车厂都在这个领域投入了大量的资源,推动着 L4.L5 级别自动驾驶体验能尽早进入我们的日常生活. 自动驾驶技术实现的核心环节 ...
- [大牛翻译系列]Hadoop(17)MapReduce 文件处理:小文件
5.1 小文件 大数据这个概念似乎意味着处理GB级乃至更大的文件.实际上大数据可以是大量的小文件.比如说,日志文件通常增长到MB级时就会存档.这一节中将介绍在HDFS中有效地处理小文件的技术. 技术2 ...
- HDFS小文件处理——Mapper处理
处理小文件的时候,可以通过org.apache.hadoop.io.SequenceFile.Writer类将所有文件写出到一个seq文件中. 大致流程如下: 实现代码: package study. ...
随机推荐
- 170321、Spring+Quartz实现定时任务的配置方法
Quartz是Java版开源定时调度器. 核心概念: Job 表示一个工作,要执行的具体内容.此接口中只有一个方法 void execute(JobExecutionContext context): ...
- CSS样式表、JS脚本加载顺序与SpringMVC在URL路径中传参数与SpringMVC 拦截器
CSS样式表和JS脚本加载顺序 Css样式表文件要在<head>中先加载,这样网页显示时可以第一次就渲染出正确的布局和样式,网页就不会闪烁,或跳变 JS脚本尽可能放在<body> ...
- POJ 2374 Fence Obstacle Course(线段树+动态规划)
Fence Obstacle Course Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 2524 Accepted: ...
- HDU_5534_Partial Tree
Partial Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)To ...
- linux查看硬件信息的方法
目前会Linux的人不少,但是精通的不多,怎样才能做一个符合企业需求的Linux人才,首先要有良好的Linux基础知识.本文为你讲解Linux的知识,今天所讲的是 Linux硬件信息怎样查看,希望你能 ...
- remote tomcat monitor---jmc--jvisualvm
http://mspring.org/article/1229----------jmc http://doorgods.blog.163.com/blog/static/78547857201481 ...
- 转:Java并发编程与技术内幕:线程池深入理解
版权声明:本文为博主林炳文Evankaka原创文章,转载请注明出处http://blog.csdn.net/evankaka 目录(?)[+] ); } catch (InterruptedExcep ...
- CGI/FastCGI/mod_php工作原理
先了解一下普通cgi的工作流程:web server收到用户请求,并把请求提交给cgi程序,cgi程序根据请求提交的参数作相应处理,然后输出标准的html语句返回给web server,web ser ...
- react native 或 flutter 开发app
react-native react native和原生Android/ios: https://www.oschina.net/news/97466/should-we-use-react-nati ...
- AntiSamy测试
AntiSamy为owasp针对xss提供的处理库,可以配置xml策略来决定过滤的内容,比如标签.属性.css等,自定义策略给开发人员使用成本比较高,AntiSamy也提供了几个内置的策略,其安全级别 ...