Apache spark DataFrame partitionBy到单个拼花地板文件(每个分区)
我想重新分区/合并我的数据,以便将其保存到每个分区的一个拼花文件中。我还想使用Spark SQL partitionBy API。所以我可以这样做:Apache spark DataFrame partitionBy到单个拼花地板文件(每个分区),apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,我想重新分区/合并我的数据,以便将其保存到每个分区的一个拼花文件中。我还想使用Spark SQL partitionBy API。所以我可以这样做: df.coalesce(1) .write .partitionBy("entity", "year", "month", "day", "status") .mode(SaveMode.Append) .parquet(s"$location") 我已经测试过了,它的性能似乎不太好。这是因为数据集中只有一个分区要
df.coalesce(1)
.write
.partitionBy("entity", "year", "month", "day", "status")
.mode(SaveMode.Append)
.parquet(s"$location")
我已经测试过了,它的性能似乎不太好。这是因为数据集中只有一个分区要处理,所有文件的分区、压缩和保存都必须由一个CPU核心完成
在调用coalesce之前,我可以重写它来手动进行分区(例如使用具有不同分区值的过滤器)
但是使用标准的Spark SQL API有更好的方法吗?顾名思义:
合并(numPartitions:Int):数据帧
返回一个新的DataFrame,该DataFrame正好包含numPartitions分区
您可以使用numPartitions参数来减少RDD/DataFrame中的分区数。它有助于在过滤大数据集后更高效地运行操作
关于您的代码,它的性能不好,因为您实际执行的是:
coalesce
实际上会洗牌网络上的所有数据,这也可能导致性能损失我希望这有帮助 我遇到了完全相同的问题,我找到了一种方法,使用
DataFrame.repartition()
。使用coalesce(1)
的问题是,并行度下降到1,最好的情况下速度很慢,最坏的情况下会出错。增加这个数字也无济于事——如果使用coalesce(10)
可以获得更多的并行性,但最终每个分区会有10个文件
要在不使用coalesce()
的情况下为每个分区获取一个文件,请使用repartition()
并使用您希望输出分区的列。因此,在您的情况下,请执行以下操作:
import spark.implicits._
df.repartition($"entity", $"year", $"month", $"day", $"status").write.partitionBy("entity", "year", "month", "day", "status").mode(SaveMode.Append).parquet(s"$location")
一旦我这样做了,我会得到每个输出分区一个拼花文件,而不是多个文件
我在Python中测试了这一点,但我认为在Scala中应该是相同的。您好,谢谢您的回复。我同意联合会有代价。在我当前的代码中,我手动对数据进行分区,然后在每个运行良好的分区上调用coalesce和save。但是我不想自己一步一步地编写分区,而是想使用正确的API。但在这样做时,联合必须先于分裂。这就是我被卡住的地方。但是你正在做的是把所有的东西都放在一个分区中,然后是分区比,你应该只是分区比,而不是分区比,但是我最终得到了很多文件。我想限制创建的拼花地板文件的数量。我每分钟传输并保存一次,所以每个分区已经有1440个文件。我不想让它成倍增加。好吧,让我这样说,您的代码将为每个分区向文件系统(本地或HDFS)写入一个拼花文件。这意味着,如果你有10个不同的实体和3个不同的年份,每个12个月,等等,你可能会创建1440个文件。我仍然不知道如何使用标准API有效地将数据保存到每个分区的一个拼花文件中,所以我不认为它回答了这个问题。你找到解决方案了吗?我猜@PatrickMcGloin没有报告,但这很有效,我会鼓励Patrick接受答案。@GlennieHellesSindholt-你是对的。答案被接受。感谢用户3033652。请注意,在scala 2.0中,需要提供一个新的org.apache.spark.sql.Column(“实体”)等作为参数repartition@morpheus或者干脆
$“entity”
。使用Spark 1.6,这非常适合拼花地板。然而,使用Avro,我仍然会在每个分区上有多个文件。