Skip to content

feat(inkless:consolidation): delayed fetcher to honor minBytes/maxWaitMs#685

Open
jeqo wants to merge 2 commits into
mainfrom
jeqo/kc-278-delayed-consolidation-fetch
Open

feat(inkless:consolidation): delayed fetcher to honor minBytes/maxWaitMs#685
jeqo wants to merge 2 commits into
mainfrom
jeqo/kc-278-delayed-consolidation-fetch

Conversation

@jeqo

@jeqo jeqo commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

The consolidation fetcher previously called Reader.fetch() synchronously on every doWork() iteration regardless of whether data was available. Idle partitions therefore queried the control plane on every loop iteration: it returned empty and the loop ran again. Existing configs diskless.consolidation.fetch.{min.bytes,max.wait.ms} were passed into FetchParams but Reader.fetch() ignored them.

Wrap the fetcher path in DisklessLeaderEndPoint.fetch with a DelayedConsolidationFetch that parks in a new
delayedConsolidationFetchPurgatory until the initial probe sees minBytes of accumulated diskless bytes or maxWaitMs expires. tryComplete runs one cheap findDisklessBatches probe (gated by a CAS so tryCompleteElseWatch's before/after double-check probes only once); onComplete runs the full FetchHandler.handle once. This purgatory has no wake-up sites, so parked ops complete via the maxWaitMs timeout, keeping control-plane pressure bounded regardless of loop rate.

Set the purgatory purgeInterval to 0 (matches delayedRemoteFetchPurgatory) so completed ops release their captured response references immediately for GC. Each completed op pins a Map[TopicIdPartition, FetchPartitionData] of fetched records; without aggressive purging, watch lists accumulate up to fetchPurgatoryPurgeIntervalRequests completed ops and exhaust the heap.

Raise the consolidation fetch defaults now that min.bytes/max.wait.ms are honored: max.bytes 1MB to 10MB (per partition), response.max.bytes 10MB to 64MB (total), min.bytes 1 to 8MB, max.wait.ms 500 to 1000.

See commits for details.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the inkless consolidation fetch path to honor diskless.consolidation.fetch.{min.bytes,max.wait.ms} by introducing a long-poll style delayed operation, reducing control-plane (PG) load when partitions are idle, and adjusts the default fetch sizing knobs accordingly.

Changes:

  • Add DelayedConsolidationFetch and a dedicated delayedConsolidationFetchPurgatory, then use it from DisklessLeaderEndPoint.fetch to park idle fetches until minBytes is reached or maxWaitMs expires.
  • Increase consolidation fetch defaults (max.bytes, response.max.bytes, min.bytes, max.wait.ms) and update the corresponding config assertions.
  • Add unit tests covering delayed-fetch completion/parking/expiration/error behavior.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
server-common/src/main/java/org/apache/kafka/server/config/ServerConfigs.java Raises default consolidation fetch sizing/wait thresholds now that they’re honored.
docs/inkless/configs.rst Updates config docs text (currently introduces two encoding artifacts flagged in comments).
core/src/test/scala/io/aiven/inkless/consolidation/DisklessLeaderEndPointTest.scala Updates expected defaults for consolidation fetch config values.
core/src/test/scala/io/aiven/inkless/consolidation/DelayedConsolidationFetchTest.scala Adds new test coverage for delayed consolidation fetch semantics.
core/src/main/scala/kafka/server/ReplicaManager.scala Adds delayedConsolidationFetchPurgatory, documents findDisklessBatches behavior, and shuts down the new purgatory.
core/src/main/scala/io/aiven/inkless/consolidation/DisklessLeaderEndPoint.scala Routes consolidation fetch through the new delayed-fetch purgatory path.
core/src/main/scala/io/aiven/inkless/consolidation/DelayedConsolidationFetch.scala Implements delayed operation: single metadata probe, park until timeout, then perform real fetch and return results/errors.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/inkless/configs.rst Outdated
Comment thread docs/inkless/configs.rst Outdated
@jeqo
jeqo force-pushed the jeqo/kc-278-delayed-consolidation-fetch branch from 0b2edd3 to 68b5ecc Compare July 6, 2026 11:48
@jeqo jeqo changed the title feat(inkless:consolidation): long-poll fetcher to stop hammering PG on idle topics feat(inkless:consolidation): delayed fetcher to honor minBytes/maxWaitMs Jul 6, 2026
@jeqo
jeqo force-pushed the jeqo/kc-278-delayed-consolidation-fetch branch from 68b5ecc to 82a137c Compare July 6, 2026 14:10
@jeqo
jeqo requested a review from Copilot July 6, 2026 14:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Comment thread core/src/main/scala/kafka/server/ReplicaManager.scala Outdated
@jeqo
jeqo force-pushed the jeqo/kc-278-delayed-consolidation-fetch branch 3 times, most recently from a19809f to f1d9adb Compare July 6, 2026 17:24
@jeqo
jeqo requested a review from Copilot July 6, 2026 17:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

@jeqo
jeqo force-pushed the jeqo/kc-278-delayed-consolidation-fetch branch from f1d9adb to 4644e0b Compare July 6, 2026 17:36
@jeqo
jeqo marked this pull request as ready for review July 6, 2026 18:37
@jeqo
jeqo force-pushed the jeqo/kc-278-delayed-consolidation-fetch branch 2 times, most recently from aefe1a6 to 1b430e5 Compare July 7, 2026 07:46
@jeqo
jeqo requested review from AnatolyPopov and removed request for AnatolyPopov July 7, 2026 07:47
@jeqo
jeqo force-pushed the jeqo/kc-278-delayed-consolidation-fetch branch 3 times, most recently from f8eddfc to caa7461 Compare July 8, 2026 09:46
@jeqo
jeqo requested review from EelisK and viktorsomogyi July 13, 2026 11:08
viktorsomogyi
viktorsomogyi previously approved these changes Jul 14, 2026

@viktorsomogyi viktorsomogyi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good from my side, but @AnatolyPopov mentioned yesterday that he'd like to take a look, so I'm not merging yet to give him a chance.

jeqo added 2 commits July 17, 2026 13:03
…s per batch

buildFetch reserves per-partition maxBytes = segment.bytes - max.message.bytes so the follower's single append cannot exceed the destination segment. That headroom assumes find_batches overshoots by at most one physical batch (<= max.message.bytes), which is false under commit_file_v2: find_batches limits at coordinate granularity and always admits the coordinate that crosses maxBytes, and a coalesced coordinate can contain many byte-contiguous physical batches whose total exceeds max.message.bytes (up to produce.buffer.max.bytes). The admitted coordinate, or even the first always-admitted one, can push the block past a small segment.bytes and fail the follower append with RecordBatchTooLargeException. This is reachable when segment.bytes is tuned small (e.g. for eager tiering).

Enforce the reserved budget at physical-batch granularity in fetch() via clampRecordsToSegment, restoring the classic invariant returned <= maxBytes + one physical batch (<= max.message.bytes) <= segment.bytes. Batches with lastOffset < fetchOffset are dropped so a re-fetch into a coalesced coordinate that a prior fetch truncated mid-run does not re-serve the already-appended prefix; at least one batch is always emitted for progress. When nothing is trimmed the original records are returned unchanged to preserve the ConcatenatedRecords zero-copy path.
@jeqo
jeqo force-pushed the jeqo/kc-278-delayed-consolidation-fetch branch from caa7461 to a604f91 Compare July 17, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants