Skip to content

Add state transition latency metrics for Helix participant - #3283

Open
crliao wants to merge 2 commits into
linkedin:masterfrom
crliao:state-transition-latency-metrics
Open

Add state transition latency metrics for Helix participant#3283
crliao wants to merge 2 commits into
linkedin:masterfrom
crliao:state-transition-latency-metrics

Conversation

@crliao

@crliao crliao commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Add metrics to track Helix state transition latency in HelixParticipant. Today only transition counts are tracked — there is no duration/latency instrumentation. (Helix's native StateTransitionStatMonitor is denylisted from InGraph due to per-partition cardinality.)

New Metrics

Metric Type Description
bootstrapToStandbyDurationMs Histogram Time to complete BOOTSTRAP→STANDBY (replication catch-up)
offlineToBootstrapDurationMs Histogram Time to complete OFFLINE→BOOTSTRAP (storage setup)
bootstrapFailureCount Counter Partitions that failed during BOOTSTRAP
maxTimeInBootstrapMs Gauge Longest currently-bootstrapping partition (4h stale cleanup)

Motivation

INC-15835 (Helix cascading OOM in prod-lva1, July 2026) showed we lacked visibility into how long partitions spend in BOOTSTRAP during rebalance storms. These metrics enable:

  • Alerting on abnormally long bootstrap durations
  • Detecting rebalance storms via bootstrap failure spikes
  • Monitoring partition catch-up progress during expansion

Changes

  • HelixParticipantMetrics.java: Added 4 new metrics + helper methods for recording transitions
  • HelixParticipant.java: Instrumented onPartitionBecomeBootstrapFromOffline and onPartitionBecomeStandbyFromBootstrap to record timing and failures

Add metrics to track BOOTSTRAP→STANDBY duration, OFFLINE→BOOTSTRAP duration,
bootstrap failures, and max time-in-BOOTSTRAP. These fill a gap where no
latency instrumentation exists today (Helix's native StateTransitionStatMonitor
is denylisted from InGraph due to high cardinality).

New metrics:
- bootstrapToStandbyDurationMs: histogram of successful bootstrap durations
- offlineToBootstrapDurationMs: histogram of offline→bootstrap transition time
- bootstrapFailureCount: counter of partitions that failed during bootstrap
- maxTimeInBootstrapMs: gauge of the longest currently-bootstrapping partition

Motivation: INC-15835 (Helix cascading OOM) showed that we lacked visibility
into how long partitions spend in BOOTSTRAP during rebalance storms.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@codecov-commenter

codecov-commenter commented Aug 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.75%. Comparing base (52ba813) to head (10dd474).
⚠️ Report is 411 commits behind head on master.

Files with missing lines Patch % Lines
...thub/ambry/clustermap/HelixParticipantMetrics.java 74.07% 6 Missing and 1 partial ⚠️
.../com/github/ambry/clustermap/HelixParticipant.java 33.33% 4 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             master    #3283       +/-   ##
=============================================
- Coverage     64.24%   50.75%   -13.50%     
+ Complexity    10398     8688     -1710     
=============================================
  Files           840      938       +98     
  Lines         71755    80525     +8770     
  Branches       8611     9692     +1081     
=============================================
- Hits          46099    40869     -5230     
- Misses        23004    36255    +13251     
- Partials       2652     3401      +749     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

}
logger.info("Before setting partition {} to bootstrap", partitionName);
localPartitionAndState.put(partitionName, ReplicaState.BOOTSTRAP);
participantMetrics.recordOfflineToBootstrapDuration(System.currentTimeMillis() - transitionStartMs);

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.

If the wait is interrupted, we still record a bootstrap duration. Should we return before these success metrics?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The existing InterruptedException catch (line 960) intentionally falls through without throw/return — partition still enters BOOTSTRAP state, so recording the duration is correct.

long maxDuration = 0;
for (Map.Entry<String, Long> entry : bootstrapStartTimeMs.entrySet()) {
long duration = now - entry.getValue();
if (duration > STALE_BOOTSTRAP_THRESHOLD_MS) {

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.

Can this stay read-only? Dropping the timer after 4h can hide the bootstrap time we want to measure.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch — removed the 4h eviction. Map is bounded by partition count per instance (~1.2k max), and entries are cleaned up on recordBootstrapComplete/recordBootstrapFailure. Fixed in 10dd474.

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