Hive表小文件治理方案

13 篇文章 1 订阅
7 篇文章 1 订阅
@Author  : Spinach | GHB
@Link    : http://blog.csdn.net/bocai8058

小文件是如何产生的?

  1. Reduce个数越多,产生的小文件越多;
  2. 写入hive表时,以动态分区(set hive.exec.dynamic.partition=true)形式写入时,会产生大量的小文件;
  3. 数据源本身就包含众多小文件;

为什么要治理小文件?

  1. 从Hive的角度看,小文件会开很多map,一个map开一个JVM去执行,所以这些任务的初始化,启动,执行会浪费大量的资源,严重影响性能。
  2. 从HDFS的角度看,小文件太多,会导致namenode元数据对象多,占用更多的内存,从而制约了集群的扩展。

Hive的小文件治理方案

HDFS中文件的存储是以文件块(block)的形式存储在DataNode中的,block块位置信息等元数据信息是存储在namenode中的,在实际生产中,一般block块的大小设置为256MB。具体关于block块疑问,可参考《HDFS Block块大小限定依据及原则》

  1. 设置以下参数:
## 设置map输入合并小文件的相关参数
set mapred.max.split.size=256000000;
set mapred.min.split.size.per.node=100000000;
set mapred.min.split.size.per.rack=100000000;
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

## 设置map输出和reduce输出进行合并的相关参数
set hive.merge.mapfiles=true;
set hive.merge.mapredfiles=true;
set hive.merge.size.per.task=256000000;
set hive.merge.smallfiles.avgsize=256000000;
  1. 少用动态分区,用时记得按distribute by rand() 将数据随机分配给Reduce,这样可以使得每个Reduce处理的数据大体一致,例如:
insert overwrite table tableName partition(date) select * from person DISTRIBUTE BY (rand()*3);
  1. 针对于ORC格式存储的表,可使用concatenate命令对指定分区进行小文件合并,例如:
alter table tableName_orc partition (date="20200101") concatenate;
  • 仅仅适用于ORC格式存储的表;
  • 使用concatenate命令合并小文件时不能指定合并后的文件数量,虽然可以多次执行该命令,但显然不够优雅。当多次使用concatenate后文件数量不在变化,这个跟参数mapreduce.input.fileinputformat.split.minsize=256mb的设定有有有关,可设定每个文件的最小size,具体见链接
  • 只能针对分区使用concatenate命令。

Spark的小文件治理方案

  1. 添加参数 .config("spark.sql.adaptive.enabled", "true")
  2. 添加repartition操作或coalesce操作;
  3. 添加sql hint暗示(/*+ REPARTITION(分区数) */),例如:
create table tableName as select /*+ REPARTITION(10) */ age,name from person where date='20200101'
insert into table tableName select /*+ REPARTITION(10) */ age,name from person where date='20200101'
insert overwrite table tableName select /*+ REPARTITION(10) */ age,name from person where date='20200101'
注意:分区数的设置根据落地数据量而定
  1. 少用动态分区,用时记得按distribute by rand() 将数据随机分配给Reduce,这样可以使得每个Reduce处理的数据大体一致,例如:
insert overwrite table tableName partition(date) select * from person DISTRIBUTE BY rand()

对已存在的小文件治理方案

  1. 设置与【Hive的小文件治理方案】中1相同的参数;
  2. 使用hadoop archive命令把小文件进行归档;
  3. 重建表,建表时减少reduce数量;
  4. 重新读取表中数据,重新控制写入文件数,如:spark.table(dwdTableName).where(s"""statis_date='$statis_date'""").coalesce(5).distinct().write.mode(SaveMode.Overwrite).insertInto(dwdTableName)

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值