hadoop处理小文件问题
2015-04-22 16:45
169 查看
本文转自个人原创blog: http://www.javali.org/document/hadoop-handle-numerous-small-files.html
Hadoop带来了廉价的处理大数据的能力,可以这么理解,hadoop是为了解决大数据(大文件)计算而出现的分布式计算框架,不过对于小文件(指远小于block size,默认64M)却会存在各种问题,比如:过多的消耗namenode的内存(一个文件在namenode会占用150Bytes内存,如果存在海量小文件,必然会超出计算机存储的极限);另外计算时启动过多的Map Tasks,占用过多资源以至于降低计算效率。
有时由于业务需要,Hadoop不可避免的会存储大量的小文件,我有一个分时计算的业务,每天会产生24个文件;纠结的是,计算当前小时数据依赖所有的历史数据,而实际上每个文件不到1M大小,Job会为每一个文件启动一个Map task,而每 一个 map task都仅仅处理了非常小的 数据,我们都知道,Map Task都需要消耗一定的资源。随着时间推移,每次运行Job启动的Map tasks越来越多,运行效率也随之降低。
这张截图就是我的Job优化前的执行状态,它启动了2273个Map tasks,整个Map阶段耗时4分多钟,完成Job计算需要7分钟,对于实时性的计算需求,这种计算耗时是很不理想的
我们知道了问题在哪里,如何解决呢?
幸运的是,由于这类问题存在的普遍性,hadoop引入了archives即HAR files(0.18.0版),使用方法可以看这里。
接下来我们做个测试,看Hadoop archives能否解决我们面临的问题。
第一步: 我们把2012-11-01一天共计24个文件打包成HAR文件,放置到/tmp目录
hadoop archive -archiveName smallFiles.har -p /user/hive/warehouse/promotion_hour_bind/dt=2012-11-01/hour=*/tmp/
第二步:写一个最简单的MapReduce测试程序
上面这个程序只有一个空的Map函数,我们只需要测试打har包前后启动的Map tasks数,不需要任何其他的逻辑。接下来把类打成jar包(javali.jar)上传到服务器
第三步,测试未打archive的源文件,看执行情况
hadoop jar ./javali.jar org.javali.mr.test.TestSmallFiles /user/hive/warehouse/promotion_hour_bind/dt=2012-11-01/*/* /tmp/result0
运行后通过可视化界面查看Job执行状态,如下截图
我们可以看到启动了24个Map tasks,因为这个分区下有24个文件。
第四步,测试archive文件
hadoop jar ./javali.jar org.javali.mr.test.TestSmallFiles /tmp/smallFiles.har /tmp/result1
运行后同样跟踪Job的执行状态
我们看到这次只启动了1个map task,减少了23个Map tasks启动所需的资源
至此,我们不难发现,hadoop archive能很好的解决海量小文件带来的问题:极大的减少了namenode的内存消耗,同时减少了job执行时启动的Map tasks,计算性能得到了极大的提升——优化后的Map耗时降到了1分钟左右。
我们清楚的知道hadoop archive是把物理上的多个小文件抽象成逻辑上的一个文件,实际上海量小文件依然是物理存在的,启动的Map tasks数量虽然减少了,但不可避免的还要多次去获取这些文件,即获取文件的次数没有减少,copy阶段同样会消耗过多的资源。
我们可以把多个文件合并成1个物理文件,前提是不影响业务的处理,可以预想这么做能提升计算效率,同时也引入了风险因素(打har包同样也会),这时候就需要根据实际情况权衡采用何种方案了
『完』
参考: http://blog.cloudera.com/blog/2009/02/the-small-files-problem/
Hadoop带来了廉价的处理大数据的能力,可以这么理解,hadoop是为了解决大数据(大文件)计算而出现的分布式计算框架,不过对于小文件(指远小于block size,默认64M)却会存在各种问题,比如:过多的消耗namenode的内存(一个文件在namenode会占用150Bytes内存,如果存在海量小文件,必然会超出计算机存储的极限);另外计算时启动过多的Map Tasks,占用过多资源以至于降低计算效率。
问题背景
有时由于业务需要,Hadoop不可避免的会存储大量的小文件,我有一个分时计算的业务,每天会产生24个文件;纠结的是,计算当前小时数据依赖所有的历史数据,而实际上每个文件不到1M大小,Job会为每一个文件启动一个Map task,而每 一个 map task都仅仅处理了非常小的 数据,我们都知道,Map Task都需要消耗一定的资源。随着时间推移,每次运行Job启动的Map tasks越来越多,运行效率也随之降低。这张截图就是我的Job优化前的执行状态,它启动了2273个Map tasks,整个Map阶段耗时4分多钟,完成Job计算需要7分钟,对于实时性的计算需求,这种计算耗时是很不理想的
解决办法
我们知道了问题在哪里,如何解决呢?幸运的是,由于这类问题存在的普遍性,hadoop引入了archives即HAR files(0.18.0版),使用方法可以看这里。
接下来我们做个测试,看Hadoop archives能否解决我们面临的问题。
第一步: 我们把2012-11-01一天共计24个文件打包成HAR文件,放置到/tmp目录
hadoop archive -archiveName smallFiles.har -p /user/hive/warehouse/promotion_hour_bind/dt=2012-11-01/hour=*/tmp/
第二步:写一个最简单的MapReduce测试程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class TestSmallFiles { public static class Map extends Mapper<Object, Text, Text, Text> { public void map(Object key, Text value, Context ctx) throws IOException, InterruptedException { } } public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException { Configuration conf = new Configuration(); Job job = new Job(conf, "TestSmallFiles"); job.setJarByClass(TestSmallFiles.class); job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(TextOutputFormat.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); job.setMapperClass(Map.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(Text.class); System.exit(job.waitForCompletion(true) ? 0 : 1); } } |
第三步,测试未打archive的源文件,看执行情况
hadoop jar ./javali.jar org.javali.mr.test.TestSmallFiles /user/hive/warehouse/promotion_hour_bind/dt=2012-11-01/*/* /tmp/result0
运行后通过可视化界面查看Job执行状态,如下截图
我们可以看到启动了24个Map tasks,因为这个分区下有24个文件。
第四步,测试archive文件
hadoop jar ./javali.jar org.javali.mr.test.TestSmallFiles /tmp/smallFiles.har /tmp/result1
运行后同样跟踪Job的执行状态
我们看到这次只启动了1个map task,减少了23个Map tasks启动所需的资源
结论
至此,我们不难发现,hadoop archive能很好的解决海量小文件带来的问题:极大的减少了namenode的内存消耗,同时减少了job执行时启动的Map tasks,计算性能得到了极大的提升——优化后的Map耗时降到了1分钟左右。我们清楚的知道hadoop archive是把物理上的多个小文件抽象成逻辑上的一个文件,实际上海量小文件依然是物理存在的,启动的Map tasks数量虽然减少了,但不可避免的还要多次去获取这些文件,即获取文件的次数没有减少,copy阶段同样会消耗过多的资源。
我们可以把多个文件合并成1个物理文件,前提是不影响业务的处理,可以预想这么做能提升计算效率,同时也引入了风险因素(打har包同样也会),这时候就需要根据实际情况权衡采用何种方案了
『完』
参考: http://blog.cloudera.com/blog/2009/02/the-small-files-problem/
相关文章推荐
- Hadoop关于处理大量小文件的问题和解决方法
- Hadoop关于处理大量小文件的问题和解决方法
- Hadoop关于处理大量小文件的问题和解决方法
- (转载)Hadoop关于处理大量小文件的问题和解决方法
- Hadoop处理大量小文件的问题和解决方法
- Hadoop处理大量小文件的问题和解决方法
- Hadoop关于处理大量小文件的问题和解决方法
- Hadoop关于处理大量小文件的问题和解决方法
- hadoop streaming python 处理 lzo 文件遇到的问题
- Hadoop小文件处理问题
- Hadoop关于处理大量小文件的问题和解决方法
- Hadoop关于处理大量小文件的问题和解决方法
- hadoop streaming python 处理 lzo 文件遇到的问题
- ios系统 ipa文件 打包流程详解 及 常见问题处理
- hadoop2.6.0实践:A01 问题处理 DEPRECATED: Use of this script to execute hdfs command is deprecated.
- hadoop2.6.0实践:A02 问题处理 util.NativeCodeLoader: Unable to load native-hadoop library for your platform
- ini文件全部写入时换行符号未写入的问题处理
- ASP.NET实现从服务器下载文件问题处理
- Hadoop技巧(04):简易处理solr date 时区问题
- Mac环境中搭建Hadoop相关问题及处理办法