NeQuissimus opened a new pull request, #28986:
URL: https://github.com/apache/flink/pull/28986

   ## What is the purpose of the change
   
   `MetricStore.TaskMetricStore#retainSubtasks` and `#isTransientMetric` 
identify the
   per-subtask key prefix (e.g. `"0.numRecordsIn"`) with 
`String#matches(String)`, which
   recompiles the regex `Pattern` on every call. Both run once per metric key, 
and
   `retainSubtasks` is invoked once per vertex on every `MetricFetcher` refresh 
from
   `MetricStore#updateCurrentExecutionAttempts`, which is `synchronized` — so 
the
   O(#metric-keys) work, including a fresh `Pattern.compile` per key, executes 
while the
   single global `MetricStore` monitor is held.
   
   On jobs with a large number of subtasks this per-refresh compilation 
dominates the time
   the monitor is held. Because the JobManager REST handler thread pool
   (`rest.server.numThreads`) is shared between the `MetricFetcher` and the 
REST endpoints,
   the whole pool stalls on that monitor: `GET /jobs/<jid>` (which aggregates 
per-subtask IO
   metrics via `MutableIOMetrics#addIOMetrics`, taking the same monitor once 
per subtask)
   becomes very slow, and endpoints that never touch `MetricStore` 
(`/jobs/overview`,
   `/jobs/<jid>/checkpoints`) queue behind the saturated pool. Observed on a 
~2,233-subtask
   job (main chain at parallelism 900): a thread dump taken while `GET 
/jobs/<jid>` hung
   showed the entire REST pool contending on the `MetricStore` monitor, one 
thread RUNNABLE
   inside `java.util.regex.Pattern`/`String#matches` while holding it. CPU was 
otherwise
   near-idle — this is lock-hold time, not compute.
   
   ## Brief change log
   
     - Add two `static final Pattern` fields to `MetricStore.TaskMetricStore` 
and match via
       `matcher(...).matches()` in `retainSubtasks` and `isTransientMetric`, 
instead of
       `String#matches(String)` which recompiles the pattern on every call. The 
regex strings
       are unchanged.
   
   ## Verifying this change
   
   This change is a behaviour-preserving refactor already covered by existing 
tests:
   `MetricStoreTest#testTaskMetricStoreCleanup` (drives `retainSubtasks` via
   `updateCurrentExecutionAttempts`), `#testSubtaskMetricStoreCleanup`, and
   `#testMalformedNameHandling` (empty/`null` metric names). 
`String#matches(regex)` is
   specified as `Pattern.compile(regex).matcher(s).matches()`, so pre-compiling 
the identical
   patterns does not change matching behaviour.
   
   ## Does this pull request potentially affect one of the following parts:
   
     - Dependencies (does it add or upgrade a dependency): no
     - The public API, i.e., is any changed class annotated with 
`@Public(Evolving)`: no
     - The serializers: no
     - The runtime per-record code paths (performance sensitive): no 
(REST/metrics query path only)
     - Anything that affects deployment or recovery: JobManager (and its 
components), Checkpointing, Kubernetes/Yarn, ZooKeeper: no
     - The S3 file system connector: no
   
   ## Documentation
   
     - Does this pull request introduce a new feature? no
     - If yes, how is the feature documented? not applicable
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes (please specify the tool below)
   
   Generated-by: Pi (Anthropic claude-opus-4-8)
   


-- 
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]

Reply via email to