yandrey321 opened a new pull request, #11128: URL: https://github.com/apache/ozone/pull/11128
## What changes were proposed in this pull request? ### Problem OM request-latency metrics are recorded as Hadoop @Metric MutableRate counters. MutableRate extends MutableStat, and MutableStat.add(long) is synchronized(this). On the OM hot path many handler threads record a measurement on the same metric instance, so they serialize on that per-counter monitor — a lock convoy that appears under concurrent load. A single getKeyInfo touches 6–7 of these counters in sequence, so the effect compounds on the read path. HDDS-9377 (already merged) introduced the lock-free ConcurrentMutableStat (striped LongAdder/LongAccumulator, drained lazily at snapshot) and applied it to OMLockMetrics and the PerformanceMetrics wrapper. The remaining MutableRate counters in OMPerformanceMetrics and KeyLifecycleServiceMetrics are the gap this PR closes, scoped deliberately to OM hot-path classes only. ### Approach New ConcurrentMutableRate (hadoop-hdds/common) — a lock-free counterpart of Hadoop's MutableRate, extending ConcurrentMutableStat with a public constructor that fixes sampleName="Ops" / valueName="Time". Hadoop's MutableRate constructor is package-private and only instantiable reflectively by the @Metric factory; this public ctor lets OM metric sources build it directly. Semantics and emitted names (<Name>NumOps / <Name>AvgTime) are identical. OMPerformanceMetrics — converted all 44 @Metric MutableRate latency counters to ConcurrentMutableRate. Because @Metric fields are instantiated reflectively (the factory always builds a real MutableRate, so a field cannot simply be retyped), the class is reworked into a hand-rolled MetricsSource following the OMLockMetrics / S3GatewayMetrics template: stats built in the constructor, getMetrics() snapshots all 44 stats plus the 6 surviving @Metric gauges. The single-writer gauges (listKeysOpsPerSec + 5 *ServiceLatencyMs) stay @Metric. KeyLifecycleServiceMetrics — taskLatencyMs (written concurrently by the lifecycle BackgroundService pool, per bucket) converted to ConcurrentMutableRate; the class becomes a hand-rolled MetricsSource. Its 13 MutableGaugeLong gauges remain @Metric. MetricUtil.captureLatencyNs — the two overload parameters widened from MutableRate to its superclass MutableStat. The body already only calls add(long). This is source-compatible (MutableRate and ConcurrentMutableStat both extend MutableStat) and lets all existing captureLatencyNs(getter(), block) call sites in ozone-manager compile unchanged. ### Metric-name compatibility All emitted metric names are preserved byte-identically: the capitalized field name plus extended=false reproduces exactly the <Name>NumOps / <Name>AvgTime pairs the @Metric factory generated. No dashboard or alert names change. Caveat: standard deviation is slightly underestimated under concurrent batched adds (documented on ConcurrentMutableStat, inherited here) — acceptable for these latency stats. ### Not converted (deliberately) OzoneManagerDoubleBufferMetrics (flushTime, queueSize) — written only by the single OMDoubleBufferFlushThread daemon, so there is no cross-thread contention and lock-free would only add churn. The MutableGaugeLong/Float gauges throughout are single-writer and left as @Metric. The genuinely-contended per-RPC MutableRate counters in the shared ipc_ fork (RpcMetrics) are out of OM scope and tracked separately. ## What is the link to the Apache JIRA https://issues.apache.org/jira/browse/HDDS-16288 ## How was this patch tested? CI: Unit tests Integration tests -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
