Hive的后端存储是HDFS,它对大文件的处理是非常高效的,如果合理配置文件系统的块大小,NameNode可以支持很大的数据量。但是在数据仓库中,越是上层的表其汇总程度就越高,数据量也就越小。而且这些表通常会按日期进行分区,随着时间的推移,HDFS的文件数目就会逐渐增加。
 
小文件带来的问题
 
关于这个问题的阐述可以读一读Cloudera的这篇文章。简单来说,HDFS的文件元信息,包括位置、大小、分块信息等,都是保存在NameNode的内存中的。每个对象大约占用150个字节,因此一千万个文件及分块就会占用约3G的内存空间,一旦接近这个量级,NameNode的性能就会开始下降了。
 
此外,HDFS读写小文件时也会更加耗时,因为每次都需要从NameNode获取元信息,并与对应的DataNode建立连接。对于MapReduce程序来说,小文件还会增加Mapper的个数,每个脚本只处理很少的数据,浪费了大量的调度时间。当然,这个问题可以通过使用CombinedInputFile和JVM重用来解决。
 
Hive小文件产生的原因
 
前面已经提到,汇总后的数据量通常比源数据要少得多。而为了提升运算速度,我们会增加Reducer的数量,Hive本身也会做类似优化——Reducer数量等于源数据的量除以hive.exec.reducers.bytes.per.reducer所配置的量(默认1G)。Reducer数量的增加也即意味着结果文件的增加,从而产生小文件的问题。
解决小文件的问题可以从两个方向入手:
1. 输入合并。即在Map前合并小文件
2. 输出合并。即在输出结果的时候合并小文件
 
配置Map输入合并
 
-- 每个Map最大输入大小,决定合并后的文件数
set mapred.max.split.size=256000000;
-- 一个节点上split的至少的大小 ,决定了多个data node上的文件是否需要合并
set mapred.min.split.size.per.node=100000000;
-- 一个交换机下split的至少的大小,决定了多个交换机上的文件是否需要合并
set mapred.min.split.size.per.rack=100000000;
-- 执行Map前进行小文件合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 
 
配置Hive结果合并
 
我们可以通过一些配置项来使Hive在执行结束后对结果文件进行合并:
 
hive.merge.mapfiles 在map-only job后合并文件,默认true
hive.merge.mapredfiles 在map-reduce job后合并文件,默认false
hive.merge.size.per.task 合并后每个文件的大小,默认256000000
hive.merge.smallfiles.avgsize 平均文件大小,是决定是否执行合并操作的阈值,默认16000000
 
Hive在对结果文件进行合并时会执行一个额外的map-only脚本,mapper的数量是文件总大小除以size.per.task参数所得的值,触发合并的条件是:
根据查询类型不同,相应的mapfiles/mapredfiles参数需要打开;
结果文件的平均大小需要大于avgsize参数的值。
示例:
 
-- map-red job,5个reducer,产生5个60K的文件。
create table dw_stage.zj_small as
select paid, count (*)
from dw_db.dw_soj_imp_dtl
where log_dt = '2014-04-14'
group by paid;
-- 执行额外的map-only job,一个mapper,产生一个300K的文件。
set hive.merge.mapredfiles= true;
create table dw_stage.zj_small as
select paid, count (*)
from dw_db.dw_soj_imp_dtl
where log_dt = '2014-04-14'
group by paid;
-- map-only job,45个mapper,产生45个25M左右的文件。
create table dw_stage.zj_small as
select *
from dw_db.dw_soj_imp_dtl
where log_dt = '2014-04-14'
and paid like '%baidu%' ;
-- 执行额外的map-only job,4个mapper,产生4个250M左右的文件。
set hive.merge.smallfiles.avgsize=100000000;
create table dw_stage.zj_small as
select *
from dw_db.dw_soj_imp_dtl
where log_dt = '2014-04-14'
and paid like '%baidu%' ;
 
压缩文件的处理
对于输出结果为压缩文件形式存储的情况,要解决小文件问题,如果在Map输入前合并,对输出的文件存储格式并没有限制。但是如果使用输出合并,则必须配合SequenceFile来存储,否则无法进行合并,以下是示例:
 
set mapred.output.compression. type=BLOCK;
set hive.exec.compress.output= true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.LzoCodec;
set hive.merge.smallfiles.avgsize=100000000;
drop table if exists dw_stage.zj_small;
create table dw_stage.zj_small
STORED AS SEQUENCEFILE
as select *
from dw_db.dw_soj_imp_dtl
where log_dt = '2014-04-14'
and paid like '%baidu%' ;
 
使用HAR归档文件
 
Hadoop的归档文件格式也是解决小文件问题的方式之一。而且Hive提供了原生支持:
 
set hive.archive.enabled= true;
set hive.archive.har.parentdir.settable= true;
set har.partfile.size=1099511627776;
ALTER TABLE srcpart ARCHIVE PARTITION(ds= '2008-04-08', hr= '12' );
ALTER TABLE srcpart UNARCHIVE PARTITION(ds= '2008-04-08', hr= '12' );
 
