Spark stays in charge
Komiter does not replace the checkpoint. Spark keeps full control of its offsets; a failed commit never affects the query.
Your Spark streaming jobs, leaving a trail Kafka can follow.
Spark Structured Streaming never tells Kafka where it got to. Komiter does — so consumer lag shows up in every tool your team already runs.
The problem
Spark keeps its offsets in its own checkpoint. There is no consumer group, no lag, and no alert when the job falls behind — until someone notices the data is hours old.
kafka-consumer-groups has nothing to describeSee it
Captured from a live run against a real broker. Nothing mocked up.
$ kafka-consumer-groups --bootstrap-server localhost:9092 \
--describe --group komiter-demo
GROUP TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG
komiter-demo orders 0 220241 257046 36805
komiter-demo orders 1 221664 260848 39184
komiter-demo orders 2 221786 258621 36835
komiter-demo orders 3 216392 255768 39376
komiter-demo orders 4 220246 257984 37738
komiter-demo orders 5 223661 259733 36072
Get started
spark.sql.streaming.streamingQueryListeners=com.komiter.Komiter
spark.readStream .format("kafka") .option("kafka.bootstrap.servers", "localhost:9092") .option("subscribe", "orders") .option("kafka.consumer.commit.groupid", "my-group") // the only new line .load()
Sources without that option are left alone, so you can adopt it one query at a time.
How it works
Komiter does not replace the checkpoint. Spark keeps full control of its offsets; a failed commit never affects the query.
It writes into the same place any consumer would, so existing tooling picks it up with no configuration.
Every source commits to its own group, even when one source spans several topics and others sit idle.
Scala, the Kafka client and the Java target are copied from Spark's own pom for each release. Nothing to collide with.
24 Spark releases supported · 3.5.0 to 4.3.0 · Scala 2.12 & 2.13 · Apache 2.0