hive相关总结
Hive分区和分桶的区别?主要作用?
区别:
分区字段不是实际的列,分桶字段必须是实际的列 。
分区表的分区数量可以一直增长,而分桶表创建好后桶的数量就固定不变了 。
分区和分桶最大的区别就是分桶随机分割数据库,分区是非随机分割数据库。因为分桶是按照列的哈希函数进行分割的,相对比较平均;而分区是按照列的值来进行分割的,容易造成数据倾斜。其次两者的另一个区别就是分桶是对应不同的文件(细粒度),分区是对应不同的文件夹(粗粒度)。
分区作用: 庞大的数据集可能需要耗费大量的时间去处理。在许多场景下,可以通过分区的方法减少每一次扫描总数据量,这种做法可以显著地改善性能。
分桶作用:
HiveSQL转化为MR的过程
(1)HiveSQL现有驱动模块中的编译器对其进行SQL语句的词法和语法解析,将HQL语句转换成抽象语法树(AST Tree)的形式;
(2)遍历转换成的抽象语法树,将其转换成QueryBlock查询单元。查询单元是一条最基本的SQL语法组成单元,包括输入源、计算过程和输出三个部分;
(3)遍历查询单元,将查询单元转换成OperatorTree操作树,操作树由很多逻辑操作组成;(例如select、join、groupby)
(4)驱动模块中的优化器会对操作树进行优化,为了减少MR任务和Shuffle数量,合并多余的操作符;
(5)遍历优化后的操作树,根据操作树生成对应的物理操作任务(MR);
(6)启动优化器对物理操作任务进行优化,生成最终的MR执行计划;
(7)最后在驱动模块中的执行器中执行,输出数据。
Hive生成小文件过多有什么影响?如何优化?
影响:
首先对底层存储HDFS来说,HDFS本身就不适合存储大量小文件,小文件过多会导致namenode元数据特别大, 占用太多内存,严重影响HDFS的性能
对 hive 来说,在进行查询时,每个小文件都会当成一个块,启动一个Map任务来完成,而一个Map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的Map数量是受限的。
优化:
- 使用 hive 自带的 concatenate 命令,自动合并小文件
注意:
1、concatenate 命令只支持 RCFILE 和 ORC 文件类型。
2、使用concatenate命令合并小文件时不能指定合并后的文件数量,但可以多次执行该命令。
3、当多次使用concatenate后文件数量不在变化,这个跟参数 mapreduce.input.fileinputformat.split.minsize=256mb 的设置有关,可设定每个文件的最小size。
- 调整参数减少Map数量
设置map输入合并小文件的相关参数:
#执行Map前进行小文件合并
#CombineHiveInputFormat底层是 Hadoop的 CombineFileInputFormat 方法
#此方法是在mapper中将多个文件合成一个split作为输入
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; -- 默认
#每个Map最大输入大小(这个值决定了合并后文件的数量)
set mapred.max.split.size=256000000; -- 256M
#一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
set mapred.min.split.size.per.node=100000000; -- 100M
#一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)
set mapred.min.split.size.per.rack=100000000; -- 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
-
减少Reduce的数量
#reduce 的个数决定了输出的文件的个数,所以可以调整reduce的个数控制hive表的文件数量, #hive中的分区函数 distribute by 正好是控制MR中partition分区的, #然后通过设置reduce的数量,结合分区函数让数据均衡的进入每个reduce即可。 #设置reduce的数量有两种方式,第一种是直接设置reduce个数 set mapreduce.job.reduces=10; #第二种是设置每个reduce的大小,Hive会根据数据总大小猜测确定一个reduce个数 set hive.exec.reducers.bytes.per.reducer=5120000000; -- 默认是1G,设置为5G #执行以下语句,将数据均衡的分配到reduce中 set mapreduce.job.reduces=10; insert overwrite table A partition(dt) select * from B distribute by rand(); 解释:如设置reduce数量为10,则使用 rand(), 随机生成一个数 x % 10 , 这样数据就会随机进入 reduce 中,防止出现有的文件过大或过小
-
使用hadoop的archive将小文件归档
Hadoop Archive简称HAR,是一个高效地将小文件放入HDFS块中的文件存档工具,它能够将多个小文件打包成一个HAR文件,这样在减少namenode内存使用的同时,仍然允许对文件进行透明的访问.
#用来控制归档是否可用
set hive.archive.enabled=true;
#通知Hive在创建归档时是否可以设置父目录
set hive.archive.har.parentdir.settable=true;
#控制需要归档文件的大小
set har.partfile.size=1099511627776;
#使用以下命令进行归档
ALTER TABLE A ARCHIVE PARTITION(dt='2020-12-24', hr='12');
#对已归档的分区恢复为原文件
ALTER TABLE A UNARCHIVE PARTITION(dt='2020-12-24', hr='12');
注意:
归档的分区可以查看不能 insert overwrite,必须先 unarchive
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!