Hive小文件合并研究

背景

Hive query将运算好的数据写回hdfs(比如insert into语句),有时候会产生大量的小文件,如果不采用CombineHiveInputFormat就对这些小文件进行操作的话会产生大量的map task,耗费大量集群资源,而且小文件过多会对namenode造成很大压力。所以Hive在正常job执行完之后,会起一个conditional task,来判断是否需要合并小文件,如果满足要求就会另外启动一个map-only job 或者mapred job来完成合并

参数解释

hive.mergejob.maponly (默认为true)

如果hadoop版本支持CombineFileInputFormat,则启动Map-only job for merge,否则启动  MapReduce merge job,map端combine file是比较高效的做法

hive.merge.mapfiles(默认为true)

正常的map-only job后,是否启动merge job来合并map端输出的结果

hive.merge.mapredfiles(默认为false)

正常的map-reduce job后,是否启动merge job来合并reduce端输出的结果,建议开启

hive.merge.smallfiles.avgsize(默认为16MB)

如果不是partitioned table的话,输出table文件的平均大小小于这个值,启动merge job,如果是partitioned table,则分别计算每个partition下文件平均大小,只merge平均大小小于这个值的partition。这个值只有当hive.merge.mapfiles或hive.merge.mapredfiles设定为true时,才有效

hive.exec.reducers.bytes.per.reducer(默认为1G)

更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/database/extra/

如果用户不主动设置mapred.reduce.tasks数,则会根据input directory计算出所有读入文件的input summary size,然后除以这个值算出reduce number

reducers = (int) ((totalInputFileSize + bytesPerReducer - 1) / bytesPerReducer);

reducers = Math.max(1, reducers);

reducers = Math.min(maxReducers, reducers);

hive.merge.size.per.task(默认是256MB)

merge job后每个文件的目标大小(targetSize),用之前job输出文件的total size除以这个值,就可以决定merge job的reduce数目。merge job的map端相当于identity map,然后shuffle到reduce,每个reduce dump一个文件,通过这种方式控制文件的数量和大小

MapredWork work = (MapredWork) mrTask.getWork();

if (work.getNumReduceTasks() > 0) {

int maxReducers = conf.getIntVar(HiveConf.ConfVars.MAXREDUCERS);

int reducers = (int) ((totalSize +targetSize - 1) / targetSize);

reducers = Math.max(1, reducers);

reducers = Math.min(maxReducers, reducers);

work.setNumReduceTasks(reducers);

}

mapred.max.split.size(默认256MB)

mapred.min.split.size.per.node(默认1 byte)

mapred.min.split.size.per.rack(默认1 byte)

这三个参数CombineFileInputFormat中会使用,Hive默认的InputFormat是CombineHiveInputFormat,里面所有的调用(包括最重要的getSplits和getRecordReader)都会转换成CombineFileInputFormat的调用,所以可以看成是它的一个包装。CombineFileInputFormat 可以将许多小文件合并成一个map的输入,如果文件很大,也可以对大文件进行切分,分成多个map的输入。一个CombineFileSplit对应一个map的输入,包含一组path(hdfs路径list),startoffset, lengths, locations(文件所在hostname list)mapred.max.split.size是一个split 最大的大小,mapred.min.split.size.per.node是一个节点上(datanode)split至少的大小,mapred.min.split.size.per.rack是同一个交换机(rack locality)下split至少的大小通过这三个数的调节,组成了一串CombineFileSplit用户可以通过增大mapred.max.split.size的值来减少Map Task数量

结论

hive 通过上述几个值来控制是否启动merge file job,通常是建议大家都开启,如果是一堆顺序执行的作业链,只有最后一张表需要固化落地,中间表用好就删除的话,可以在最后一个insert into table之前再开启,防止之前的作业也会launch merge job使得作业变慢。

上周还发现目前启动的针对RCFile的Block Merger在某种少见情况下,会生成duplicated files,Hive代码中本身已经考虑到这点,所以会在Merger Task RCFileMergeMapper的JobClose函数中调用Utilities.removeTempOrDuplicateFiles(fs, intermediatePath, dpCtx),  不过不知道为什么没有生效,还会存在重复文件,需要再研究下

Hive是否起merge job是由conditional task在运行时决定的,如果hadoop job或者hive未如预期般执行合并作业,则可以利用github上的file crush工具完成合并,它的原理也是启动一个mapreduce job完成合并,不过目前只支持textfile 和 sequencefile

链接地址:https://github.com/edwardcapriolo/filecrush

时间: 2024-10-03 07:55:19

Hive小文件合并研究的相关文章

MapReduce将小文件合并成大文件,并设置每个切片的大小的案例

