前言
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表(类似于RDBMS中的表),并提供类SQL查询功能;Hive是由Facebook开源,用于解决海量结构化日志的数据统计。hive调优无论在我们面试中还是工作中都经常遇到,今天我们先来从它的底层架构来说起。
一、hive转化为MapReduce过程
1.Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree
2.遍历AST Tree,抽象出查询的基本组成单元QueryBlock
3遍历QueryBlock,翻译为执行操作树OperatorTree
4逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量
5遍历OperatorTree,翻译为MapReduce任务
6.物理层优化器进行Mapeduce任务的变换,生成最终的执行计划
二、hive数据倾斜
1.数据倾斜是什么
一般来说,在分布式处理数据的时候,我们希望分配到每个节点的数据量能够大致相同,但实践过程中往往会出现大部分数据集中到某个节点的情况,导致所有节点都要等他处理完才能进行下一步行动。
2.数据倾斜的原因
1)、key分布不均匀
2)、业务数据本身的特性
3)、建表时考虑不周
4)、某些SQL语句本身就有数据倾斜
3.数据倾斜的底层原理
mapreduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完。Hive的执行是分阶段的,map处理数据量的差异取决于上一个stage的reduce输出,所以如何将数据均匀的分配到各个reduce中,就是解决数据倾斜的根本所在。
三.hive优化
3.1架构优化
执行引擎:Hive支持多种执行引擎,分别是 MapReduce、Tez、Spark、Flink。可以通过hivesite.xml文件中的hive.execution.engine属性控制。
分区表:对于一张比较大的表,将其设计成分区表可以提升查询的性能,对于一个特定分区的 查询,只会加载对应分区路径的文件数据,所以执行速度会比较快。
分桶表:与分区表类似,分桶表的组织方式是将HDFS上的文件分割成多个文件。分桶可以加快数据采样,也可以提升join的性能(join的字段是分桶字段),因为分桶可 以确保某个key对应的数据在一个特定的桶内(文件)。
文件格式:在HiveQL的create table语句中,可以使用stored as …指定表的存储格式。
数据压缩:压缩技术可以减少map与reduce之间的数据传输,从而可以提升查询性能,关于压 缩的配置可以在hive的命令行中或者hive-site.xml文件中进行配置。
3.2参数优化
本地模式:当Hive处理的数据量较小时,启动分布式去处理数据会有点浪费,因为可能启动的时 间比数据处理的时间还要长。Hive支持将作业动态地转为本地模式。
严格模式:是强制不允许用户执行3种有风险的HiveQL语句,一旦执行会直接 失败。这3种语句是:
查询分区表时不限定分区列的语句;
两表join产生了笛卡尔积的语句;
用order by来排序,但没有指定limit的语句。
JVM重用:Hadoop会为为一个map或者reduce启动一个JVM,这样可以并行执行 map和reduce。
并行执行 :Hive的查询通常会被转换成一系列的stage,这些stage之间并不是一直相互依赖的, 可以并行执行这些stage.
推测执行:Hadoop采用了推测执行机制,它根据一定的规则推测出 “拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理 同一份数据,并终选用先成功运行完成任务的计算结果作为终结果
合并小文件:在map执行前合并小文件,减少map数.在Map-Reduce的任务结束时合并小文件.
Fetch模式:可以简单地读取表对应的存储目录下的文件,然后输出查询结果到控制台。在开启 fetch模式之后,在全局查找、字段查找、limit查找等都不启动 MapReduce 。
3.3SQL优化
列裁剪和分区裁剪:列裁剪是在查询时只读取需要的列;
分区裁剪就是只读取需要的分区。
group by 代替 count(distinct)
group by 配置调整。
join优化
处理空值或无意义值
单独处理倾斜key
设置合理的map、reduce task数