sme*_*eeb 5 partitioning distributed-computing unions apache-spark apache-spark-sql
我有一个 Spark 应用程序,需要大量使用它unions,我将在不同时间、不同情况下将大量 DataFrame 合并在一起。我正在努力使这项工作尽可能高效地进行。我对 Spark 还很陌生,我突然想到了一件事:
如果我有dfA具有 X 个分区 ( ) 的 DataFrame 'A' ( ) numAPartitions,并将其联合到dfB具有 Y 个分区 ( ) 的DataFrame 'B' ( numBPartitions) ,那么生成的联合 DataFrame ( unionedDF) 会是什么样子,结果如何分区?
// How many partitions will unionedDF have?
// X * Y ?
// Something else?
val unionedDF : DataFrame = dfA.unionAll(dfB)
Run Code Online (Sandbox Code Playgroud)
对我来说,理解这一点似乎非常重要,因为 Spark 性能似乎严重依赖于 DataFrames 采用的分区策略。因此,如果我左右合并 DataFrame,我需要确保不断管理合并后的 DataFrame 的分区。
我唯一能想到的(以便正确管理联合数据帧的分区)是对它们重新分区,然后在联合它们后立即将数据帧持久保存到内存/磁盘:
val unionedDF : DataFrame = dfA.unionAll(dfB)
unionedDF.repartition(optimalNumberOfPartitions).persist(StorageLevel.MEMORY_AND_DISK)
Run Code Online (Sandbox Code Playgroud)
这样,一旦它们联合起来,我们就重新分区它们,以便将它们正确地分布在可用的工作程序/执行程序上,然后调用persist(...)告诉 Spark 不要从内存中逐出 DataFrame,这样我们就可以继续处理它。
问题是,重新分区听起来很昂贵,但它可能不像替代方案(根本不管理分区)那么昂贵。Spark-land 是否有关于如何有效管理工会的普遍接受的准则?
是的,分区对于Spark很重要。
我想知道您是否可以通过拨打以下电话自己找到答案:
yourResultedRDD.getNumPartitions()
Run Code Online (Sandbox Code Playgroud)
结合后我必须坚持吗?
一般来说,如果要多次使用 RDD,则必须持久/缓存 RDD(无论它是联合的结果还是土豆:))。这样做可以防止Spark再次在内存中获取它,并且在某些情况下可以将应用程序的性能提高 15%!
例如,如果您只想使用生成的 RDD 一次,那么不持久化它是安全的。
我必须重新分区吗?
由于您不关心查找分区数量,因此您可以阅读我的Spark 中的内存开销问题 ,了解分区数量如何影响您的应用程序。
一般来说,分区越多,每个执行器处理的数据块就越小。
回想一下,一个工作线程可以托管多个执行程序,您可以将其视为集群的机器/节点,而执行程序则是在该工作线程上运行的进程(在核心中执行)。
Dataframe不是一直在内存中吗?
并不真地。这对于Spark来说真的很可爱,因为当你处理大数据时,你不希望内存中存有不必要的东西,因为这会威胁你的应用程序的安全。
DataFrame 可以存储在Spark为您创建的临时文件中,并且仅在需要时才加载到应用程序的内存中。
欲了解更多信息,请阅读:我应该始终缓存我的 RDD 和 DataFrame 吗?
| 归档时间: |
|
| 查看次数: |
10232 次 |
| 最近记录: |