Hive group by 和 count(distinct) 中的减速器数量

Hive number of reducers in group by and count(distinct)

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

我使用 table 进行了测试,其中有 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 ) 并且似乎数据倾斜是不可避免的?

这两个查询都使用了相同数量的映射器,这是预期的,并且使用了单个最终减速器,这也是预期的,因为您需要单个标量计数结果。同一顶点上的多个 reducer 是 运行 独立、隔离的,每个都会产生自己的输出,这就是最后一个阶段只有一个 reducer 的原因。不同的是计划。

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

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

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

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

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

另请参阅此答案: