当前位置:   article > 正文

hive--小文件问题_hive 文件大小

hive 文件大小

小文件如何产生

  • hive的底层存储是HDFS,默认的块大小是128M,通常小于默认块大小,HDFS默认也算一个block, 所以产生小文件主要有以下几种:
    • 1、数据源本身就包含有大量的小文件。
    • 2、使用spark/flink实时写hive时,根据业务的时间窗口(10s,20s)落地hive表,产生很多小文件。
    • 3、采用动态分区也会产生很多小文件。
    • 4、reduce的个数输出。默认reduce个数和落地hive文件个数一样。

小文件带来的影响

  • 1、从Hive的角度看,小文件会开很多map,一个map开一个JVM去执行,所以这些任务的初始化,启动,执行会浪费大量的资源,严重影响性能。
  • 2、HDFS存储太多小文件, 会导致namenode元数据特别大, 占用太多内存, 查询效率降低。
    • HDFS的文件元信息,包括位置、大小、分块信息等,都是保存在NameNode的内存中的。每个对象大约占用150个字节,因此一千万个文件及分块就会占用约3G的内存空间,一旦接近这个量级,NameNode的性能就会开始下降了。

解决方案

已有的小文件

  • 1.使用hadoop archive命令把小文件进行归档。
#用来控制归档是否可用
set hive.archive.enabled=true;
#通知Hive在创建归档时是否可以设置父目录
set hive.archive.har.parentdir.settable=true;
#控制需要归档文件的大小
set har.partfile.size=1099511627776;

#使用以下命令进行归档
ALTER TABLE srcpart ARCHIVE PARTITION(ds='2021-09-08', hr='12');

#对已归档的分区恢复为原文件
ALTER TABLE srcpart UNARCHIVE PARTITION(ds='2021-09-08', hr='12');

#::注意,归档的分区不能够INSERT OVERWRITE,必须先unarchive

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 2.重建表,建表时减少reduce数量。
set mapred.reduce.tasks=100; -- 设置reduce数量
  • 1

小文件的产生途径

  • 参数设置
-- 每个Map最大输入大小(这个值决定了合并后文件的数量)
set mapred.max.split.size=256000000;
-- 一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
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;
-- ===设置map输出和reduce输出进行合并的相关参数:
 
-- 设置map端输出进行合并,默认为true
set hive.merge.mapfiles = true;
-- 设置reduce端输出进行合并,默认为false
set hive.merge.mapredfiles = true;
-- 设置合并文件的大小
set hive.merge.size.per.task = 134217728;
 
-- 当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。
set hive.merge.smallfiles.avgsize=16000000;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 少用动态分区,使用distribute by分区
--设置作业优先级(VERY_HIGH,HIGH,NORMAL,LOW)
set mapred.job.priority = NORMAL;
--开启中间压缩(map输出结果压缩)
set hive.exec.compress.intermediate = true;
--在Map-Reduce的任务结束时合并小文件
set hive.merge.mapfiles=true;
set hive.merge.mapredfiles = true;
--合并文件的大小,设置为块大小的两倍256M
set hive.merge.size.per.task = 134217728;
--当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge
set hive.merge.smallfiles.avgsize=134217728;
-- orc的表同时需要下面两个,其它文件可以去掉
set hive.exec.orc.default.block.size=134217728;
set hive.merge.orcfile.stripe.level=false;
-- 设置读写并发
set hive.support.concurrency=false;
set hive.support.quoted.identifiers=none;
 
 
insert overwrite table ${hivevar:item_table} partition (dt='${hivevar:item_date}')
select `(dt)?+.+`
from ${hivevar:item_table}
where dt='${hivevar:item_date}'
distribute by rand();
 
--程序解读: 使用distribute by rand() 自动产生shuffle, 将数据随机分配给reduce,避免出现较大文件。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 使用sequencefile作为表存储形式,不要使用textfile,在一定程度上可以减少小文件

参考

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/728045
推荐阅读
相关标签
  

闽ICP备14008679号