Hive调优——合并小文件

目录

一、小文件产生的原因

二、小文件的危害

三、小文件的解决方案

3.1 小文件的预防

3.1.1 减少Map数量

 3.1.2 减少Reduce的数量

3.2 已存在的小文件合并

3.2.1 方式一:insert overwrite (推荐)

 3.2.2 方式二:concatenate

 3.2.3 方式三:使用hive的archive归档

3.2.4 方式四:hadoop getmerge

一、小文件产生的原因

  • 数据源本身就包含大量的小文件,例如api,kafka消息管道等。
  • 动态分区插入数据的时候,会产生大量的小文件,从而导致map数量剧增;;
  • reduce 数量越多,小文件也越多,小文件数量=ReduceTask数量*分区数;
  • hive中的小文件是向 hive 表中导入数据时产生;

向 hive 中导入数据的几种方式:

(1)直接向表中插入数据

insert into table t_order2 values (1,'zhangsan',88),(2,'lisi',61);

     这种方式每次插入时都会产生一个小文件,多次插入少量数据就会出现多个小文件,故这种方式生产环境基本不使用;

(2)通过load方式加载数据

-- 导入文件
load data local inpath "/opt/module/hive_data/t_order.txt" overwrite into table t_order;
-- 导入文件夹
load data local inpath "/opt/module/hive_data/t_order" overwrite into table t_order;

     使用 load方式可以导入文件或文件夹,当导入一个文件时,hive表就有一个文件,当导入文件夹时,hive表的文件数量为文件夹下所有文件的数量;

(3)通过查询方式加载数据

insert overwrite t_order  select oid,uid from t_order2

   这种方式是生产环境中经常用的,也是最容易产生小文件的方式。insert 导入数据时会启动MR任务,MR-reduce的个数与输出文件个数一致。

    因此,hdfs的文件数量=  reduceTask数量* 分区数,有些fetch本地抓取任务(例如:简单的 select * from tableA)仅有map阶段,那此时文件个数 = mapTask数量*分区数

二、小文件的危害

        小文件通常是指文件大小要比HDFS块大小(一般是128M)还要小很多的文件。

  • NameNode在内存中维护整个文件系统的元数据镜像、其中每个HDFS文件元数据信息(位置、大小、分块等)对象约占150字节,如果小文件过多会占用大量内存,会直接影响NameNode性能。相对的,HDFS读写小文件也会更加耗时,因为每次都需要从NameNode获取元信息,并与对应的DataNode建立pipeline连接。

  • 从 Hive 角度看,一个小文件会开启一个 MapTask,一个 MapTask开一个 JVM 去执行,这些任务的启动及初始化,会浪费大量的资源,严重影响性能。

三、小文件的解决方案

   小文件的解决思路主要有两个方向:1.小文件的预防;2.已存在的小文件合并

3.1 小文件的预防

     通过调整参数进行合并,在 hive 中执行 insert overwrite  tableA select xx  from tableB 之前设置如下合并参数,即可自动合并小文件。

3.1.1 减少Map数量

         在Map前进行输入合并,从而减少mapper任务的数量。

  • 设置map输入时的合并参数:
#执行Map前进行小文件合并
#CombineHiveInputFormat底层是 Hadoop的 CombineFileInputFormat 方法
#此方法是在mapper中将多个文件合成一个split切片作为输入
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; -- 默认


#每个Map最大的输入大小(这个值决定了合并后文件的数量)
set mapred.max.split.size=256*1000*100;   -- 256M
#一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
set mapred.min.split.size.per.node=100*100*100;  -- 100M
#一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)
set mapred.min.split.size.per.rack=100*100*100; -- 100M
  • 设置map端输出时和reduce端输出时的合并参数:
#设置map端输出进行合并,默认为true
set hive.merge.mapfiles = true;
#设置reduce端输出进行合并,默认为false
set hive.merge.mapredfiles = true;
#设置合并文件的大小
set hive.merge.size.per.task = 256*1000*1000;   -- 256M
#当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge
set hive.merge.smallfiles.avgsize=16000000;   -- 16M
  • 启用压缩(小文件合并后,也可以选择启用压缩)
# hive的查询结果输出是否进行压缩
set hive.exec.compress.output=true;
# MapReduce Job的结果输出是否使用压缩
set mapreduce.output.fileoutputformat.compress=true;
#设置压缩方式是snappy
set parquet.compression = snappy;

 3.1.2 减少Reduce的数量

#reduce的个数决定了输出的文件的个数,所以可以调整reduce的个数控制hive表的文件数量,
#通过设置reduce的数量,利用distribute by使得数据均衡的进入每个reduce。
#设置reduce的数量有两种方式,第一种是直接设置reduce个数
set mapreduce.job.reduces=10;

