Python 3.x 如何确保在使用成功完成的Spark作业重新分区的同时重新分区完整的数据?
我的目标是重新划分源数据并将其保存在目标路径。我打算每个分区只创建一个S3对象,我已经通过以下方法实现了这一点:Python 3.x 如何确保在使用成功完成的Spark作业重新分区的同时重新分区完整的数据?,python-3.x,apache-spark,amazon-s3,Python 3.x,Apache Spark,Amazon S3,我的目标是重新划分源数据并将其保存在目标路径。我打算每个分区只创建一个S3对象,我已经通过以下方法实现了这一点: df.repartition("created_year", "created_month", "created_day").write.mode('overwrite').partitionBy( "created_year", "created_month", "crea
df.repartition("created_year", "created_month", "created_day").write.mode('overwrite').partitionBy( "created_year", "created_month", "created_day").parquet(dest_path)
source_df.distinct().count() == destination.distinct().count()
我希望确保所有数据都已传输,并且我了解到重新分区可能会删除重复的数据。因此,我决定检查每个源和目标的不同计数是否应该匹配。因此,我做了以下工作:
df.repartition("created_year", "created_month", "created_day").write.mode('overwrite').partitionBy( "created_year", "created_month", "created_day").parquet(dest_path)
source_df.distinct().count() == destination.distinct().count()
这将返回False
,表明在已完成所有任务的作业中,源和目标的不同计数不同
这是检查完整数据是否已重新分区和保存的正确方法吗?更好/正确的方法是什么
源和目标是AmazonS3上的两个不同的存储桶
可能的MVC是:
def count_distinct(src_path, spark):
try:
df = spark.read.parquet(f'{src_path}')
distinct_count = df.distinct().count()
print(distinct_count)
return distinct_count
except:
log_failed_bucket(src_path)
return None
def compare_distinct(spark, bucket_name):
src_path = form_path_string(bucket_name)
original_distinct_count = count_distinct(src_path, spark)
dest_path = form_path_string(bucket_name, repartitioned_data=True)
final_distinct_count = count_distinct(dest_path, spark)
return original_distinct_count == final_distinct_count
除非您在
partitionBy
中提供了所有列,否则在写入时无法删除重复项,并且在partitionBy
中提供所有列也是不可能的
如果任何分区列的值为null或为空
值,它将分别位于分区列的\uuuu配置单元\uu默认\uu分区\uuuuu
文件夹下
如果使用spark.read.format().load()读取多个路径,那么您应该提供'basePath'选项(如果它是动态形成的,则有可能丢失路径),否则您可以直接加载'basePath',并遵循下面提到的健全方法
您可以在根据源数据集和目标数据集之间的分区列进行分组后检查计数/不同
可以使用sourcePath从basePath检查总计数
源和目标之间分区列的不同值计数组合检查
重新分区
不会删除重复项。您必须有一些代码的其他部分没有显示出来,这些部分会影响计数。要获得每个分区的单个文件,请稍微更改代码:。重新分区(1,“创建年”、“创建月”、“创建日”)
我只调用这两个函数-就是这样。没有别的了。