我正在使用以下配置运行EMR集群: 1个主机,4个从机。执行者总数:11,每个执行者具有5个核心和34GB内存。动态分配设置为True。
我的pyspark工作流程包括以下步骤:
从S3读取总计50万行的50个csv文件 插入spark dataframe(df)。运行df.rdd.getNumPartitions()返回 50个分区。
使用df.repartition(1000),我将该数据帧重新划分为1000个分区。
使用熊猫UDF函数,我对该数据帧运行一些操作,并将结果分配给另一个数据帧(result_df)。这个数据框 与df相比,还有一个额外的字符串列。
我现在运行result_df.write.format(“ parquet”)。save(s3_path_dest,mode =“ overwrite”)将结果保存到S3位置。在此刻, 我看到在Spark Web UI中获得了2个“保存”阶段。第一阶段 有50个任务,表明有50个分区,而第二阶段 有1000个任务,对应于1000个分区。
然后我在上面的数据帧(result_df)上运行另一个pandas UDF函数,除了较旧的2列外,它还返回2列 列并将结果df保存到S3位置,就像在 步骤4。我现在看到又有两个阶段:第一阶段只有 5个任务,而第二个有1000个任务。
问题1:为什么会发生这种“自动”重新分区? (5个分区)
问题2:为什么将这个过程分为两个阶段,每个阶段以不同的分区数进行操作?我希望一个阶段可以处理1000个任务/分区。
问题3:在spark UI SQL选项卡中,我看到最后一步是从“ FileScan csv”步骤开始的。这是否意味着当我执行最后一步时,整个工作流程会从重新开始执行?我没想到会这样,因为我已经触发了中间保存操作(步骤4),该操作应该一直执行DAG,并且不需要重新计算将来步骤中可能需要的结果。
预先感谢您的帮助。