在执行Spark多维数据集时如何避免长时间运行的任务

时间:2018-01-11 01:17:11

标签: sql apache-spark query-optimization cube

想象一下一个博客,其中每个事件都归因于多个维度(siteID,countryID,pageID等),并且还有一个访客ID:

eventID | siteID | countryID | pageID | visitorID

目标是为每个维度组合计算唯一身份访问者,包括总计(即多维数据集)。它可以表示为以下Spark SQL查询:

SELECT
  COUNT(DISTINCT(visitorID)) 
FROM weblog
   GROUP BY siteID, countryID, pageID WITH CUBE

假设所有维度字段都具有相对较高的基数,Spark可以有效地完成这种聚合,因为每个维度组合将接收相对较少数量的访问者ID。

然而,

CUBE操作会创建与

等分组相对应的繁重任务
... GROUP BY siteID, countryID
... GROUP BY siteID
etc.

这些任务会收到非常多的ID(计算总计的任务会接收整个日志中的所有ID)。似乎Spark 2.2无法并行化,因此作业运行时受这些长时间运行的任务的限制。

如何优化此类查询?

1 个答案:

答案 0 :(得分:0)

简短的回答是不要使用COUNT(DISTINCT(_))。你不能吃蛋糕然后吃。您可以获得精确的结果,这可能会导致偏差和失败,或者具有有限精度和可预测性能的合理近似值。

而是使用草图使用近似计数。

SELECT approx_count_distinct(visitorID)
FROM ...
GROUP BY ... WITH CUBE