Hive如何处理大量小文件

Hive如何处理大量小文件,第1张

1.动态分区插入数据的时候,会产生大量的小文件,从而导致map数量的暴增

2.数据源本身就包含有大量的小文件

3.reduce个数越多,生成的小文件也越多

1 从HIVE角度来看的话呢,小文件越多,map的个数也会越多,每一个map都会开启一个JVM虚拟机,每个虚拟机都要创建任务,执行任务,这些流程都会造成大量的资源浪费,严重影响性能

2 在HDFS中,每个小文件约占150byte,如果小文件过多则会占用大量的内存。这样namenode内存容量严重制约了集群的发展

4.1 使用Hadoop achieve把小文件进行归档

4.2 重建表,建表时减少reduce的数量

4.3 通过参数调节,设置map/reduce的数量

4.3.1设置map输入合并小文件的相关参数:

4.3.2 设置map输出和reduce输出进行合并的相关参数:

1.当分区过多且数据很大时,可以使用严格模式,避免出发一个大的mapreduce任务。当分区数量过多且数据量较大时,执行宽范围的数据扫描会触发一个很大的mapreduce任务。在严格模式下,当where中没有分区过滤条件时会禁止执行。

2.hive如果有过多的分区,由于底层是存储在HDFS上,HDFS上只用于存储大文件 而非小文件,因为过多的分区会增加namenode的负担。

3.hive会转化为mapreduce,mapreduce会转化为多个task。过多小文件的话,每个文件一个task,每个task一个JVM实例,JVM的开启与销毁会降低系统效率。

1、列裁剪和分区裁剪

2、谓词下推

3、sort by 替换order by 

4、group by 代替distinct

5、group by 配置调整

map 端预聚合:set hive.map.aggr=true set hive.groupby.mapaggr.checkinterval=100000

倾斜均衡配置项:set hive.groupby.skewindate=true

6、join优化

6.1 大小表,小表前置

6.2 多表Join时key相同

6.3 利用mapjoin特性

6.4 分桶表 mapjoin

6.5 倾斜均衡配置项:

设置hive.optimize.skewjoin=true,开启后,在join过程中hive会将计数超过阈值hive.skewjoin.key(默认100000)的倾斜key对应的行临时写进文件中,然后再启动另一个job做map join生成结果。通过hive.skewjoin.mapjoin.map.task参数还可以控制第二个job的mapper数量,默认10000.

6.7 优化sql处理join数据倾斜

6.7.1、空值或无意义的值:若不需要空值数据,就提前写到where语句过滤掉,如果需要保留的话,将空值key用随机方式打散。

6.7.2、单独处理倾斜key

6.7.3、不同数据类型,join的关联字段类型不一样,导致耗时长,所以需要注意做类型转换(join关联字段,一个是int,一个是string,,计算key的hash值时默认时int类型做的,这样导致所有真正的string类型的key都分配到一个reducer上了)

6.7.4、mapjoin的小表比较大的时候,,无法直接使用mapjoin,则 select/*+mapjoin(b)*/  from  a left join ( select /*+mapjoin (b)*/ from b inner join a )

6.8、mapreduce 优化

6.8.1、调整mapper数

mapper数量与输入文件的split数息息相关。如果想减少mapper数,就适当提高mapred.min.split.size,split数就减少了;如果想增大mapper数,除了降低maperd.min.split.size之外,也可以提高mapred.map.task;一般来讲,如果输入文件是少量大文件,就减少mapper数;如果是大量非小文件,就增大mapper数,如果是小文件,就喝吧小文件

6.8.2 调整reducer数

使用参数mapred.reduce.task可以直接设定reducer数量,如果不设置的话,hive会自行推测,推测逻辑如下:

参数hive.exec.reducers.bytes.per.reducer.设定每个reducer能够处理的最大的数据量,默认时1G

参数hive.exec.reducers.max设定每个job的最大的reducer数量,默认时999或者1009

得到reducer数:reducers_num=min(total_input_size/reducers.bytes.per.reducer,reducers.max)

reducer数量与输出文件的数量相关,如果reducer数太多,会产生大量小文件,对hdfs造成压力,如果reducer数太少,每个reducer要处理很多数据,容易拖慢运行时间或造成oom

6.8.3 合并小文件

输入阶段合并:需要更改hive的输入文件格式,即参数hive.input.format,默认值是org.apache.hadoop.hive.ql.io.hiveiputformat,我们该成org.apache.hadoop.hive.ql.io.combinehiveinputformat.

这样比调整mapper数时,又多出两个参数,分别是mapred.min.split.size.per.node和mapred.min.split.size.per.rack,含义是单节点和单机架上的最小split大小。如果发现又split大小小于这两个默认值100MB,则会进行合并

输出阶段合并:直接将hive.merge.mapfiles和hive.merge.mapredfiles都设置为true即可。

hive.merge.mapfiles表示将map-only任务的输出合并

hive.merge.mapredfiles表示将map-reduce任务的输出合并

另外hive.merge.size.per.task可以指定每个task输出后合并文件大小的期望值

hive.merge.size.smallfiles.avgsize可以指定所有输出文件大小的均值阈值,默认时1G

6.9 启用压缩

压缩job的中间结果数据和输出数据,可以少量CPU时间节省出很多空间。压缩方式一般选择snappy,效率最高,要启用中间压缩,需要设定:

hive.exec.compress.intermediate为true,同时指定压缩方式hive.intermediate.compression.code为org.apache.hadoop.io.compress.snappycode.

另外,参数hive.intermediate.compression.type可以选对块block还是对记录record压缩,block压缩率比较高,输出压缩的配置基本相同:打开hive.exec.compress.output

6.10 jvm重用

在mr job中,默认时每执行一个task就会启动一个jvm,如果task非常小而且碎,那么jvm启动和关闭耗时都会比较长。可以通过调节参数mapred.job.reuse.jvm.num.task来重用。例如将这个参数设置为5,那么久代表同一个mr job中顺序执行的5各task可以重复使用一个jvm,减少启动和关闭开销,但是他对不同mr job的task无效

6.11 采用合适的存储格式

6.12 数据倾斜

数据倾斜原因:1、join 倾斜 2、聚合倾斜

group by 倾斜: group by 字段中某个字段的值过多,导致处理这个值得reduce耗时很久

解决方法:set hive.map.aggr=true  -- 表示开启map端聚合

set hive.groupby.skewindata=true  注意:只能对单个字段聚合 , 生成两个map job ,第一个map job中map输出结果随机分布到reduce中,每个reduce做部分聚合 *** 作,并输出结果,这样相同的groub key有可能被分发到不同的reduce中,从而达到负载均衡的目的;第二个map job再根据预处理的数据结果按照group by key分布到reduce中,这个过程可以保证相同的key被分到同一个reduce中,最后完成最终的聚合 *** 作

6.13 优化in、exists语句

使用left semi join 替换in 、exists

6.14 合并 mapreduce *** 作

multi-group by 是hive的一个非常好的特性,它使得hive中利用中间结果变更非常方便

例如:

from ( select a.status,b.school from status_update a join profilees b on (a.userid=b.suerid)) subq1

insert overwirte table a1 partition(ds='2021-03-07') 

select subq1.school,count(1) group by subq1.school

insert overwrite table b1 partition(ds='2021-03-07')

select subq1.status,count(1) group by subq1.status

上述语句使用了multi-group by特性联系group by 2次数据,使用不同的group by key,这一特性可以减少一次mapreduce *** 作


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12113105.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存