Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark Spark:操作所有特定RDD或数据帧分区的数据_Apache Spark_Pyspark_Apache Spark Sql_Partitioning_Pyspark Sql - Fatal编程技术网

Apache spark Spark:操作所有特定RDD或数据帧分区的数据

Apache spark Spark:操作所有特定RDD或数据帧分区的数据,apache-spark,pyspark,apache-spark-sql,partitioning,pyspark-sql,Apache Spark,Pyspark,Apache Spark Sql,Partitioning,Pyspark Sql,我在文档中发现了一些帖子、文章、参考资料等,它们暗示了可以使用foreachPartition访问特定分区的想法。然而,我还没有弄清楚如何处理给定分区中的所有数据 我的目标是从数据库中选择一些数据,对其进行操作,按列中的唯一值进行分区,然后将这些分区中的每个分区作为一个特定命名的jsonl文件写入s3,供另一个系统访问 重新分区=myDataframe.repartitionprocessed\u日期 已重新分区。foreachPartitionwritePartitionToS3 我已经尝试了

我在文档中发现了一些帖子、文章、参考资料等,它们暗示了可以使用foreachPartition访问特定分区的想法。然而,我还没有弄清楚如何处理给定分区中的所有数据

我的目标是从数据库中选择一些数据,对其进行操作,按列中的唯一值进行分区,然后将这些分区中的每个分区作为一个特定命名的jsonl文件写入s3,供另一个系统访问

重新分区=myDataframe.repartitionprocessed\u日期 已重新分区。foreachPartitionwritePartitionToS3 我已经尝试了很多方法来解析这些数据,但似乎我只能在foreachPartition中获得单个元组,而分区本身没有边界,以便有效地分离这些数据

def WRITEPARTIONSTOS3分区: 对于分区中的行: pprint行 为简洁起见,删除了几列后生成:

行实体_id=u'2315183'。。。处理日期=datetime.date2015,3, 25行实体_id=u'2315183'。。。处理日期=datetime.date2015, 3,25行实体_id=u'2315183'。。。 已处理的_date=datetime.date2015,3,25行实体_id=u'2315183', ... 处理日期=datetime.date2015,3,25

分区的定义也可能不像我想象的那样,但我知道有一个内置的DataFrameWriter可以按分区编写,但我不能使用它。我确实需要能够生成这样的命名文件,而不是part xxx格式:

s3a://.jsonl

我以这样一种方式划分数据,分区的大小将相对较小,每个处理的_日期,每个作为自己的数据帧选择的实体,一个分区,所以这不是一个问题,但我也不想收集一个节点上的所有内容来解析分区列表,因为我想并行地将文件写入s3

更新: 我最终通过获取唯一值,然后根据这些值过滤原始数据集,实际解决了我的案例中的问题。请记住,如果数据集非常大,您永远不会希望这样做,但我有这个选项,因为我在循环中创建了小的ish数据帧,从数据库中进行选择,然后处理这些数据块

获取当前唯一值的列表 在“处理日期”列中 uniqueProcessedDates=myDataframe。选择“处理日期”\ .distinct.rdd.maplambda r:r[0]。收集 对于每个唯一的处理日期,我们希望 过滤记录,然后写入它们 对于uniqueProcessedDates中的值: sortedRowsThisProcessedDate=myDataframe.filterpostgresDF.processed_日期==date 一些自定义函数来写入数据 WriteProcessedDataTestOS3SortedRowsThisProcessedDate.collect
尽管如此,我相信这在很多方面都是非常低效的。我正在考虑的一件事是按照需要写入每个文件的确切值集重新划分每个RDD,因为对s3的写入必须以原子方式完成。我认为,除此之外,还可能有助于避免在写入数据之前从多个节点收集数据。

没有可访问的边界。DataFrame.repartition使用哈希分区器来洗牌数据,因此行的出现没有更广泛的意义。在这里,您可以假设特定处理日期的所有记录都位于特定分区上

通过添加sortWithinPartitions,可以稍微改善这种情况:

myDataframe .重新分区已处理\u日期 .sortWithinPartitionsprocessed_日期 能够逐个访问单个日期的所有记录

另一个可能的改进是使用orderBy方法:

myDataframe.orderByprocessed\u日期 这将导致连续日期,但仍然无法访问边界

在这两种情况下,当在分区上迭代时,必须手动检测边界

最后,如果您想要真正的控制,请使用RDD和repartitionAndSortWithinPartitions方法。这将为您提供对数据分布的细粒度控制。您可以定义partitionFunc以特定的方式分发数据,因此预先没有分区边界


DataFrameWriter.partitionBy使用了不同的机制,这在这里对您没有用处。

这确实让我重新开始工作,尽管我最终使用了不同的解决方案。我认为处理数据的repartitionAndSortWithinPartitions方法可能是最灵活的,尽管我花了一些时间摸索如何使用partitionFunc操作数据。我还没有找到一个使用这种方法的真正清晰和简单的例子。