Dataframe 并行化pyspark 2.2.0数据帧分区写入S3

Dataframe 并行化pyspark 2.2.0数据帧分区写入S3,dataframe,amazon-s3,parallel-processing,pyspark,Dataframe,Amazon S3,Parallel Processing,Pyspark,开始使用pyspark并遇到我用代码创建的瓶颈: 我正在按驱动器id将pyspark 2.2.0数据帧“分组” 并将每个分区(组)写入S3上自己的位置 我需要它来定义S3位置上由驱动器id分区的Athena表-这允许我在通过驱动器id查询时非常高效地读取数据 #df is spark dataframe g=df.groupBy(df.drive_id) rows=sorted(g.count().collect()) #each

开始使用pyspark并遇到我用代码创建的瓶颈:

我正在按驱动器id将pyspark 2.2.0数据帧“分组” 并将每个分区(组)写入S3上自己的位置

我需要它来定义S3位置上由驱动器id分区的Athena表-这允许我在通过驱动器id查询时非常高效地读取数据

        #df is spark dataframe 
        g=df.groupBy(df.drive_id)
        rows=sorted(g.count().collect())
        #each row is a parition
        for row in rows:
            w=df.where((col("drive_id") == row.drive_id))
        w.write.mode('append').parquet("s3n://s3bucket/parquet/drives/"+str(table)+"/drive_id="+str(row.drive_id) )
问题是,循环使处理串行化,并且只逐个写入驱动器分区

显然,这并不能很好地扩展,因为单分区写任务非常小,并行化并不能带来很多好处

如何用一个write命令替换循环,该命令将在一个操作中将所有分区写入不同的位置


这个操作应该并行运行在spark workers上,而不是驱动程序上。

我找到了答案——非常简单

dataframe.write.parquet具有可选参数partitionBy(列的名称)

因此,不需要在“分组方式”中,也不需要在循环中: 使用单行:

df.write.partitionBy(drive_id).parquet("s3n://s3bucket/dir")

创建标准配置单元格式的分区“s3n://s3bucket/dir/drive\u id=123”

我找到了答案——非常简单

dataframe.write.parquet具有可选参数partitionBy(列的名称)

因此,不需要在“分组方式”中,也不需要在循环中: 使用单行:

df.write.partitionBy(drive_id).parquet("s3n://s3bucket/dir")
以标准配置单元格式“s3n://s3bucket/dir/drive\u id=123”创建分区