从多个 Kafka 主题读取 Spark 结构化流应用程序

jam*_*ann 11 apache-kafka apache-spark spark-structured-streaming

我有一个 Spark 结构化流应用程序 (v2.3.2),它需要从许多 Kafka 主题中读取数据,进行一些相对简单的处理(主要是聚合和一些连接)并将结果发布到许多其他 Kafka 主题。因此在同一个应用程序中处理多个流。

我想知道如果我只设置 1 个订阅多个主题的直接 readStream,然后使用选择拆分流,那么从资源的角度(内存、执行程序、线程、Kafka 侦听器等)是否会有所不同,而不是 1每个主题的 readStream。

就像是

df = spark.readStream.format("kafka").option("subscribe", "t1,t2,t3")
...
t1df = df.select(...).where("topic = 't1'")...
t2df = df.select(...).where("topic = 't2'")...
Run Code Online (Sandbox Code Playgroud)

对比

t1df = spark.readStream.format("kafka").option("subscribe", "t1")
t2df = spark.readStream.format("kafka").option("subscribe", "t2")
Run Code Online (Sandbox Code Playgroud)

一个比另一个更“有效”吗?我找不到任何关于这是否有所作为的文档。

谢谢!

Joe*_*den 5

每个操作都需要完整的沿袭执行。你最好把它分成三个单独的 kafka 读取。否则,您将阅读每个主题 N 次,其中 N 是写入次数。

我真的不建议这样做,但如果您想将所有主题放入同一个阅读中,请执行以下操作:

streamingDF.writeStream.foreachBatch { (batchDF: DataFrame, batchId: Long) =>
  batchDF.persist()
  batchDF.filter().write.format(...).save(...)  // location 1
  batchDF.filter().write.format(...).save(...)  // location 2
  batchDF.unpersist()
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为你的第一句话极大地提高了我对 Spark 结构化流中发生的事情的直觉。当从“最后”看它时,很明显永远不应该在执行的沿袭中包含不必要的依赖项。感谢您的洞察力! (2认同)