[ISSUE #10441] Reduce per-RPC allocation in metrics by caching static AttributeKey instances#10443
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR focuses on reducing allocation/CPU overhead on metrics and remoting hot paths by introducing AttributeKey singletons and adding small caches for frequently repeated attribute/metric lookups.
Changes:
- Added fast-path caching for remoting request/response code distribution counting.
- Introduced typed OpenTelemetry
AttributeKeyconstants and attribute caching/build helpers in remoting and broker metrics. - Reduced repeated string allocations (e.g., cached lowercase metrics value, avoided
Map.getOrDefaultboxing paths).
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| remoting/src/main/java/org/apache/rocketmq/remoting/netty/RemotingCodeDistributionHandler.java | Adds “last code” fast path to reduce map lookups for hot request/response codes. |
| remoting/src/main/java/org/apache/rocketmq/remoting/metrics/RemotingMetricsManager.java | Adds attribute caching and typed label keys to reduce OpenTelemetry attribute overhead. |
| remoting/src/main/java/org/apache/rocketmq/remoting/metrics/RemotingMetricsConstant.java | Introduces typed AttributeKey singletons for labels. |
| remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingHelper.java | Minor optimization to avoid getOrDefault overhead for code descriptions. |
| common/src/main/java/org/apache/rocketmq/common/attribute/TopicMessageType.java | Caches lowercase metrics value to avoid repeated conversions. |
| broker/src/main/resources/rmq.broker.logback.xml | Suppresses Logback status output via NopStatusListener. |
| broker/src/main/java/org/apache/rocketmq/broker/metrics/PopMetricsManager.java | Switches to typed label keys for attributes. |
| broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsManager.java | Adds topic attributes cache and switches to typed label keys. |
| broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsConstant.java | Introduces typed AttributeKey singletons for broker metrics labels. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
607c58a to
52c49e8
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #10443 +/- ##
=============================================
- Coverage 48.06% 48.04% -0.03%
- Complexity 13313 13321 +8
=============================================
Files 1377 1377
Lines 100632 100726 +94
Branches 12995 13010 +15
=============================================
+ Hits 48369 48392 +23
- Misses 46344 46383 +39
- Partials 5919 5951 +32 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
oss-sentinel-ai
left a comment
There was a problem hiding this comment.
Review by github-manager-bot
Summary
This PR caches OpenTelemetry AttributeKey instances as static finals to avoid per-RPC allocation, optimizes TopicMessageType lookup, adds a volatile inline cache for RemotingCodeDistributionHandler, and adds Logback NopStatusListener to suppress startup log noise.
Findings
- [Good] BrokerMetricsConstant.java:69-86 — Pre-built typed
AttributeKeysingletons eliminate per-call allocation on the metrics hot path. - [Good] BrokerMetricsManager.java:105-120 — Import changes correctly reference the new cached keys.
- [Good] RemotingCodeDistributionHandler.java:35-68 — Volatile inline cache pattern correctly avoids
ConcurrentHashMap.computeIfAbsent()on repeated request codes. - [Good] TopicMessageType.java — Enum-based lookup is more efficient than string comparison.
- [Good] rmq.broker.logback.xml —
NopStatusListenersuppresses Logback startup noise in production.
Suggestions
- The volatile inline cache pattern in
RemotingCodeDistributionHandleris effective for sequential workloads. Consider documenting that this optimization assumes temporal locality in request codes. - Consider adding a microbenchmark to quantify the allocation reduction.
Verdict
✅ Approved — Solid performance optimization with clean implementation.
Automated review by github-manager-bot
994bf3d to
8eeec77
Compare
…static AttributeKey instances
8eeec77 to
f8e69a4
Compare
… metrics hot path Builds on top of PR apache#10443 (which introduces the typed AttributeKey constants). After AttributeKey instances are de-duplicated, the next allocation hot spot in the metrics path is the Attributes object itself. For repeated parameter combinations the broker keeps rebuilding identical immutable Attributes (each ~200-300 byte). This commit introduces a two-level cache (volatile inline cache + ConcurrentHashMap fallback) at three points: - BrokerMetricsManager.getOrBuildTopicAttributes(topic, msgType, isSystem): 4-field volatile inline cache + CHM keyed by 'topic|msgType|isSystem'. - RemotingMetricsManager.getOrBuildAttributes(reqCode, respCode, isLongPolling, result): long-packed cache key (35 bits across 4 args, no String allocation), volatile inline cache + CHM. Falls back to direct build for unknown result values. - RemotingCodeDistributionHandler: replace two independent volatile fields (lastCode, lastAdder) with an immutable CachedCounter holder published through a single volatile reference. A single volatile read per inc() returns a self-consistent (code, adder) snapshot, eliminating a torn-read between the two fields under @sharable concurrent access from multiple Netty EventLoop threads.
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot
Summary
Pre-builds AttributeKey singletons as static constants in BrokerMetricsConstant and updates all call sites to use them, eliminating per-RPC allocation of InternalAttributeKeyImpl objects.
Findings
- [Critical]
BrokerMetricsConstant.java:69-83— All 15AttributeKeysingletons are correctly typed (stringKeyfor String labels,booleanKeyfor boolean labels). Each call toAttributeKey.stringKey("name")creates a new object; caching eliminates this per-RPC allocation. - [Critical]
BrokerMetricsManager.java,PopMetricsManager.java,RemotingMetricsManager.java— All call sites consistently updated to use the cached keys. No remainingAttributeKey.stringKey()calls on hot paths. - [Info]
RemotingMetricsManager.java:125-135— ThenewAttributes()helper now uses cached keys. This is called on every RPC completion, so the savings are proportional to RPC throughput.
Suggestions
No concerns. This is a straightforward, low-risk optimization with clear benefits on high-throughput brokers.
Verdict: LGTM. Clean optimization with consistent application across all metrics call sites.
Automated review by github-manager-bot
Summary
Reduce per-RPC allocation by replacing reflective
AttributeKey.stringKey(name)/AttributeKey.booleanKey(name)calls with pre-built staticAttributeKey<T>singletons.Problem
JFR heap dump showed 38,182
InternalAttributeKeyImplinstances for only 6 distinct key names. EveryAttributesBuilder.put(String, T)call internally creates a freshAttributeKey— a stateless immutable object that should be a singleton.Fix
Define
static final AttributeKey<T> LABEL_*_KEYconstants inBrokerMetricsConstantandRemotingMetricsConstant, then migrate allput(String, T)callsites toput(AttributeKey<T>, T).Files
BrokerMetricsConstant.javaAttributeKey<>constantsBrokerMetricsManager.javaPopMetricsManager.javaRemotingMetricsConstant.javaAttributeKey<>constantsRemotingMetricsManager.java.equals()comparisonSplit Note
Three misc optimizations previously bundled here (NopStatusListener, TopicMessageType.metricsValue cache, RemotingHelper eager eval fix) have been split into PR #10491.