Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.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中保存具有非常大值的数据帧_Apache Spark_Pyspark_Apache Spark Sql - Fatal编程技术网

Apache spark 在Spark中保存具有非常大值的数据帧

Apache spark 在Spark中保存具有非常大值的数据帧,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,使用Spark data frame,我正在执行groupBy操作,以将与键关联的所有值收集到列表中。收集的值的大小可能会有很大的差异。事实上,我正试图通过连接复合键的值以进行后处理来生成“文档” 举例来说,df是一个具有3个字符串列a、B、C的数据帧 df.groupBy(concat($“A”,lit($”,$“B”)。别名(“Key”))。agg(collect_list($“C”)。别名(“值”) 运行此查询以获取两行数据是有效的,这意味着该命令是正确的 但是,当我试图将完整输出保存为压

使用Spark data frame,我正在执行groupBy操作,以将与键关联的所有值收集到列表中。收集的值的大小可能会有很大的差异。事实上,我正试图通过连接复合键的值以进行后处理来生成“文档”

举例来说,df是一个具有3个字符串列a、B、C的数据帧

df.groupBy(concat($“A”,lit($”,$“B”)。别名(“Key”))。agg(collect_list($“C”)。别名(“值”)

运行此查询以获取两行数据是有效的,这意味着该命令是正确的

但是,当我试图将完整输出保存为压缩的CSV或拼花地板时,这个过程失败的原因有几个,包括内存问题(我试图调整)和氪化

我怀疑有些值非常大是个问题。
对于这种情况,是否有最佳做法?

虽然确切知道您会遇到什么错误会有所帮助,但您的问题很可能是因为太多数据进入一行。为了克服这个问题,您可以添加一些带有随机列的人工分区。这样,分组的数据将在多行和多个文件之间共享,从而防止OOM错误的发生。以下是您如何做到这一点:

val df = sc.parallelize(Seq((1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 2)))
    .toDF("A", "B", "C")
你要做的就是这样,C可能会变得太大

df.groupBy("A", "B")
  .agg(collect_list('C))
  .show
+---+---+---------------+                                                       
|  A|  B|collect_list(C)|
+---+---+---------------+
|  1|  2|      [3, 4, 5]|
|  1|  3|            [2]|
+---+---+---------------+
相反,您可以添加一个随机列R以防止C变得太大。数据将按R的多个值进行拆分,从而减少一行中可能包含的数据量。在这里,我使用了3个可能的随机值作为示例,但在您的情况下,应该需要一个更大的值

val new_df = df.withColumn("R", floor(rand()*3)).groupBy("A", "B", "R").agg(collect_list('C) as "C").show
new_df.show
+---+---+---+------+
|  A|  B|  R|     C|
+---+---+---+------+
|  1|  2|  1|   [5]|
|  1|  2|  2|[3, 4]|
|  1|  3|  1|   [2]|
+---+---+---+------+
然后您可以像这样编写分区数据帧

new_df.write.partitionBy("A", "B", "R").parquet("...")

谢谢,这个解决方案有效。我仍然需要在后处理中聚合这些分区。我仍然在想,在spark中是否有更优雅的解决方案来处理(键、文档)?当组合这些值时,我开始出现内存溢出问题,这是不正常的。这取决于。Spark旨在处理分布式文档。如果出现OOM错误,则意味着某些文档太大,无法放入单个工作人员的RAM中。我的建议允许并行处理这些大文档,这就是spark的目的。明白了。不过,在一天结束时,我需要将一组分布式文档重新组合为每个键一个文档。顺便说一句,我刚刚发现这个线程有一个与我类似的问题:你需要它来进一步处理spark或其他大数据工具吗?在这种情况下,包含多个文件的文件夹可以正常工作。因此,您只需要创建文件夹并四处移动文件。