指望Spark Dataframe极其缓慢

时间:2017-07-17 10:42:14

标签: scala apache-spark count spark-dataframe rdd

我正在使用来自Join的一些记录创建一个新的DataFrame。

val joined_df = first_df.join(second_df, first_df.col("key") ===
second_df.col("key") && second_df.col("key").isNull, "left_outer")
joined_df.repartition(1)
joined_df.cache()
joined_df.count()

除计数操作外,一切都很快(不到一秒)。 RDD转换开始并且完成需要几个小时。有什么方法可以加快速度吗?

INFO MemoryStore: Block rdd_63_140 stored as values in memory (estimated size 16.0 B, free 829.3 MB)
INFO BlockManagerInfo: Added rdd_63_140 in memory on 192.168.8.52:36413 (size: 16.0 B, free: 829.8 MB)
INFO Executor: Finished task 140.0 in stage 10.0 (TID 544). 4232 bytes result sent to driver
INFO TaskSetManager: Starting task 142.0 in stage 10.0 (TID 545, localhost, executor driver, partition 142, PROCESS_LOCAL, 6284 bytes)
INFO Executor: Running task 142.0 in stage 10.0 (TID 545)
INFO TaskSetManager: Finished task 140.0 in stage 10.0 (TID 544) in 16 ms on localhost (executor driver) (136/200)
INFO ShuffleBlockFetcherIterator: Getting 0 non-empty blocks out of 200 blocks
INFO ShuffleBlockFetcherIterator: Started 0 remote fetches in 0 ms
INFO ShuffleBlockFetcherIterator: Getting 0 non-empty blocks out of 200 blocks
INFO ShuffleBlockFetcherIterator: Started 0 remote fetches in 0 ms

2 个答案:

答案 0 :(得分:13)

  

除计数操作外,一切都很快(一秒钟以内)。

这是合理的,如下所示:count之前的所有操作都被称为转换,这种类型的spark操作是懒惰的,即它在调用动作之前不进行任何计算(count in你的例子。)

第二个问题出在repartition(1)

请记住,您将失去spark提供的所有并行性,并且您的计算将在一个执行程序中运行(如果您处于独立模式,则为核心),因此您必须删除此步骤或更改 1 指向CPU核心数(独立模式)或执行者数量(集群模式)的数字。

  

RDD转换开始并且完成需要几个小时。

如果我理解正确你会将DataFrame转换为RDD,这在火花中确实是一种不好的做法,你应该尽可能避免这种转换。 这是因为DataFrameDataset中的数据是使用特殊火花编码器编码的(如果我记得的话,它被称为tungstant),这会占用更少的内存JVM序列化编码器,所以这样的转换意味着spark会改变你自己的数据类型(这需要更少的内存并让spark 优化大量的交换只需处理编码数据,而不是将数据序列化,然后将其反序列化为JVM数据类型,这就是为什么DataFrameDatasetRDD s强大的原因

希望这能帮到你

答案 1 :(得分:1)

正如其他人所提到的,count之前的操作是"懒惰"只有注册一个转换,而不是实际强制计算

当您致电count时,会触发计算。这是Spark读取您的数据,执行所有先前注册的转换并计算您请求的结果(在本例中为count)。

  

RDD转换启动并完成需要数小时才能完成

我认为术语"转换"可能有点不准确。实际发生的情况是,您注册的DataFrame转换已转换为RDD操作,并且这些转换适用于作为DataFrame基础的RDD。您在此处提供的代码中没有转换本身

另外,可以通过DataFrame属性将RDD显式转换为DataFrame.rdd。正如this answer中所提到的,这通常是一个坏主意,因为您在结构良好的数据方面会失去一些(在性能和API方面)的好处。