簡體   English   中英

Spark 流式傳輸:保留組中的最新值

[英]Spark streaming: keep the most recent value in a group

我有一個 stream 之類的

+------+-------------------+------+
|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 |
+------+-------------------+------+

我想使用火花流只為每個組保留最近的時間。

用火花 dataframe 我會使用 window function 作為

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")

在火花流中執行相同操作的最佳方法是什么,以及如何以僅存儲最新解決方案的方式保存結果?

更新:我試圖在最近的時間每組只保留一行。 是否可以為此目的使用帶有mapGroupsWithState的狀態轉換?

在 Spark Structured Streaming 中進行聚合時,您需要首先定義一個Window 通過這個Window 操作,您定義了將在哪個時間間隔計算您的聚合(“最大時間,按“組”列分組”)。

假設您計划在 5 分鍾(非滑動)window 內獲得最大時間,那么您將定義:

val df = spark.readStream
  .format("kafka")
  [...]
  .selectExpr("CAST(value AS STRING) as group", "timestamp")

val dfGrouped = df
  .select(
    col("group"),
    col("timestamp"),
    unix_timestamp(col("timestamp"), "yyyy-MM-dd HH:mm:ss").alias("time_unix"))
  .groupBy(col("group"), window($"timestamp", "5 minutes"))
  .agg(max("time_unix").alias("max_time_unix"))
  .withColumn("time", col("max_time_unix").cast(TimestampType))
  .drop("window", "max_time_unix")

需要注意的是,最大值的聚合僅適用於數值,因此,轉換為unix_timestamp ,如上所示。

根據Output Modes ,您可以選擇update模式以僅獲取組上的更新。 確保您的 output 接收器(例如控制台或數據庫)能夠處理更新並且不會創建重復項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM