Pyspark 流式聚合未写入接收器

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/_

我必须处理每天收到的一些文件。信息具有主键(日期、客户端id、操作id)。因此,我创建了一个只将新数据附加到增量表中的流:

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
每秒钟执行一次聚合。而你可能想要一天或是别的什么