簡體   English   中英

在 Spark Structured Streaming 中外部連接兩個數據集(不是數據幀)

[英]Outer join two Datasets (not DataFrames) in Spark Structured Streaming

我有一些代碼將兩個流數據DataFrames連接DataFrames並輸出到控制台。

val dataFrame1 =
  df1Input.withWatermark("timestamp", "40 seconds").as("A")

val dataFrame2 =
  df2Input.withWatermark("timestamp", "40 seconds").as("B")

val finalDF: DataFrame = dataFrame1.join(dataFrame2,
      expr(
        "A.id = B.id" +
          " AND " +
          "B.timestamp >= A.timestamp " +
          " AND " +
          "B.timestamp <= A.timestamp + interval 1 hour")
      , joinType = "leftOuter")
finalDF.writeStream.format("console").start().awaitTermination()

我現在想要的是重構這部分以使用Datasets ,這樣我就可以進行一些compile-time檢查。

所以我嘗試的非常簡單:

val finalDS: Dataset[(A,B)] = dataFrame1.as[A].joinWith(dataFrame2.as[B],
      expr(
        "A.id = B.id" +
          " AND " +
          "B.timestamp >= A.timestamp " +
          " AND " +
          "B.timestamp <= A.timestamp + interval 1 hour")
      , joinType = "leftOuter")
finalDS.writeStream.format("console").start().awaitTermination()

但是,這會產生以下錯誤:

org.apache.spark.sql.AnalysisException:不支持兩個流數據幀/數據集之間的流外連接,如果連接鍵中沒有水印,或者可空端沒有水印和適當的范圍條件;;

可以看到, join代碼沒有改變,所以兩邊都有水印和范圍條件。 唯一的變化是使用Dataset API 而不是DataFrame

另外,當我使用內join時也很好:

val finalDS: Dataset[(A,B)] = dataFrame1.as[A].joinWith(dataFrame2.as[B],
          expr(
            "A.id = B.id" +
              " AND " +
              "B.timestamp >= A.timestamp " +
              " AND " +
              "B.timestamp <= A.timestamp + interval 1 hour")
          )
    finalDS.writeStream.format("console").start().awaitTermination()

有誰知道這怎么會發生?

好吧,當你使用joinWith方法而不是join你依賴於不同的實現,看起來這個實現不支持leftOuter join用於流式數據集。

您可以使用官方文檔的水印部分檢查外部聯接 方法join不使用joinWith 請注意,結果類型將是DataFrame 這意味着您很可能必須手動映射字段

val finalDS = dataFrame1.as[A].join(dataFrame2.as[B],
    expr(
      "A.key = B.key" +
        " AND " +
        "B.timestamp >= A.timestamp " +
        " AND " +
        "B.timestamp <= A.timestamp + interval 1 hour"),
    joinType = "leftOuter").select(/* useful fields */).as[C]

如果您在這里了解為什么會出現此異常

org.apache.spark.sql.AnalysisException: Stream-stream outer join between two streaming DataFrame/Datasets is not supported without a watermark in the join keys, or a watermark on the nullable side and an appropriate range condition;;

當您將水印引入連接並且 Spark 3 已經支持流連接時仍然存在,您可能在連接后添加了水印,但 Spark 希望您在每個流的連接之前添加水印!

暫無
暫無

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

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