0

您对如何在具有 10K+ 列的表上加速 Spark-SQL 有什么建议吗?

TL;TR: . 我必须解决 spark-SQL 处理具有来自 ORC 文件的 10K+ 列的宽表的性能问题。我注意到了这种改进 /CR:https://issues.apache.org/jira/browse/SPARK-25643

Spark 架构旨在处理长而窄的数据(<1K cols),这与我们这里的 = 10K 列 - 宽且相对较短的输入相反。

建议的解决方案:

  • 简单:而不是 10K+ 列上的一个大 SQL - 创建多个 SQL - 在临时表中输出 - 然后从临时表连接/联合到最后一个。

  • SPARK:“解决者/计划构建者”——不确定我是否正确命名,需要进一步调查。我运行这个测试:

    val n = 1000
    val values = (1 to n).map(_.toString).mkString(", ")
    val columns = (1 to n).map("column" + _).mkString(", ")
    val query = s" SELECT $columns FROM VALUES ($values) T($columns) WHERE 1=2 AND 1 IN ($columns) GROUP BY $columns ORDER BY $columns".stripMargin
   spark.time(spark.sql(query))

输出:

预期线性 [ms] 真实 [毫秒] 真实 [分钟]
100 200 183 0.003
250 500 306 0.005
500 1000 524 0.009
1000 2000 1514 0.025
2500 5000 7922 0.132
5000 10000 31131 0.519
10000 20000 134429 2.240
12500 25000 200568 3.343
15000 30000 348068 5.801
20000 40000 595804 9.930

尝试从 O(N^2) => O(N) ..

  • SPARK:自动分离器 - 在火花管道中引入 2 个新阶段:

    1. 语法拆分器 - 在开始时,即:更改“联合”行为 - 拆分为单独的 SQL,或更高级 - 处理 SQL,将列分成组:A - 参与转换(数学等的一部分),B - 不转换,然后创建多个列数较少的 SQL
    2. 最后从那些较小的 SQL 中输出混合器(连接/联合)。

TODO:寻找开销:过于复杂的计算/结构,计划中的新阶段等。

  • 框外命题 [3rd party],例如:H2O with ORC parser

H2O 有自己的 DF 表示 - 由 Cliff Click 完全重写。H2O 支持 xxK+ 列。H2O 计算 - 低级 - 无 SQL。期望:相当高 - H2O 被设计为使用 WIDE 列,并且列转换非常高效 - 它们有自己的索引机制等。

  • 开箱即用的命题:DB 和使用 DBA 解决问题

  • 开箱即用:noSQL,因为它是为宽列设计的


Spark 命题相当大/影响现有的 SQL 功能——不能保证这在将来会起作用。

PoC plan: 
1. Create: 3 tables - one with 10K columns
2. SQL that contains 3+ unions, 5+calculations
3. Multi SQLs 3+ (splitting unions) +1 final JOIN 
3. Compare timing 2. and 3. 

注意:这个 PoC 可能是火花分离器解决方案的一个足够好的指标。期望:假设当前时间是指数 => 更改为时间的总和,一切都将取决于最终的连接(不应该有任何其他操作)。

否则,基本上,我在泡菜:请任何建议如何解决这个问题。

4

0 回答 0