Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 提高读取拼花地板文件的并行性-Spark优化自连接_Apache Spark_Optimization_Apache Spark Sql_Self Join - Fatal编程技术网

Apache spark 提高读取拼花地板文件的并行性-Spark优化自连接

Apache spark 提高读取拼花地板文件的并行性-Spark优化自连接,apache-spark,optimization,apache-spark-sql,self-join,Apache Spark,Optimization,Apache Spark Sql,Self Join,我想执行自连接以生成候选匹配对。目前,这是不工作的,因为这个操作太慢了。不幸的是,我不能广播数据帧,因为它们太大了 首先,我聚合元组的数量以减少数据: val aggregated = df.groupBy("discrete_foo", "discrete_bar").agg(sum("value")) aggregated.repartition(7, "discrete_foo", "discrete_bar").sortWithinPartitions("discreate_foo",

我想执行自连接以生成候选匹配对。目前,这是不工作的,因为这个操作太慢了。不幸的是,我不能广播数据帧,因为它们太大了

首先,我聚合元组的数量以减少数据:

val aggregated = df.groupBy("discrete_foo", "discrete_bar").agg(sum("value"))
aggregated.repartition(7, "discrete_foo", "discrete_bar").sortWithinPartitions("discreate_foo", "discrete_bar, "baz").write.parquet.option("compression", "gzip").mode("overwrite")
这工作很好,速度很快。然后,我想执行自联接以生成候选对象。 我已经注意到我需要生成更多的并行性:

--conf spark.sql.shuffle.partitions=4000 \
--conf spark.default.parallelism=4000 \ 
因此,将设置增加的默认并行度和随机并行度。此外,我尝试对两个离散值进行粗化(即增加属于离散块的项的数量),从而减少元组的数量。还是不走运。因此,我还试图通过重新划分来强制执行大量任务:

val materializedAggregated= spark.read.parquet(s"path/to/file/aggregated_stuff"      )
  .repartition(4000)
val selfB = materializedAggregated
  .withColumnRenamed("baz", "other_batz")
  .withColumnRenamed("value", "other_value")

val candidates = materializedMultiSTW
  .join(selfB, Seq("discrete_foo", "discrete_bar"), "inner")
  .filter(col(FeedIdentifierColumns.imsiHash) =!= col("other_imsi_hash"))
然而,这也不起作用&太慢了。我还可以做些什么来加快这个查询的计算速度?我有什么遗漏吗

在下面,您将看到在读取自联接数据时尝试增加并行性的各种失败尝试

我甚至设置:

--conf spark.sql.files.maxPartitionBytes=16777216 \
到1/8,即16比128MB,生成的任务数量仍然太少,即只有250个

一些细节 执行计划:

即使没有手动重新分区,速度也太慢,而且我担心没有创建足够的分区:

处理的任务更少-这很可能会使速度变慢:

如何确保此初始步骤具有更高的并行性? 扣子能帮上忙吗?但是,当只读取一次经过洗牌的数据时,它实际上不会产生加速效果,对吗? 写入聚合文件时,重新分区步骤如何?我应该在这里设置一个更高的数字吗? 到目前为止,即使省略它(并且基本上重新计算聚合两次),它也不会超过260个任务

环境
我在HDP3.1上使用spark 2.3.x

无论
spark.sql.shuffle.partitions
spark.default.parallelism
的设置如何,来自内部联接的最大任务数将等于联接键数(即它们的基数)

这是因为在SortMergeJoin中,数据将使用join键的散列进行洗牌。来自每个不同联接键的所有数据都将发送给单个执行器

因此,问题是你没有足够的垃圾箱——它们太粗糙了。您将看到的最大任务数将等于箱子数


如果您以更高的粒度存储数据,您应该会看到任务的数量增加。

这是否可能是由于生成候选比较时的偏差造成的?(在您的例子中,离散值)例如,如果您在名字上阻塞,那么John与John比较中的self-join可能会生成大量比较。SortMergeJoin意味着所有这些都将在单个节点上计算。(有趣的是,当我面对同样的问题时,你已经尝试了我在这里提到的大多数事情)当然,这是可能的,但我认为这只是一个小问题/次要问题。我的问题首先是:不知何故,我不能告诉spark生成更多的任务,也就是说,我不能向它扔更多的CPU以使它更快。但是你绝对正确,我需要找到一个解决方案来解决你所描述的问题。与此同时,我已经用每个执行器一个CPU重新启动了这个作业,每个执行器有30 Gig的ram-这至少(目前)消除了任何溢出到磁盘的需要。但这不是目前的瓶颈——只是任务的数量。啊——我想我现在可能明白了。你所做的两件事是有意义的,但前提是你有足够的离散值。您已经完成了:--conf spark.sql.shuffle.partitions=4000--conf spark.default.parallelism=4000和重新分区(4000),但是这只在至少有4000个离散存储箱的情况下才起作用——即,更细粒度的存储箱应该会导致更多的任务,更粗糙的存储箱应该会导致更少的任务tasks@RobinL我可以确认这是正确的。我仍然需要找到正确数量的参数,但这个建议肯定给了我250多个任务!