Spark Structured Streaming写入镶木地板会创建如此多的文件

时间:2017-02-21 06:49:42

标签: apache-spark spark-streaming parquet

我使用结构化流来加载来自kafka的消息,做一些聚合然后写入镶木地板文件。问题是,只有来自kafka的100条消息创建了大量的镶木地板文件(800个文件)。

聚合部分是:

return model
            .withColumn("timeStamp", col("timeStamp").cast("timestamp"))
            .withWatermark("timeStamp", "30 seconds")
            .groupBy(window(col("timeStamp"), "5 minutes"))
            .agg(
                count("*").alias("total"));

查询:

StreamingQuery query = result //.orderBy("window")
            .writeStream()
            .outputMode(OutputMode.Append())
            .format("parquet")
            .option("checkpointLocation", "c:\\bigdata\\checkpoints")
            .start("c:\\bigdata\\parquet");

使用spark加载其中一个镶木地板文件时,它显示为空

+------+-----+
|window|total|
+------+-----+
+------+-----+

如何将数据集仅保存到一个镶木地板文件? 感谢

1 个答案:

答案 0 :(得分:1)

我的想法是使用Spark结构化流技术来消耗Azure Even Hub中的事件,然后将它们以镶木地板格式存储在存储中。

我终于弄清楚了如何处理许多创建的小文件。 Spark版本2.4.0。

这是我查询的样子

dfInput
  .repartition(1, col('column_name'))
  .select("*")
  .writeStream
  .format("parquet")
  .option("path", "adl://storage_name.azuredatalakestore.net/streaming")
  .option("checkpointLocation", "adl://storage_name.azuredatalakestore.net/streaming_checkpoint")
  .trigger(processingTime='480 seconds')
  .start()

结果,我每480秒在存储位置上创建了一个文件。 为了弄清楚文件大小和文件数量之间的平衡以避免OOM错误,只需使用两个参数:分区数和processingTime,这表示批处理间隔。

我希望您可以根据自己的用例调整解决方案。