sparksql运算调优纪事(一)——hive小文件处理

业务目的

全量离线运算统计,结果写入oracle

依赖版本

spark 2.0.1
hive 1.1.0

问题

  1. 执行时task数量过多
  2. hive动态分区小文件过多
  3. 测试环境5运算节点,内存分别为12G,运行30万测试数据不断发生内存溢出问题

逐步调优

1、执行时task数量过多,总数达到了108000个,OMG,每个任务都是内存溢出,因为是用sparksql读hive表,所以spark的spark.default.parallelism强制指定task数并没有用,考虑–conf spark.sql.shuffle.partitions=30,在查询hive on hbase外部表时有效,但遇到hive分区表无效,此外考虑通过spark中repartition来处理,但是sparksql原始查询还是会根据hive分区表的情况开启task,问题定位到hive分区表。

2、目前是将数据动态分区,执行insert overwrite,产生了大量小文件
hive小文件
如图可以看到小文件数量达到100个,而且大小都不到10K,这样一方面对于namenode来说维护成本过高,另一方面在对hive分区表全量数据进行运算清洗时,消耗巨大,导致task数极其不合理。

处理方式:

set mapred.max.split.size=256000000;
set mapred.min.split.size.per.node=100000000;
set mapred.min.split.size.per.rack=100000000;
set mapred.reduce.tasks=20;
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
set hive.map.aggr=true;
set hive.groupby.mapaggr.checkinterval=100000;
set hive.merge.mapfiles = true;
set hive.merge.mapredfiles = true;
set hive.merge.size.per.task=256000000;
set hive.merge.smallfiles.avgsize=16000000;
set hive.exec.reducers.bytes.per.reducer=5120000000;
set hive.exec.reducers.max = 888;
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
  • hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;-使用Combinefileinputformat,将多个小文件打包作为一个整体的inputsplit,减少map任务数

  • hive.map.aggr=true //用于设定是否在 map 端进行聚合,默认值为真

  • hive.groupby.mapaggr.checkinterval=100000 //用于设定 map
    端进行聚合操作的条目数,根据具体情况设置

  • hive.merge.mapfiles = true #在Map-only的任务结束时合并小文件

  • hive.merge.size.per.task = 256000000 #合并文件的大小

  • hive.merge.smallfiles.avgsize=16000000
    #当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge,根据具体情况设置

    扫描二维码关注公众号,回复: 8774771 查看本文章
  • hive.exec.reducers.bytes.per.reducer=5120000000;
    输出文件大小,根据具体情况设置

  • hive.exec.reducers.max = 888 每个任务最大的reduce数,默认为999

  • mapred.reduce.tasks = 20; reduce task任务数

随后执行需要的动态分区语句

insert overwrite table part_table
partition(a,b)
SELECT
  xxxx
FROM unpart_table
 where xxxxx
DISTRIBUTE BY rand();

文件数
3、通过处理hive分区小文件数,使得map操作减少从而使得task任务大幅度减少,spark执行过程中不再发生溢出问题。

后记

在排查过程中还发现,之前有使用

set hive.enforce.bucketing = true;

强制分桶会导致分区文件被细化为更小的文件,使得各种合并配置无效。

发布了25 篇原创文章 · 获赞 22 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/fzuzhanghao1993/article/details/100775661