Pinot freshness-based readiness stuck with Kafka read_committed on low-volume topics
- Dominant language
- Java
- Stars
- 6.1k
- Forks
- 1.5k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 195
Description
## Summary
We’re running **Apache Pinot 1.3.0** consuming from **Kafka** topics produced by **Flink 1.19 KafkaSink** with `EXACTLY_ONCE` delivery guarantee. Pinot tables use Kafka isolation level `read_committed`.
On **low-volume topics** (can be idle for ~30 minutes), during **server restart** Pinot’s startup readiness using `FreshnessBasedConsumptionStatusChecker` gets stuck forever and never turns `GOOD`.
The freshness-based check falls back to the offset-based check, but that also fails. The log keeps repeating with a stable **`+1` offset gap**.
Manually consuming the last hour of user messages shows the last visible user record offset is **18895**. There is **no record at 18896** visible to a normal consumer.
This blocks server startup readiness and causes restart loops.
## Log example
From: `org.apache.pinot.server.starter.helix.FreshnessBasedConsumptionStatusChecker`
```text
Segment xxx__5__25__20260303T1524Z with freshness 1993405ms has not caught up within min freshness 10000. At offset 18896. Earliest offset 14662. Latest offset 18897.
Segment xxx__5__25__20260303T1524Z with freshness 2003675ms has not caught up within min freshness 10000. At offset 18896. Earliest offset 14662. Latest offset 18897.
Segment xxx__5__25__20260303T1524Z with freshness 2005995ms has not caught up within min freshness 10000. At offset 18896. Earliest offset 14662. Latest offset 18897.
Segment xxx__5__25__20260303T1524Z with freshness 2013937ms has not caught up within min freshness 10000. At offset 18896. Earliest offset 14662. Latest offset 18897.
Segment xxx__5__25__20260303T1524Z with freshness 2024211ms has not caught up within min freshness 10000. At offset 18896. Earliest offset 14662. Latest offset 18897.
```
## What we suspect
It looks like this may be caused by **Kafka transactional markers / control records at the tail**, which are not visible to a normal `read_committed` consumer, but still advance offsets.
That would explain why Pinot keeps waiting at offset `18896` while the latest offset is reported as `18897`, even though no user-visible record exists there.
## Impact
- Server startup readiness never becomes `GOOD`
- Restart loops on affected Pinot servers
- Reproducible on low-throughput / idle topics
## What we tried
- `realtimeFreshnessIdleTimeoutMs`
This worked around the issue for us, but from the documentation/comments it seems this is not recommended to enable in production.
- `enableRealtimeOffsetBasedConsumptionStatusChecker`
This produced the same result.
## Environment
- Apache Pinot: **1.3.0, 1.4.0**
- Kafka producer: **Flink 1.19 KafkaSink**
- Delivery guarantee: `EXACTLY_ONCE`
- Kafka isolation level in Pinot: `read_committed`
## Expected behavior
Pinot server readiness should eventually turn `GOOD` after restart when the stream is caught up from the perspective of visible committed user records, even if Kafka tail offsets include transactional markers/control records.
## Actual behavior
Pinot readiness remains stuck forever because consumption status checking appears to compare against offsets that include non-user-visible transactional/control records.
Contributor guide
Research direction
Start with org.apache.pinot.server.starter.helix.FreshnessBasedConsumptionStatusChecker and compare its freshness-based and offset-based paths using the supplied +1 offset logs. Reproduce with a low-volume Kafka topic using read_committed and Flink EXACTLY_ONCE, then verify that readiness eventually becomes GOOD when the tail contains only transactional control records.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, kafka
- Domain
- databases, distributed-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100