1

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

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

查询一:

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 mappersand1 reducers和 thay 几乎都有same cumulative CPU seconds. 这意味着它们没有基因差异,并且时间差异可能是由集群负载引起的。

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

4

1 回答 1

1

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

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

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

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

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

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

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

于 2020-05-13T10:48:08.103 回答