#第二种是设置每个reduceTask的大小,Hive会根据数据总大小猜测确定一个reduce个数
set hive.exec.reducers.bytes.per.reducer=512*1000*1000; -- 默认是1G,这里为设置为5G

#执行以下语句,将数据均衡的分配到reduce中
set mapreduce.job.reduces=10;

insert overwrite table A partition(dt)
select * from B
distribute by  cast(rand()*10 as int);

解释:如设置reduce数量为10,则使用cast(rand()*10 as int),生成0-10之间的随机整数,根据【随机整数 % 10】计算分区编号,这样数据就会均衡的分发到各reduce中,防止出现有的文件过大或过小

3.2 已存在的小文件合并

      对集群上已存在的小文件进行定时或实时的合并操作,定时操作可在访问低峰期操作,如凌晨2点,合并操作主要有以下几种方式:

3.2.1 方式一:insert overwrite (推荐)

执行流程总体如下:

(1)创建备份表(创建备份表时需和原表的表结构一致)

create table test.table_hive_back like test.table_hive ;

(2)设置合并文件相关参数,并使用insert overwrite 语句读取原表,再插入备份表

  • 设置合并文件相关参数

       使用 hive的merger合并参数,在正式 insert overwrite 之前做一个合并,合并的时候注意设置好压缩,不然文件会比较大。

  • 合并文件至备份表中,执行前保证没有数据写入原表
#如果有多级分区,将分区名放到partition中
insert overwrite table test.table_hive_back partition(batch_date) 
select * from test.table_hive;

 psinsert overwrite table test.table_hive_back 备份表的时候,可以使用distribute by 命令设置合并后的batch_date分区下的文件数据量

insert overwrite table 目标表 [partition(hour=...)] select * from 目标表 
distribute by cast( rand() * 具体最后落地生成多少个文件数 as int);
  • insert overwrite会重写数据,先进行删除后插入(不用担心如果overwrite失败,数据没了,这里面是有事务保障的);

  • distribute by分区控制数据从map端发往到哪个reduceTask中,distribute by的分区规则:分区字段的hashcode值对reduce 个数取模后, 余数相同的数据会分发到同一个reduceTask中。

  • rand()函数:生成0-1的随机小数,控制最终输出多少个文件。

# 使用distribute by rand()将数据随机分配给reduce,这样可以使得每个reduce处理的数据大体一致。 避免出现有的文件特别大, 有的文件特别小,例如:控制dt分区目录下生成100个文件,那么hsql如下:
insert overwrite table A partition(dt)
 select * from B
distribute by cast(rand()*100 as int);

#cast(rand()*100 as int) 可以生成0-100的随机整数

     如果合并之后的文件竟然还变大了,可能是 select from的原数据是被压缩的,但是insert overwrite目标表的时候,没有设置输出文件压缩功能,解决方案:

# hive的查询结果输出是否进行压缩
set hive.exec.compress.output=true;
# MapReduce Job的结果输出是否使用压缩
set mapreduce.output.fileoutputformat.compress=true;
#设置压缩方式是snappy
set parquet.compression = snappy;

(3)确认表数据一致后,将原表修改名称为临时表tmp,将备份表修改名称为原表

  • 先查看原表和备份表数据量,确保表数据一致
#查看原表和备份表数据量
set hive.compute.query.using.stats=false ;
set hive.fetch.task.conversion=none;
SELECT count(*) FROM test.table_hive;
SELECT count(*) FROM test.table_hive_back ;
  • 将原表修改名称为临时表tmp,将备份表修改名称为原表
alter table test.table_hive rename to test.table_hive_tmp;
alter table test.table_hive_back rename to test.table_hive ;

(4)查看合并后的分区数和小文件数量

    正常情况下:hdfs文件系统上的table_hive表的分区数量没有改变,但是每个分区的几个小文件已经合并为一个文件。

#统计合并后的分区数
[atguigu@bigdata102 ~]$ hdfs dfs -ls /user/hive/warehouse/test/table_hive
#统计合并后的分区数下的文件数
[atguigu@bigdata102 ~]$ hdfs dfs -ls /user/hive/warehouse/test/table_hive/batch_date=20210608

  例如:

(5)观察一段时间后再删除临时表

drop  table test.table_hive_tmp ;

     ps:注意修改hive表名的时候,对应表的存储路径会发生变化,如果有新的任务上传数据到具体路径,需要注意可能需要修改。

 3.2.2 方式二:concatenate

      对于orc文件,可以使用hive自带的 concatenate 命令,自动合并小文件

#对于非分区表
alter table test concatenate;

#对于分区表
alter table test [partition(...)] concatenate
#例如:alter table test partition(dt='2021-05-07',hr='12') concatenate;