如果使用的不是分区表,则可创建成外部表,并使用har://协议来指定路径。
 
来源:https://blog.csdn.net/yycdaizi/article/details/43341239

hive小文件合并设置参数的更多相关文章

  1. Hive merge(小文件合并)

    当Hive的输入由非常多个小文件组成时.假设不涉及文件合并的话.那么每一个小文件都会启动一个map task. 假设文件过小.以至于map任务启动和初始化的时间大于逻辑处理的时间,会造成资源浪费.甚至 ...

  2. hive优化之小文件合并

    文件数目过多,会给HDFS带来压力,并且会影响处理效率,可以通过合并Map和Reduce的结果文件来消除这样的影响: set hive.merge.mapfiles = true ##在 map on ...

  3. Hive小文件处理

    小文件是如何产生的: 动态分区插入数据的时候,会产生大量的小文件,从而导致map数量的暴增 数据源本身就包含有大量的小文件 reduce个数越多,生成的小文件也越多 小文件的危害: 从HIVE角度来看 ...

  4. 数仓面试高频考点--解决hive小文件过多问题

    本文首发于公众号:五分钟学大数据 小文件产生原因 hive 中的小文件肯定是向 hive 表中导入数据时产生,所以先看下向 hive 中导入数据的几种方式 直接向表中插入数据 insert into ...

  5. 彻底解决Hive小文件问题

    最近发现离线任务对一个增量Hive表的查询越来越慢,这引起了我的注意,我在cmd窗口手动执行count操作查询发现,速度确实很慢,才不到五千万的数据,居然需要300s,这显然是有问题的,我推测可能是有 ...

  6. HDFS操作及小文件合并

    小文件合并是针对文件上传到HDFS之前 这些文件夹里面都是小文件 参考代码 package com.gong.hadoop2; import java.io.IOException; import j ...

  7. Hadoop MapReduce编程 API入门系列之小文件合并(二十九)

    不多说,直接上代码. Hadoop 自身提供了几种机制来解决相关的问题,包括HAR,SequeueFile和CombineFileInputFormat. Hadoop 自身提供的几种小文件合并机制 ...

  8. Hadoop经典案例(排序&Join&topk&小文件合并)

    ①自定义按某列排序,二次排序 writablecomparable中的compareto方法 ②topk a利用treemap,缺点:map中的key不允许重复:https://blog.csdn.n ...

  9. MR案例:小文件合并SequeceFile

    SequeceFile是Hadoop API提供的一种二进制文件支持.这种二进制文件直接将<key, value>对序列化到文件中.可以使用这种文件对小文件合并,即将文件名作为key,文件 ...

随机推荐

  1. 使用dbms_profiler收集存储过程每步执行时间

    最近和优化团队的专家学到一个很有意义的内置包:dbms_profiler,专门用于分析Oracle存储过程中的各段代码的时间开销情况,从而快速找到性能瓶颈的步骤. 1.sys创建dbms_profil ...

  2. 001-ADO.NET

    Web.config <connectionStrings> <add name="connStr" connectionString="server= ...

  3. git冲突管理

    Diff 查看工作区(working directory)和暂存区(staged)之间差异:git diff 查看工作区(working directory)与当前仓库版本(repository)HE ...

  4. 记录心得-shiro框架demo示例

    从懵懂到了解,再到熟悉,是一个进步的过程! 先撸代码,跑起来看效果,再做详细的介绍,开始干活! 1,先列出工程目录结构,自己需要创建对应层级的程序和相关配置文件. 2,导入maven依赖的jar包.打 ...

  5. WebSphere应用程序更新方式

    在日常的使用中,一个javaee程序部署以后,以后续的使用中会有模块等的更新,但我经常见到有人直接更新服务器上的类包,文件等,(可能是tomcat,jboss这种热部署使用惯了)这样子的方式有几个问题 ...

  6. 2017.11.27 变量进阶与LED矩阵

    局部变量:函数内部声明的变量,只在函数内部有效. 全部变量:在函数外部声明的变量,全局都有效,直到程序执行完毕. 全局变量负作用: 1.降低函数的独立性 2.降低函数的通用性,不利于函数的重复调用. ...

  7. 《linux 必读》

    1. linux 内核设计与实现 2. 深入理解 linux 内核

  8. rabbitMQ Management http://localhost:15672/ 打不开

    C:\RabbitMQ Server\rabbitmq_server-3.7.7\sbin>rabbitmq-plugins enable rabbitmq_management 安装rabbi ...

  9. MIUI系统如何获取ROOT权限

    MIUI系统有么好方法启用了Root超级权限?各位都清楚,Android手机有Root超级权限,一旦手机启用了root相关权限,就能够实现更多的功能,举例子,各位公司的营销部门的同事,使用大多数营销工 ...

  10. C++ 屏幕录制

    http://www.pudn.com/Download/item/id/1584698.html task.renwuyi.com