[improve][broker] Reduce persistent topic backlog check overhead with ManagedCursor.hasBacklog#26058
Conversation
da0836b to
d203c4e
Compare
… ManagedCursor.hasBacklog Motivation: Issue apache#26036 points out that several broker paths only need to know whether a cursor has any backlog, but they currently call getNumberOfEntriesInBacklog(true), which computes an exact backlog count. For boolean decisions in persistent topic paths, this can add unnecessary overhead. Modifications: - Add backward-compatible hasBacklog methods to ManagedCursor, Subscription, and Replicator. - Implement an optimized precise ManagedCursorImpl.hasBacklog() that skips individually deleted ranges and stops as soon as it finds one readable backlog entry. - Use hasBacklog in persistent subscription, replicator, topic migration, and backlog checks instead of computing precise counts for yes/no decisions. - Add managed-ledger tests that compare hasBacklog with the original getNumberOfEntriesInBacklog count semantics across empty, caught-up, mixed ack, cross-ledger, batch-index, reset, recovery, deleted-range-to-tail, negative-counter fallback, and uninitialized mark-delete states. - Add broker tests for subscription delegation, replicator usage, and migration cleanup behavior. Performance impact: This adds a fast existence check for persistent topic backlog paths, avoiding exact backlog counting when callers only need a boolean result. Fixes apache#26036
d203c4e to
e61e5c9
Compare
| } | ||
|
|
||
| @Override | ||
| public boolean hasBacklog(boolean isPrecise) { |
There was a problem hiding this comment.
Please search for all usages of cursor.getNumberOfEntriesInBacklog(boolean) where the result is compared against 0. There seems to be some more usages that need to be addressed.
There was a problem hiding this comment.
Good catch. I updated the remaining backlog presence checks to use hasBacklog(...) while preserving the existing precise/imprecise modes, and added coverage for the updated paths. Please take another look when you have a chance.
There was a problem hiding this comment.
org.apache.pulsar.broker.service.AbstractReplicator#disconnect seems to have one remaining backlog check based on count.
There was a problem hiding this comment.
Good catch, missed that one. Changed.
Replace backlog count comparisons with hasBacklog for boolean presence checks and add deterministic coverage for cursor and subscription backlog semantics.
Replace the remaining replicator disconnect backlog presence check with hasBacklog to avoid computing the exact backlog count for a boolean decision.
Remove a constant backlog field from the replicator disconnect log and make the migration backlog check message more descriptive.
|
btw. I did some analysis with Claude Code about cases where there would be
I guess the backlog check in |
Motivation
Fixes #26036.
Some persistent topic paths only need to know whether backlog exists, but currently call
getNumberOfEntriesInBacklog(...)and compare the returned count with zero. For precise checks, thiscan add unnecessary overhead because the caller does not need the exact backlog count. For imprecise
checks, using a boolean API also better expresses the intent and keeps the call sites consistent.
Modifications
hasBacklogmethods toManagedCursor,Subscription, andReplicator.ManagedCursorImpl.hasBacklog()to short-circuit once it finds one readable backlog entry.hasBacklogmethods to delegate to the managed cursor.hasBacklog(...)in persistent topic, subscription,dispatcher, compactor subscription, and replicator paths while preserving the existing precise or
imprecise mode at each call site.
hasBacklog()/hasBacklog(true)/hasBacklog(false)with the existing backlog count APIs across empty, caught-up, mixed ack,cross-ledger, batch-index, reset, recovery, deleted-range-to-tail, negative-counter fallback, and
uninitialized mark-delete states.
sequences.
lifecycle operations such as skip, reset, expire, and clear backlog.
Performance impact
This reduces persistent topic backlog check overhead by avoiding exact backlog counting when callers only
need a boolean result. In the common precise-check case, the check can stop at the first valid backlog entry.
For existing imprecise checks, the patch preserves the same imprecise mode and only replaces count-based
presence comparisons with the equivalent boolean API.
Verifications
./gradlew :managed-ledger:test --tests org.apache.bookkeeper.mledger.impl.ManagedCursorTest.hasBacklog*./gradlew :pulsar-broker:test --tests org.apache.pulsar.broker.service.persistent.PersistentTopicTest.testHasBacklogTracksRealProduceConsumeAckOrders --tests org.apache.pulsar.broker.service.persistent.PersistentTopicTest.testHasBacklogTracksRealSubscriptionLifecycleOperations./gradlew :managed-ledger:checkstyleMain :managed-ledger:checkstyleTest :pulsar-broker:checkstyleMain :pulsar-broker:checkstyleTest