Hive 分组中的减速器数量和计数(不同)

Posted

技术标签:

【中文标题】Hive 分组中的减速器数量和计数(不同)【英文标题】:Hive number of reducers in group by and count(distinct) 【发布时间】:2020-05-13 06:40:44 【问题描述】:

有人告诉我 count(distinct ) 可能会导致数据倾斜,因为只使用了一个 reducer。

我使用一个包含 50 亿条数据和 2 个查询的表进行了测试,

查询 A:

select count(distinct columnA) from tableA

查询 B:

select count(columnA) from
(select columnA from tableA group by columnA) a

实际上,查询 A 大约需要 1000-1500 秒,而查询 B 需要 500-900 秒。结果似乎在意料之中。

但是,我意识到这两个查询都使用 370 mappers1 reducers 并且几乎使用了 same cumulative CPU seconds。这意味着它们没有基因差异,并且时间差异可能是由集群负载引起的。

我很困惑为什么所有人都使用一个 1 减速器,我什至尝试过mapreduce.job.reduces,但它不起作用。顺便说一句,如果他们都使用 1 个减速器,为什么人们建议不要使用 count(distinct ) 并且似乎无法避免数据倾斜?

【问题讨论】:

【参考方案1】:

两个查询都使用相同数量的映射器,这是预期的,而单个最终化简器也是预期的,因为您需要单个标量计数结果。同一个顶点上的多个reducer 独立运行,相互隔离,每个都会产生自己的输出,这就是为什么最后一个阶段只有一个reducer。不同之处在于计划。

在第一个查询执行中,单个 reducer 读取每个 mapper 输出并对所有数据进行不同的计数计算,它处理的数据太多。

第二个查询使用中间聚合,最终 reducer 接收部分聚合的数据(在上一步聚合的不同值)。 final reducer 需要再次聚合部分结果才能得到最终结果,它可以比第一种情况下的数据少得多。

从 Hive 1.2.0 开始,对 count(distinct) 进行了优化,您不需要重写查询。设置这个属性:hive.optimize.distinct.rewrite=true

还有映射器聚合(映射器也可以预先聚合数据并在其数据部分的范围内产生不同的值 - 拆分)设置此属性以允许映射端聚合:hive.map.aggr=true

使用EXPLAIN命令查看执行计划的差异。

另请参阅此答案:https://***.com/a/51492032/2700344

【讨论】:

感谢您的详细回复!当我在不设置任何属性的情况下运行Query A 时,我意识到reducer 的进度百分比有时会降低,例如:17%, 18%, 0%, 0%, 0%, 0%, 18%, 0%, 0%, 17%, 20%, 21%, ... 而mapper 的进度百分比正常增加。为什么会发生这种情况? @user2894829 检查减速器执行日志。也许一些减速器失败了。尝试在 Tez 上运行。如果减速器失败,它将显示负数:***.com/a/45185353/2700344 感谢您的信息!关于set hive.map.aggr=true;的最后一个问题。我阅读了一些材料并获得了 2 条信息:1)此属性在最近的 Hive 中已默认设置为 true。 2) 一位博主说此属性可能导致count(*) 的结果错误,他必须将其更改为sum(1),然后才能得到正确的结果。这只是一个暂时的错误吗? yq.aliyun.com/articles/622421抱歉,这是用中文写的,但有2个查询未完成。 @user2894829 我不知道这个错误。测试一下。如果这是您的 Hive 版本中的错误,请创建 Jira 票证。issues.apache.org/jira/projects/HIVE/issues @user2894829 已经过时了。它是在 2015 年发布的。跳过它。

以上是关于Hive 分组中的减速器数量和计数(不同)的主要内容,如果未能解决你的问题,请参考以下文章

Datastax Search / Solr中的分组和计数(*)

Hive 计数不同的 UDAF

Xquery 中的分组和计数

有没有办法根据 Hive/SQL 中的条件初始化计数器?

与计数、最大值和分组依据相关

solrcloud jsonfacet分组聚合 unique计数不准确