Pyspark 流式聚合未写入接收器
我必须处理每天收到的一些文件。信息具有主键(日期、客户端id、操作id)。因此,我创建了一个只将新数据附加到增量表中的流:Pyspark 流式聚合未写入接收器,pyspark,spark-structured-streaming,azure-databricks,delta-lake,Pyspark,Spark Structured Streaming,Azure Databricks,Delta Lake,我必须处理每天收到的一些文件。信息具有主键(日期、客户端id、操作id)。因此,我创建了一个只将新数据附加到增量表中的流: operations\ .repartition('date')\ .writeStream\ .outputMode('append')\ .trigger(once=True)\ .option("checkpointLocation", "/mnt/sandbox/operations/_
operations\
.repartition('date')\
.writeStream\
.outputMode('append')\
.trigger(once=True)\
.option("checkpointLocation", "/mnt/sandbox/operations/_chk")\
.format('delta')\
.partitionBy('date')\
.start('/mnt/sandbox/operations')
这很好,但我需要按(日期、客户端id)对这些信息进行汇总,所以我创建了另一个从这个操作表到新表的流。因此,我尝试将我的date
字段转换为时间戳,以便在编写聚合流时使用append模式:
import pyspark.sql.functions as F
summarized= spark.readStream.format('delta').load('/mnt/sandbox/operations')
summarized= summarized.withColumn('timestamp_date',F.to_timestamp('date'))
summarized= summarized.withWatermark('timestamp_date','1 second').groupBy('client_id','date','timestamp_date').agg(<lot of aggs>)
summarized\
.repartition('date')\
.writeStream\
.outputMode('append')\
.option("checkpointLocation", "/mnt/sandbox/summarized/_chk")\
.trigger(once=True)\
.format('delta')\
.partitionBy('date')\
.start('/mnt/sandbox/summarized')
导入pyspark.sql.F函数
summated=spark.readStream.format('delta').load('/mnt/sandbox/operations'))
Summated=Summated.withColumn('timestamp_date',F.to_timestamp('date'))
Summated=Summated.withWatermark('timestamp_date','1秒').groupBy('client_id','date','timestamp_date').agg()
总结\
.重新分区(“日期”)\
.writeStream\
.outputMode('append')\
.选项(“检查点位置”,“/mnt/sandbox/summated/_chk”)\
.trigger(一次=真)\
.format('delta')\
.partitionBy('日期')\
.start(“/mnt/sandbox/summated”)
此代码可以运行,但不会在接收器中写入任何内容
为什么它不将结果写入接收器?这里可能有两个问题 格式错误的日期输入 我很确定问题出在
F.to_timestamp('date')
上,它由于输入格式错误而给出null
如果是这样,带水印('timestamp_date','1秒')
永远无法“物化”,也不会触发任何输出
你能spark.read.format('delta').load('/mnt/sandbox/operations')
(到read
而不是readStream
)并看看转换是否给出了正确的值吗
spark.\
read.\
format('delta').\
load('/mnt/sandbox/operations').\
withColumn('timestamp_date',F.to_timestamp('date')).\
show
所有行使用相同的时间戳
也有可能withWatermark('timestamp_date','1秒')
没有完成(因此“完成”聚合),因为所有行都来自同一个时间戳,因此时间不会提前
您应该有具有不同时间戳的行,这样每个时间戳日期的时间概念可以超过延迟窗口。这里可能有两个问题 格式错误的日期输入 我很确定问题出在
F.to_timestamp('date')
上,它由于输入格式错误而给出null
如果是这样,带水印('timestamp_date','1秒')
永远无法“物化”,也不会触发任何输出
你能spark.read.format('delta').load('/mnt/sandbox/operations')
(到read
而不是readStream
)并看看转换是否给出了正确的值吗
spark.\
read.\
format('delta').\
load('/mnt/sandbox/operations').\
withColumn('timestamp_date',F.to_timestamp('date')).\
show
所有行使用相同的时间戳
也有可能withWatermark('timestamp_date','1秒')
没有完成(因此“完成”聚合),因为所有行都来自同一个时间戳,因此时间不会提前
您应该有具有不同时间戳的行,这样每个时间戳日期的时间概念可以超过延迟时间窗口。数据的频率是多少?您的
timestamp\u date
列每1秒将存在多少行?数据是每日的,因为timestamp\u date
是从date
转换而来的,我认为所有行都将在同一秒中,这是不正确的。我认为您不太了解如何使用窗口
功能,因为摘要
是空的,所以它的可能副本不会写入接收器。实际上,您是在说,groupby
每秒钟执行一次聚合。然而,你可能想按天或其他方式分组数据的频率是多少?您的timestamp\u date
列每1秒将存在多少行?数据是每日的,因为timestamp\u date
是从date
转换而来的,我认为所有行都将在同一秒中,这是不正确的。我认为您不太了解如何使用窗口
功能,因为摘要
是空的,所以它的可能副本不会写入接收器。实际上,您是在说,groupby
每秒钟执行一次聚合。而你可能想要一天或是别的什么