groupby和count中reducer的配置单元数(distinct)

1cklez4t  于 2021-05-31  发布在  Hadoop
关注(0)|答案(1)|浏览(384)

我被告知count(distinct)可能会导致数据倾斜,因为只使用了一个reducer。
我用一个有50亿数据的表做了一个测试,有两个查询,
查询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 mappers 以及 1 reducers 他们几乎拥有 same cumulative CPU seconds . 这意味着它们之间没有时间差,时间差可能是由集群负载引起的。
我不明白为什么所有的人都用一个1还原剂,我甚至尝试 mapreduce.job.reduces 但它不起作用。顺便说一句,如果他们都使用1减速机,为什么人们建议不要使用 count(distinct ) 而且数据倾斜似乎是无法避免的?

mu0hgdu0

mu0hgdu01#

两个查询都使用相同数量的Map器(这是预期的)和单个final reducer(这也是预期的),因为您需要单个标量计数结果。同一顶点上的多个减速器独立运行,相互隔离,每个减速器将产生自己的输出,这就是为什么最后一级只有一个减速器。不同之处在于计划。
在第一次查询执行中,单个reducer读取每个Map器的输出,并对所有数据进行不同的计数计算,它处理了太多的数据。
第二个查询使用中间聚合,最终的reducer接收部分聚合的数据(在上一步聚合的不同值)。final reducer需要再次聚合部分结果才能得到最终结果,它可以比第一种情况下的数据少得多。
从hive1.2.0开始,对count(distinct)进行了优化,您不需要重写查询。设置此属性: hive.optimize.distinct.rewrite=true 还有Map器聚合(Map器也可以预聚合数据并在其数据部分的范围内生成不同的值-拆分)设置此属性以允许Map端聚合: hive.map.aggr=true 使用explain命令检查执行计划中的差异。
另请参见以下答案:https://stackoverflow.com/a/51492032/2700344

相关问题