Pyspark分区行为

时间:2019-04-11 11:53:51

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

我正在尝试了解SQL上下文中的repartition()行为。我有一个包含178行的数据框。一列是与数据相关的唯一ID。在我的数据框中,我知道每个唯一ID都有2行。

我希望能够控制我得到的每个分区中的记录数。就我而言,我想在89个分区中包含2条记录。

按照文档(http://spark.apache.org/docs/2.2.0/api/python/pyspark.sql.html?highlight=repartition#pyspark.sql.DataFrame.repartition) 我正在执行以下操作:

df = spark.read \
        .parquet("my_data_path") \
        .repartition(89, "Id") 
        .withColumn('result_col', some_udf("data"))

df.persist()

df.write.format("org.elasticsearch.spark.sql").mode('append').save()

但是在运行作业时回到SparkUI时,我可以看到重新分区不好。

summary]([![https://postimg.cc/3d948XPV tasks

所以我对列的重新配合有些理解不正确。我试图在Id列中添加一些盐,但没有任何变化。我的问题是如何控制每个分区的记录数以及是否可以使用repartition()

谢谢大家

1 个答案:

答案 0 :(得分:0)

找到了解决方案,为正在寻找它的人们提供帮助。

解决方案是让SQL上下文使用RDD函数:


df = spark.read \
        .parquet("my_data_path") \

# We create a window in order to add index to our rows
w = Window.orderBy("random_field_sort")

# Add index
df = df.withColumn("index", row_number().over(w) % my_repartition_value))

schema = df.schema

# Use your index as Key in order to create a RDD of Key;Value
df = df.rdd.map(lambda x: (x["index"], (x)))

# The main point for the repartiton with the partitionBy 
# & revert back the structur of the data
rdd = df.partitionBy(my_repartition_value).map(lambda x: x[1])

# Good to go
df = spark.createDataFrame(rdd, schema)

df = df.withColumn('result_col', some_udf("data"))

df.persist()

df.write.format("org.elasticsearch.spark.sql").mode('append').save()