注意: 

  • concatenate 命令只支持 rcfile和 orc文件类型。 
  • concatenate命令合并小文件时不能指定合并后的文件数量,但可以多次执行该命令。 
  • 当多次使用concatenate后文件数量不变化,这个跟参数 mapreduce.input.fileinputformat.split.minsize=256mb 的设置有关,可设定每个文件的最小size。

 3.2.3 方式三:使用hive的archive归档

    每日定时脚本,对于已经产生小文件的hive表使用har归档,然后已归档的分区不能insert overwrite ,必须先unarchive

#用来控制归档是否可用
set hive.archive.enabled=true;

#通知Hive在创建归档时是否可以设置父目录
set hive.archive.har.parentdir.settable=true;

#控制需要归档文件的大小
set har.partfile.size=256000000;

#对表的某个分区进行归档
alter table test_rownumber2 archive partition(dt='20230324');

#对已归档的分区恢复为原文件
alter table test_rownumber2 unarchive partition(dt='20230324');

3.2.4 方式四:hadoop getmerge

  对于txt格式的文件可以使用hadoop getmerge命令来合并小文件。使用 getmerge 命令先合并数据到本地,再通过put命令回传数据到hdfs。

  • 将hdfs上分区为pdate=20220815,文件路径为  /user/hive/warehouse/xxxx.db/xxxx/pdate=20220815/* 下载到linux 本地进行合并文件,本地路径为:/home/hadoop/pdate/20220815

         hadoop fs -getmerge  /user/hive/warehouse/xxxx.db/xxxx/pdate=20220815/*  /home/hadoop/pdate/20220815;

  •  将hdfs源分区数据删除

        hadoop fs -rm  /user/hive/warehouse/xxxx.db/xxxx/pdate=20220815/*

  • 在hdfs上新建分区

      hadoop fs -mkdir -p /user/hive/warehouse/xxxx.db/xxxx/pdate=20220815

  • 将本地合并后的文件回传到hdfs上

         hadoop fs -put  /home/hadoop/pdate/20220815  /user/hive/warehouse/xxxx.db/xxxx/pdate=20220815/*

参考文章:

HIVE中小文件问题_hive小文件产生的原因-CSDN博客

Hive教程(09)- 彻底解决小文件的问题-阿里云开发者社区

0704-5.16.2-如何使用Hive合并小文件-腾讯云开发者社区-腾讯云

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/386997.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Zigbee课程设计系列文章】Zigbee开发环境搭建

【Zigbee课程设计系列文章】Zigbee开发环境搭建 前言IAR 下载安装Z-Stack协议栈安装 🎊项目专栏:【Zigbee课程设计系列文章】(附详细使用教程完整代码原理图完整课设报告) 前言 👑由于无线传感器网络(也即…

RMSNorm原理及代码

RMSNorm原理及代码 在大模型中使用层归一化有如下几个因素: 改善网络稳定性加速收敛速度提高模型的泛化能力 批量归一化是对一个批次内的数据进行归一化 层归一化是对一个样本中的不同特征进行归一化 如下是LayerNorm与RMSNorm的公式 在LLaMA中使用RMSNorm替代…

【华为云】容灾方案两地三中心实践理论

应用上云之后,如何进行数据可靠性以及业务连续性的保障是非常关键的,通过华为云云上两地三中心方案了解相关方案认证地址:https://connect.huaweicloud.com/courses/learn/course-v1:HuaweiXCBUCNXI057Self-paced/about当前内容为灾备常见理论…

NARF关键点提取原理简介

一、NARF2D边缘点探测的矩形平面的边长s和计算点p和上邻域的距离所用的k值 二、障碍物边缘和阴影边缘 三、NARF边缘点探测 四、NARF借助边缘点信息进行关键点检测 本人也是参考其他博主,以及这份英文文献写的(毕竟是英文文献,部分翻译肯定有些误差&…

企业计算机服务器中了mkp勒索病毒怎么办?Mkp勒索病毒解密处理

随着网络技术的不断发展,企业的生产运营也加大了步伐,网络为企业的生产运营提供了强有力保障,但网络是一把双刃剑,给企业带来便利的同时也为企业带来了严重的数据威胁。春节期间,云天数据恢复中心接到很多企业的值班人…

反序列化漏洞(一)Shiro漏洞CVE-2016-4437复现

★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与学习之用,读者将信息做其他用途,由Ta承担全部法律及连带责任,文章作者不承担任何法律及连带责任。 1、前言 春节后第一篇,祝大家龙年一切顺利&…

MySQL-运维

一、日志 1.错误日志 错误日志是MySQL中最重要的日志之一,它记录了当mysql启动和停止时,以及服务器在运行过程中发生任何严重错误时的相关性息。当数据库出现任何故障导致无法正常使用时,建议首先查看此日志。 该日志是默认开启的&#xf…

国产制造,欧美品质:爱可声助听器产品质量获国际认可

随着科技的发展和全球化的推进,越来越多的中国制造产品开始走向世界舞台。其中,爱可声助听器凭借其卓越的产品质量,成为了国产制造的骄傲。 国产制造指的是在中国境内生产的产品,欧美品质则是指产品在设计、生产、质量控制等方面…

CSS3学习(一)

1. 语法规范 CSS主要由选择器和一条或多条的声明构成。 选择器用于指定CSS样式的HTML标签&#xff0c;花括号里面是对应的具体样式 属性与属性值以键值对的形式出现&#xff0c;属性与属性之间用分号隔开 <head>里写<style> 2. 基础选择器 【作用】选择标签使…

【计算机网络】FTP 文件传输协议

同样使用TCP 但使用了两个并行的TCP 控制链接 control connection 带外 out-of-band 传送的数据链接 data connection 对于FTP而言&#xff0c;控制链接贯穿了整个用户会话期间&#xff0c;数据链接每传输一个文件就有一次建立FTP是有状态&#xff08;state&#xff09;的&…

【从Python基础到深度学习】4. Linux常用命令(进阶)

接上篇 【从Python基础到深度学习】4. Linux 常用命令-CSDN博客 1.文件查找 - find 命令 find [搜索路径] [搜索条件] [操作]1.1 常用选项和参数 -name&#xff1a;按文件名搜索。 find 命令的 -name 选项可以接受通配符来匹配文件名。通配符可以帮助你更灵活地搜索文件名&a…

【Web】NSSCTF Round#18 Basic个人wp(部分)

目录 ①门酱想玩什么呢&#xff1f; ②Becomeroot ①门酱想玩什么呢&#xff1f; 先试一下随便给个链接 不能访问远程链接&#xff0c;结合评论区功能&#xff0c;不难联想到xss&#xff0c;只要给个评论区链接让门酱访问就可 我们研究下评论区 从评论区知道&#xff0c;要…

建立知识体系,这份指南就够了

最近&#xff0c;许多读者私信我&#xff0c;问到这个问题。 恰好又要推送了&#xff0c;索性分享一些心得。 说实话&#xff0c;这是个很大的问题&#xff0c;要彻底讲透&#xff0c;大概得写一整本书。 所以&#xff0c;我尝试用尽量简洁的篇幅&#xff0c;将这个问题说清楚。…

Redis进阶(二):事务

redis事务特点 弱化的原子性 redis事务的原子性不像MySQL原子性一样&#xff0c;执行不成功的话&#xff0c;redis事务不会进行回滚操作 不具备一致性 redis没有约束&#xff0c;也没有回滚机制&#xff0c;因此事务执行的过程中如果某个修改操作出现失败&#xff0c;就可能引起…

研究多态恶意软件,探讨网络安全与AI

前言 近期ChatGPT火遍全球&#xff0c;AI技术被应用到了全球各行各业当中&#xff0c;国内外各大厂商也开始推出自己的ChatGPT&#xff0c;笔者所在公司在前段时间也推出了自研的安全GPT&#xff0c;AI技术在网络安全行业得到了很多的应用&#xff0c;不管是网络安全研究人员、…

ClickHouse--05--MergeTree 表引擎

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 MergeTree 系列表引擎前言MergeTree 系列表引擎 --功能MergeTree 系列表引擎 --种类 1.MergeTree1.1MergeTree 建表语句&#xff1a;1.2 MergeTree 引擎表目录解析查…

vscode-python的debug 教学(最全)

vscode中的python-debugger的使用 Visual Studio Code 的主要功能之一是其强大的调试支持。VS Code 的内置调试器有助于加速编辑、编译和调试循环。 一、 安装python-debugger插件 在插件库内搜索python Debugger&#xff0c;安装插件 三、 进行debug&#xff08;不带参数…

Linux查看日志的几种方法总结

摘要 Linux系统中查看日志的命令确实多种多样&#xff0c;每个命令都有其特定的用途和优势。常用的命令有&#xff1a;tail、cat、tac、head、echo&#xff0c;grep、less、awk、sed。 下面我会详细解释这些命令在查看日志时的用法和特点&#xff1a; tail命令&#xff1a; ta…

ELAdmin 部署

后端部署 按需修改 application-prod.yml 例如验证码方式、登录状态到期时间等等。 修改完成后打好 Jar 包 执行完成后会生成最终可执行的 jar。JPA版本是 2.6&#xff0c;MyBatis 版本是 1.1。 启动命令 nohup java -jar eladmin-system-2.6.jar --spring.profiles.active…

【AI视野·今日CV 计算机视觉论文速览 第292期】Thu, 18 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Thu, 18 Jan 2024 Totally 102 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers GARField: Group Anything with Radiance Fields Authors Chung Min Kim, Mingxuan Wu, Justin Kerr, Ken Goldberg, Matt…