测试代码: package cn.toto.bigdata.combinefile; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.NullWritable; import org.apach

swift 小文件合并

问题描述 swift中针对大文件有切割,对小文件(1MB以内)没有优化处理.我想通过合并相关小文件,优化小文件存取.但不知道可行性方面是否合适.求助于大家! 解决方案

Hdspace分布式机构知识库系统的小文件存储

Hdspace分布式机构知识库系统的小文件存储 卞艺杰 陈超  李亚冰 陆小亮 机构知识库作为一种新型的学术交流模式和开放获取活动的绿色通道已逐渐成为国内外图书情报界关注的新焦点, 随着机构库的发展其数据规模也在不断扩大,  传统的存储模式已经不能满足日益增长的存储需求. 在对机构库内容存储特点的研究基础上建立基于 HDFS与Dspace 的分布式机构库 Hdspace.  首先提出一种小文件合并生成新的存储文件,  并对文件提出基于学科分类的两级索引,  结合索引预缓存机制提高小文件的读取响应

转 海量小文件存储与Ceph实践

海量小文件存储(简称LOSF,lots of small files)出现后,就一直是业界的难题,众多博文(如[1])对此问题进行了阐述与分析,许多互联网公司也针对自己的具体场景研发了自己的存储方案(如taobao开源的TFS,facebook自主研发的Haystack),还有一些公司在现有开源项目(如hbase,fastdfs,mfs等)基础上做针对性改造优化以满足业务存储需求: 一. 通过对若干分布式存储系统的调研.测试与使用,与其它分布式系统相比,海量小文件存储更侧重于解决两个问题: 1.

Hadoop MapReduce处理海量小文件:自定义InputFormat和RecordReader

一般来说,基于Hadoop的MapReduce框架来处理数据,主要是面向海量大数据,对于这类数据,Hadoop能够使其真正发挥其能力.对于海量小文件,不是说不能使用Hadoop来处理,只不过直接进行处理效率不会高,而且海量的小文件对于HDFS的架构设计来说,会占用NameNode大量的内存来保存文件的元数据(Bookkeeping).另外,由于文件比较小,我们是指远远小于HDFS默认Block大小(64M),比如1k~2M,都很小了,在进行运算的时候,可能无法最大限度地充分Locality特性带

基于Hadoop的云盘系统客户端技术难点之三 小文件存储优化

作者:张子良 版权所有,转载请注明出处. 一.概述 首先明确概念,这里的小文件是指小于HDFS系统Block大小的文件(默认64M),如果使用HDFS存储大量的小文件,将会是一场灾难,这取决于HDFS的实现机制和框架结构,每一个存储在HDFS中的文件.目录和块映射为一个对象存储在NameNode服务器内存中,通常占用150个字节.如果有1千万个文件,就需要消耗大约3G的内存空间.如果是10亿个文件呢,简直不可想象.这里需要特别说明的是,每一个小于Block大小的文件,存储是实际占用的存储空间仍然

mapreduce关于大量小文件的优化策略

在分布式的架构中,分布式文件系统HDFS,和分布式运算程序编程框架mapreduce. HDFS:不怕大文件,怕很多小文件 mapreduce :怕数据倾斜 那么mapreduce是如果解决多个小文件的问题呢? mapreduce关于大量小文件的优化策略 (1) 默认情况下,TextInputFormat对任务的切片机制是按照文件规划切片,不管有多少个小文件,都会是单独的切片,都会交给一个maptask,这样,如果有大量的小文件 就会产生大量的maptask,处理效率极端底下 (2)优化策略 最

基于Hadoop的海量小文件存储方法的研究

基于Hadoop的海量小文件存储方法的研究 时倩 方睿 岳亮 彭榆峰 随着科学技术的发展,各行业及领域需要处理的数据呈爆炸式增长.Hadoop是大文件存储处理的理想平台,但Hadoop在处理海量小文件时的表现并不令人满意.本文首先对HDFS的系统架构作了简要介绍,进而分析了HDFS处理海量小文件时存在的问题,最后介绍了目前国内外对该问题提出的优化方案. 基于Hadoop的海量小文件存储方法的研究

Node.js实现JS文件合并小工具_node.js

临近春节,项目结束了,没事情做,于是就想学学node.js,之前写了一个是为了实验室项目的需要,用c#写了个js代码压缩合并的小插件,后来想到可以用node重构,于是就练练手吧,下面小编直接给大家上代码了. 代码如下所示: /*符合CommonJs规范*/ var writePath = 'min.js',/*默认输出到本目录min.js文件里*/ fs = require('fs'), r1 = /^(.+)$/mg,/*分行*/ r2 = /\s{2,}/g,/*去空格*/ r3 = /([