簡體   English   中英

Spark 3 結構化流在 Kafka 源代碼中使用 maxOffsetsPerTrigger 和 Trigger.Once

[英]Spark 3 structured streaming use maxOffsetsPerTrigger in Kafka source with Trigger.Once

我們需要在 Kafka 源代碼中使用maxOffsetsPerTrigger和結構化流中的Trigger.Once()但基於此問題,它似乎在 spark 3 中讀取allAvailable 。在這種情況下有沒有辦法實現速率限制?

這是 spark 3 中的示例代碼:

def options: Map[String, String] = Map(
  "kafka.bootstrap.servers" -> conf.getStringSeq("bootstrapServers").mkString(","),
  "subscribe" -> conf.getString("topic")
) ++
  Option(conf.getLong("maxOffsetsPerTrigger")).map("maxOffsetsPerTrigger" -> _.toString)
val streamingQuery = sparkSession.readStream.format("kafka").options(options)
  .load
  .writeStream
  .trigger(Trigger.Once)
  .start()

沒有其他方法可以正確設置速率限制。 如果maxOffsetsPerTrigger不適用於使用Once觸發器的流作業,您可以執行以下操作以獲得相同的結果:

  1. 選擇另一個觸發器並使用maxOffsetsPerTrigger來限制速率並在處理完所有數據后手動終止此作業。

  2. 在使作業成為批處理作業時使用選項startingOffsetsendingOffsets 重復直到處理完主題中的所有數據。 但是, 這里詳述了“RunOnce 模式下的流式處理優於批處理”是有原因的。

最后一個選擇是查看鏈接的拉取請求並自行編譯 Spark。

這是我們“解決”這個問題的方法。 這基本上是mike在接受的答案中寫的方法。

在我們的例子中,消息的大小變化很小,因此我們知道處理一個批處理需要多少時間。 所以簡而言之,我們:

  • Trigger.Once()更改為 Trigger.ProcessingTime Trigger.ProcessingTime(<ms>)因為maxOffsetsPerTrigger適用於此模式
  • 通過調用awaitTermination(<ms>)來模擬Trigger.Once()來終止這個正在運行的查詢
  • 將處理間隔設置為大於終止間隔,以便恰好一個“批次”適合處理

val kafkaOptions = Map[String, String](
      "kafka.bootstrap.servers" -> "localhost:9092",
      "failOnDataLoss" -> "false",
      "subscribePattern" -> "testTopic",
      "startingOffsets" -> "earliest",
      "maxOffsetsPerTrigger" -> "10",  // "batch" size
    )

val streamWriterOptions = Map[String, String](
    "checkpointLocation" -> "path/to/checkpoints",
  )

val processingInterval = 30000L
val terminationInterval = 15000L

sparkSession
      .readStream
      .format("kafka")
      .options(kafkaOptions)
      .load()
      .writeStream
      .options(streamWriterOptions)
      .format("Console")
      .trigger(Trigger.ProcessingTime(processingInterval))
      .start()
      .awaitTermination(terminationInterval)

這是可行的,因為將根據maxOffsetsPerTrigger限制讀取和處理第一批。 說,在 10 秒內。 然后開始處理第二批,但它在大約 5 秒后在操作中間終止,並且從未達到設定的 30 秒標記。 但它正確地存儲了偏移量。 在下一次運行中拾取並處理這個“殺死”的批次。

這種方法的一個缺點是您必須大致知道處理一個“批次”需要多少時間——如果您將terminationInterval設置得太低,作業的 output 將始終為零。

當然,如果您不關心在一次運行中處理的批次的確切數量,您可以輕松地將processingInterval調整為比terminationInterval小幾倍。 在這種情況下,您可以在一個 go 中處理不同數量的批次,但仍然遵守maxOffsetsPerTrigger的值。

暫無
暫無

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

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