Repository navigation
Add subscription stall diagnostics and reduce WAL prefetch overhead - #18808
Merged
Merged
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #18808 +/- ##
============================================
+ Coverage 45.82% 45.86% +0.04%
Complexity 712 712
============================================
Files 5498 5502 +4
Lines 397637 398740 +1103
Branches 51765 51954 +189
============================================
+ Hits 182235 182902 +667
- Misses 215402 215838 +436 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
3 of 4 tasks
3 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Consensus subscription queues can stop delivering data while WAL lag remains positive. Poll/progress timestamps alone do not show gaps between data events, ongoing prefetch work, or allocator pressure. Periodic statistics pre-read WAL before pending delivery, per-entry pending cursor advances repeatedly inspect the same WAL footer, and Tablet memory rejection recreates the iterator and rescans the retained prefix. Add delivery/prefetch timing, allocator diagnostics, and DEBUG tracing, and remove these redundant WAL operations while preserving retry data and replay progress.
Behavior and metric semantics
poll. Empty polls, watermarks, and ACKs do not reset the data idle timer. Expose the last and maximum delivery interval and current data idle time in milliseconds.subscriptionMemoryUsedInBytesas the per-queue value and expose the node total separately asdataNodeSubscriptionMemoryUsedInBytes. Bind/unbind the new gauges across metric service restarts. Add matching English and Chinese messages.Interpret delivery idle time together with queue active/initialized state, WAL lag, and polling activity, since it also grows while no data arrives or consumers do not poll.
Avoid redundant WAL work
walNextBufferedfrom the iterator's existing usable cache. Reading this field does not callhasNext(), read WAL, or advance replay. A false value does not imply exhaustion; interpret it alongside lag and worker activity.ProgressWALIterator.advanceTo()once at batch exit. This coalesces retained-file coverage checks for the processed prefix, including early exits for gaps or memory pressure. A seek generation change prevents stale batch work from fast-forwarding the iterator.Prefetch DEBUG tracing
Round start/end logs include a compact consumer-group/topic/region identifier, elapsed time, cursor changes, pending/WAL accepted-entry deltas, queue sizes, memory/admission blocking reasons, and the requested reschedule result/delay. Additional logs identify read-lock acquisition, WAL scan start, entry parsing/conversion and duration, estimated tablet bytes, and memory reservation rejection details. Subtask logs show whether a pending wakeup causes immediate re-enqueue despite the round's result.
To capture these logs, enable the following loggers in
conf/logback-datanode.xml:Output is written to
logs/log_datanode_debug.logwith the worker thread name. DEBUG snapshots read existing state without probing the WAL iterator or constructing the queue's full core report.Manual performance comparison
SubscriptionWalPrefetchPerformanceTestadds two independently enabled UTs. Both skip by default:testNoIoStatsProbeAndCoalescedAdvancePerformance: enableiotdb.test.subscription.performance.prefetch-overhead=trueto compare the statistics probe and per-entry versus batch-exit cursor advancement from commitf228b0865ae.testMemoryBlockedRetryPerformance: enableiotdb.test.subscription.performance.memory-retry=trueto compare iterator recreation versus retaining the same rejected request from commitb7174d747ab.Run either comparison from the repository root:
Measured on 2026-10-12 with Windows 11, an Intel Core i9-13900H, Oracle JDK 17.0.15 and one Surefire fork. Both variants in each comparison use the same sealed, uncompressed V3 WAL with a retained prefix of 4,096 logical row requests and two fragments per request. The cursor fixture additionally retains an uncovered follower and 65 local successor requests. Each comparison runs two warmup rounds and five measured rounds with alternating execution order. The table reports wall-time medians and work counts per measured sample:
hasNext(): 30.033 mshasBufferedNext(): 0.500 µsThe cursor test deliberately keeps an uncovered follower in the historical file; both paths must deliver it before the next eligible local request. The retry test includes the first seek and WAL deserialization in both paths, models seven rejected attempts followed by one successful attempt, and verifies both rows, writer metadata, original buffer positions, request identity during cached retries, and the next request after success.
These measurements compare the previous and optimized iterator operation sequences within the current implementation using a warm filesystem cache. They cover iterator work and WAL parsing; they do not measure whole-revision or end-to-end subscription throughput. Retry timing excludes Tablet conversion, subscription memory admission and scheduler delays. The sub-microsecond cached probe is close to timer overhead, so its timing ratio is not a useful throughput claim. Assertions check work counts and payload/progress correctness; elapsed time has no pass/fail threshold.
Workload overrides use the
iotdb.test.subscription.performance.prefix:entries,batch-size,retries,warmupsanditerations. Defaults are 4096, 64, 8, 2 and 5 respectively.Validation
testlifecycle runs passed with only the ten selected subscription test classes enabled and one Surefire fork. English used a 1.5 GiB Maven heap; Chinese used 1 GiB and Serial GC. Checkstyle passed in English and was skipped in the Chinese run (-Dcheckstyle.skip=true) to reduce build memory; Spotless remained enabled.ProgressWALIteratorTest,ConsensusPrefetchingQueueTest,ConsensusPrefetchingQueueSeekTest,ConsensusPrefetchingQueueWalBackpressureTest,ConsensusLogToTabletConverterTest,ConsensusPrefetchingQueueDataNodeMemoryTest,SubscriptionMemoryManagerTest,ConsensusSubscriptionPrefetchingQueueMetricsTest,SubscriptionMetricsRestartTest, andSubscriptionWalPrefetchPerformanceTest.git diff --check, and English/Chinese message-key and placeholder parity passed.Self-review
Key changed classes
ConsensusPrefetchingQueue,ProgressWALIterator,ConsensusLogToTabletConverter,SubscriptionQueueTimeTracker,ConsensusPrefetchSubtask,ConsensusSubscriptionPrefetchingQueueMetrics,SubscriptionMetrics, andSubscriptionMemoryManager.