scala - 如何使用 spark 结构化流管理从 kafka 读取的偏移量
问题描述
我有一个 spark 结构化的流作业,需要从 kafka 主题中读取数据并进行一些聚合。该作业需要每天重新启动,但是当它重新启动时,如果我设置startingOffsets="latest"
,我将丢失重新启动时间之间的数据。如果我设置startingOffsets="earliest"
,那么该作业将从主题中读取所有数据,但不会从最后一个流作业离开的位置读取。谁能帮助我如何配置以在最后一个流式作业离开的位置设置偏移量?
我正在使用Spark 2.4.0和kafka 2.1.1,我尝试为写入作业设置检查点位置,但似乎 Spark 不检查 kafka 消息的偏移量,因此它会继续检查最后一个偏移量或第一个偏移量取决于startingOffsets。
这是我的 spark 从 kafka 读取的配置:
val df = spark.readStream
.format("kafka")
.option("kafka.bootstrap.servers", host)
.option("subscribe", topic)
.option("startingOffsets", offset)
.option("enable.auto.commit", "false")
.load()
例如,kafka 主题有 10 条消息,偏移量从 1 到 10,spark 刚刚处理完消息 5,然后重新启动。如何让 spark 继续从消息 5 而不是从 1 或 11 读取?
解决方案
似乎使用一些代码我可以获取我需要的偏移量并将其保存到一些可靠的存储中,例如 cassandra。然后当火花流开始时,我只需要读取保存的偏移量并将其填充到startingOffsets。这是帮助我获得所需偏移量的代码
import org.apache.spark.sql.streaming._
import org.apache.spark.sql.streaming.StreamingQueryListener._
spark.streams.addListener(new StreamingQueryListener() {
override def onQueryStarted(queryStarted: QueryStartedEvent): Unit = {
println("Query started:" + queryStarted.id)
}
override def onQueryTerminated(queryTerminated: QueryTerminatedEvent): Unit = {
println("Query terminated" + queryTerminated.id)
}
override def onQueryProgress(queryProgress: QueryProgressEvent): Unit = {
println("Query made progress")
println("Starting offset:" + queryProgress.progress.sources(0).startOffset)
println("Ending offset:" + queryProgress.progress.sources(0).endOffset)
//Logic to save these offsets
// the logic to save the offset write in here
}
})
推荐阅读
- apache-kafka - kafka流中的不均匀分区分配
- node.js - 如何在 MERN 中使用 multer 上传多个文件输入?
- java - Jhipster 注册中心尝试注册自己
- google-meet - Google Meet:获取会议的当前活跃成员
- svg - 在 SVG 中定位文本元素的字体大小和 x/y 百分比之间有什么关系?
- javascript - Firebase Realtime Database equalTo query for child in increasing keys
- haskell - 使用 IntelliJ-Haskell 插件在 IntelliJ 中创建 Haskell 项目时出错
- docker - 在 AWS Lambda 容器镜像中使用 Gradle 的 shadowJar
- java - Reactor onErrorContinue 运算符是否让原始序列继续?
- powershell - 使用 PowerShell 从证书中检索 KeySpec 值