我使用结构化流来加载来自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|
+------+-----+
+------+-----+
如何将数据集仅保存到一个镶木地板文件? 感谢
答案 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
,这表示批处理间隔。
我希望您可以根据自己的用例调整解决方案。