本文将介绍 Hive GroupBy,Distinct 和 Join 的原理与相关调优参数,帮助大家深入理解Hive。
Mode
根据调用UDAF的不同接口,Hive GroupBy 算子分为以下几类Mode,具体请看代码注释 :)
/**
* Group-by Mode: COMPLETE: complete 1-phase aggregation: iterate, terminate
* PARTIAL1: partial aggregation - first phase: iterate, terminatePartial
* PARTIAL2: partial aggregation - second phase: merge, terminatePartial
* PARTIALS: For non-distinct the same as PARTIAL2, for distinct the same as
* PARTIAL1
* FINAL: partial aggregation - final phase: merge, terminate
* HASH: For non-distinct the same as PARTIAL1 but use hash-table-based aggregation
* MERGEPARTIAL: FINAL for non-distinct aggregations, COMPLETE for distinct
* aggregations.
*/

# 是否开启mapper端聚合
hive.map.aggr
# 是否开启,如果数据倾斜,是否优化group by为两个MR job
#该配置会触发hive增加额外的mr过程,随机化key后进行聚合操作得到中间结果,再对中间结果执行最终的聚合操作。
#count(distinct)操作比较特殊,无法进行中间的聚合操作,因此该参数对有count(distinct)操作的sql不适用。
hive.groupby.skewindata
# 用于map端聚合的hashtable最大可用内存,如果超过该内存比例,将flush到磁盘
hive.map.aggr.hash.force.flush.memory.threshold
# 可以用于mapper端hatable的内存比例
hive.map.aggr.hash.percentmemory (Default: 0.5) – Percent of total map task memory that can be used for hash table.
# 如果hashtable大小/输入行数 大于该阈值,那么停止hash聚合,转为sort-based aggregation
hive.map.aggr.hash.min.reduction (Default: 0.5)
# 每隔多少行,检测hashtable大小和input row比例是否超过阈值
hive.groupby.mapaggr.checkinterval
# 是否开启bucket group by
hive.optimize.groupby当 query 只有一个distinct expression时,那么将 distinct expression作为一个partition key做shuffle,然后利用 MapReduce / Tez 的排序,在 reducer 端取最后一个key的即可完成去重功能。
如果查询中有多个 distinct expression,同一条record,会生成多条记录进行Shuffle,增大Shuffle量。考虑以下query:
select dealid, count(distinct uid), count(distinct date) from order group by dealid;不考虑 Map Aggregation的情况下,上述 query 实际执行计划如下图所示。 Reducer端接收到的 key 中元素分别是:dealid, distinct expression的序号, distinct expression。

具体代码可参考ReduceSinkOperator.process方法,代码片段如下图所示。


hive.mapjoin.localtask.max.memory.usage来改变Local Task可使用的内存大小。 

SELECT * FROM cities JOIN sales on cities.cityId=sales.cityId; 则Conditional Tasks结构如下。在作业执行过程中,Hive将获取到所有关联表的元数据,如:大小,位置等,然后选择一个从众多conditional tasks中选择一个task作为真正执行的task。 

# 是否自动转换common join为map join
set hive.auto.convert.join=true;
# 如果join的小表和小于该阈值,会尝试将Common join 转换成map join。通过explain命令,可以发现Operator树中有conditional Operator。 如果n-1张表大小和,小于该阈值,则生成conditional tasks。
hive.smalltable.filesize or hive.mapjoin.smalltable.filesize
# 如果join的小表小于该阈值,会直接将Common join转换成Map join。需要考虑到数据解压之后的实际大小,hive表在被解压后,文件大小可能会增大10倍。
hive.auto.convert.join.noconditionaltask.size
set hive.optimize.skewjoin=true;
set hive.skewjoin.key=100000;
set hive.optimize.bucketmapjoin=true;参考资料:
推荐阅读 :
零基础学习 Hadoop 该如何下手?
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31509949/viewspace-3157183/ ,如需转载,请注明出处,否则将追究法律责任。