dataframe.repartition(x)是否会加快执行速度

dataframe.repartition(x)是否会加快执行速度,dataframe,apache-spark,Dataframe,Apache Spark,我有一个Spark脚本,它从AmazonS3读取数据,然后以另一种bucket-usion-parquet格式写入 这是代码的样子: File = "LocationInFirstBucket.csv.gz" df_ods = spark.read.csv(File, header=True, sep=";") df_ods.repartition(25).write.format("parquet").mode("OverWrite").save("AnotherLocationInS3")

我有一个Spark脚本,它从AmazonS3读取数据,然后以另一种bucket-usion-parquet格式写入

这是代码的样子:

File = "LocationInFirstBucket.csv.gz"
df_ods = spark.read.csv(File, header=True, sep=";")

df_ods.repartition(25).write.format("parquet").mode("OverWrite").save("AnotherLocationInS3")
我的问题是:重分区参数(这里是25)如何影响执行时间?我应该增加它以便脚本运行更快吗

第二个问题:如果在最后一行之前缓存df会更好吗


谢谢

这里的问题是Spark可以将写入并行化到某一点,因为一个文件不能由多个执行器同时写入

重新分区有助于并行化,因为它将写入25个不同的文件(每个分区一个)。如果增加分区的数量,则会增加写入文件的数量,从而加快执行速度。这是有代价的,因为读取时间会随着要读取的文件数量的增加而增加

限制是与您运行作业的执行者的数量,例如,如果与25个执行者一起运行,则将“重新分区”设置为26对您没有帮助,因为要写入第26个分区,必须完成前25个分区中的一个分区


至于另一个问题,我不认为.cache()会帮助你,因为Spark很懒,也许可以进一步帮助你。

回答1:-重新分区25个或更多或更少,这取决于你有多少数据和你提供的执行者的数量。如果您的Spark代码在具有多个执行器的集群中运行,并且没有重新分区,那么重新分区将加快并行写入数据的速度


回答2:-没有必要在最后一行之前缓存df,因为您在代码中只使用了一个操作。如果您将对DF执行多个操作,并且不希望它作为操作数重新计算,则您将对其进行缓存。

在典型设置中,在这种特定情况下,重新分区或缓存都不会对您有所帮助。由于从非拆分格式读取数据:

df_ods
将只有一个分区

在这种情况下,如果您对该数据执行了任何实际处理,则重新分区是有意义的

然而,如果您只是向分布式文件系统写入数据,那么重新分区只会使成本增加一倍——您必须首先将数据发送到其他节点(包括序列化、反序列化、网络传输、写入磁盘),然后仍然向分布式文件系统写入数据

当然,这是有道理的。若群集的网络连接速度比群集到S3节点的网络连接速度快得多,那个么有效延迟可能会低一些


至于缓存,这里的缓存没有任何价值。缓存数据集非常昂贵,并且只有在重用持久化数据时才有意义。

编写文件确实取决于提供的分区和执行器的数量。我邀请您尝试使用集群中的任何数据集,看看会发生什么。显然,如果您有10个文件分区和50个执行器,那么40个执行器将是理想的选择。你可以试试。谢谢你的解释。如果我确实需要减少执行时间,我有什么选择?我应该在阅读时对df_ods进行分区吗?如果是的话,那怎么办呢?除了不使用gz之外?首先解包数据可能会稍微快一点,但您必须在自己的设置中对其进行基准测试。
File = "LocationInFirstBucket.csv.gz"
df_ods = spark.read.csv(File, header=True, sep=";")