有人告诉我 count(distinct ) 可能会导致数据倾斜,因为只使用了一个减速器。
我使用一个包含 50 亿数据的表和 2 个查询进行了测试,
Query A:
select count(distinct columnA) from tableA
Query B:
select count(columnA) from
(select columnA from tableA group by columnA) a
实际上,查询 A 大约需要 1000-1500 秒,而查询 B 需要 500-900 秒。结果似乎在意料之中。
但是,我意识到这两个查询都使用370 mappers
and 1 reducers
并且他们几乎拥有same cumulative CPU seconds
。这意味着它们不存在本质差异,时间差异可能是由集群负载引起的。
我很困惑为什么都使用 1 个减速器,我什至尝试过mapreduce.job.reduces
但它不起作用。顺便说一句,如果他们都使用 1 个减速器,为什么人们建议不要使用count(distinct )
而且数据倾斜似乎是无法避免的?
两个查询都使用相同数量的映射器(这是预期的)和单个最终减速器,这也是预期的,因为您需要单个标量计数结果。同一顶点上的多个减速器独立、隔离地运行,每个减速器都会产生自己的输出,这就是最后一级只有单个减速器的原因。区别在于计划。
在第一个查询执行中,单个reducer读取每个mapper输出并对所有数据进行不同计数计算,它处理了太多数据。
第二个查询使用中间聚合,最终减速器接收部分聚合的数据(在上一步中聚合的不同值)。最终的reducer需要再次聚合部分结果才能得到最终结果,它的数据量可能比第一种情况要少得多。
从 Hive 1.2.0 开始,对 count(distinct) 进行了优化,您不需要重写查询。设置该属性:hive.optimize.distinct.rewrite=true
还有映射器聚合(映射器也可以预先聚合数据并在其数据部分的范围内生成不同的值 - 分割)设置此属性以允许映射端聚合:hive.map.aggr=true
use EXPLAIN命令来检查执行计划中的差异。
另请参阅这个答案:https://stackoverflow.com/a/51492032/2700344
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)