Apache spark Spark streaming:保留组中的最新值
我有一条小溪Apache spark Spark streaming:保留组中的最新值,apache-spark,spark-structured-streaming,spark-streaming-kafka,Apache Spark,Spark Structured Streaming,Spark Streaming Kafka,我有一条小溪 +------+-------------------+------+ |group | time| label| +------+-------------------+------+ | a|2020-01-01 10:49:00|red | | a|2020-01-01 10:51:00|yellow| | a|2020-01-01 12:49:00|blue | | b|2020-01-01 12:44:00
+------+-------------------+------+
|group | time| label|
+------+-------------------+------+
| a|2020-01-01 10:49:00|red |
| a|2020-01-01 10:51:00|yellow|
| a|2020-01-01 12:49:00|blue |
| b|2020-01-01 12:44:00|red |
| b|2020-01-01 12:46:00|blue |
| c|2020-01-01 12:46:00|green |
+------+-------------------+------+
我想使用spark streaming只为每个组保留最近的时间
对于spark数据帧,我将使用窗口函数作为
val window = {
Window
.partitionBy("group")
.orderBy($"time".desc)
}
df
.withColumn("rn",row_number.over(window))
.filter("rn = 1")
.drop("rn")
.show()
或者
df
.orderBy($"time".desc)
.dropDuplicates("group")
在spark streaming中执行相同操作的最佳方式是什么?如何以只存储最新解决方案的方式保存结果
更新:
我试图在最近的时间里每组只保留一行。是否可以将有状态转换与
mapGroupsWithState
一起使用?在Spark Structured Streaming中进行聚合时,您需要首先定义一个窗口。通过这一点,您可以定义计算聚合的时间间隔(“最大时间,按列“组”分组”)
假设您计划在5分钟(非滑动)窗口内获得最大时间,那么您将定义:
val df=spark.readStream
.格式(“卡夫卡”)
[...]
.selectExpr(“转换(值为字符串)为组”,“时间戳”)
val df=df
.选择(
col(“集团”),
col(“时间戳”),
unix时间戳(“时间戳”),“yyyy-MM-dd-HH:MM:ss”)。别名(“时间unix”))
.groupBy(列(“组”),窗口($“时间戳”,“5分钟”)
.agg(max(“time\u unix”).别名(“max\u time\u unix”))
.withColumn(“time”,col(“max_time_unix”).cast(TimestampType))
.drop(“窗口”、“最大时间”)
需要注意的是,最大值上的聚合仅适用于数值,因此,转换为unix\u时间戳
,如上所示
根据,然后您可以选择update
模式以仅获取组的更新。确保您的输出接收器(如控制台或数据库)能够处理更新而不创建重复项。在Spark Structured Streaming中进行聚合时,您需要首先定义一个窗口。通过这一点,您可以定义计算聚合的时间间隔(“最大时间,按列“组”分组”)
假设您计划在5分钟(非滑动)窗口内获得最大时间,那么您将定义:
val df=spark.readStream
.格式(“卡夫卡”)
[...]
.selectExpr(“转换(值为字符串)为组”,“时间戳”)
val df=df
.选择(
col(“集团”),
col(“时间戳”),
unix时间戳(“时间戳”),“yyyy-MM-dd-HH:MM:ss”)。别名(“时间unix”))
.groupBy(列(“组”),窗口($“时间戳”,“5分钟”)
.agg(max(“time\u unix”).别名(“max\u time\u unix”))
.withColumn(“time”,col(“max_time_unix”).cast(TimestampType))
.drop(“窗口”、“最大时间”)
需要注意的是,最大值上的聚合仅适用于数值,因此,转换为unix\u时间戳
,如上所示
根据,然后您可以选择update
模式以仅获取组的更新。确保您的输出接收器(如控制台或数据库)能够处理更新,而不是创建重复项。谢谢您的帮助。无论如何,在代码列中,“label”被丢弃。如何包含它?在更新/完成模式下,禁止流连接。您有两个选项来包含列“label”:将其作为groupBy条件使用,或对其应用任何聚合逻辑。我明白您的意思。然而,我试图实现的是为每个组只保留最新的行,因此我无法在该列上执行任何聚合。我想人们应该以某种方式比较每个组的时间戳对,并丢弃较旧的时间戳,然后继续迭代,直到只剩下一行,或者类似的东西。谢谢帮助。无论如何,在代码列中,“label”被丢弃。如何包含它?在更新/完成模式下,禁止流连接。您有两个选项来包含列“label”:将其作为groupBy条件使用,或对其应用任何聚合逻辑。我明白您的意思。然而,我试图实现的是为每个组只保留最新的行,因此我无法在该列上执行任何聚合。我想人们应该以某种方式比较每个组的时间戳对,并丢弃较旧的时间戳,并以迭代方式继续,直到只剩下一行,或者类似的内容