什么时候在Spark中执行.repartition(Int AnyValue),在读取Parquet之后(或在该Parquet上运行计算之后)?

时间:2019-06-05 15:53:41

标签: scala apache-spark pyspark apache-spark-sql

我有一个基于日期列进行分区的镶木地板文件,做.reparition()的最佳方法是什么?读完镶木地板后,我应该立即这样做吗?

 val myPq = "/hive/data/myPq.db/myPq"
    sparkSession.read
      .format("parquet")
      .load(inputConfig.getString("myPq")).repartition(200).createOrReplaceTempView("myPqView")

或者在执行了各种转换(例如过滤器,地图等)之后。

def readMyPq(){
val myPq = "/hive/data/myPq.db/myPq"
    sparkSession.read
      .format("parquet")
   .load(inputConfig.getString("myPq")).repartition(200).createOrReplaceTempView("myPqView")

val returnDF = spark.sql("Multiple Transformations from createOrReplaceTempView")
}

有什么好办法?预先谢谢你

2 个答案:

答案 0 :(得分:3)

这完全取决于您何时认为数据最不平衡。如果以不平衡的方式读取数据(例如1个大分区,199个小分区),则可能需要立即重新分区。

如果读入数据时数据是平衡的,但是在filter / map / etc之后,有一个大分区和一堆小分区,此时,您可能需要重新分区。

如果您的数据需要,那么在两个地方重新分区甚至都有意义。 请记住,重新分区并不便宜,应该与不重新分区的成本进行平衡。用正常数据流的一些样本进行基准测试,然后查看结果。

答案 1 :(得分:2)

我看不到您的代码段之间的区别,除了第二个是包含第一个的方法之外。但是,重新分区会使您在执行器之间的数据混乱。因此,如果您可以选择稍后在代码中进行重新分区,则最好对最小的数据集进行重新分区。如果您使用指定的过滤器,并且过滤出大量数据,那么最好在发生这种情况后调用重新分区。