[ 
https://issues.apache.org/jira/browse/YUNIKORN-3310?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Manikandan R resolved YUNIKORN-3310.
------------------------------------
    Fix Version/s: 1.10.0
       Resolution: Fixed

> queue removal resets terminal app state metrics to zero
> -------------------------------------------------------
>
>                 Key: YUNIKORN-3310
>                 URL: https://issues.apache.org/jira/browse/YUNIKORN-3310
>             Project: Apache YuniKorn
>          Issue Type: Bug
>          Components: core - scheduler
>    Affects Versions: 1.7.0, 1.8.0
>            Reporter: Guruprasad Veerannavaru
>            Assignee: Guruprasad Veerannavaru
>            Priority: Minor
>              Labels: metrics, pull-request-available
>             Fix For: 1.10.0
>
>   Original Estimate: 48h
>  Remaining Estimate: 48h
>
> h3. Background
> {{yunikorn_queue_app}} is a Gauge that tracks application counts per state 
> per queue. For terminal states (completed, failed, rejected), the value only 
> ever increments — apps enter these states and never leave. This makes 
> terminal states effectively cumulative counters, not point-in-time gauges.
> Dynamic (unmanaged) queues are removed when they have no applications. The 
> completed app is moved out of {{queue.applications}} immediately on entering 
> Completed (via {{UnSetQueue}} → {{RemoveApplication}}), so the queue can 
> become empty within seconds — well before the 3-day {{terminatedTimeout}} 
> that governs app cleanup from the partition.
> h3. What YUNIKORN-2908 introduced
> [YUNIKORN-2908|https://issues.apache.org/jira/browse/YUNIKORN-2908] added 
> {{RemoveQueueMetrics()}} on queue removal to fix two issues with *resource 
> metrics*:
> # After queue removal, metrics like guaranteed and max resources continued to 
> be reported by Prometheus, giving a wrong impression that resources were 
> still allocated to a non-existent queue.
> # When resource config was removed from a queue (or a resource type removed 
> from config), stale metric values were never cleaned up — metrics are only 
> updated when there's a new valid value, not a 'null' value.
> The fix correctly unregisters all queue metrics on removal. This is the right 
> behavior for resource metrics (guaranteed, max, allocated) — they represent 
> instantaneous state that should not persist after queue removal.
> h3. What broke
> Terminal state gauges (completed, failed, rejected) were also wiped by the 
> blanket {{RemoveQueueMetrics()}}. When the queue is recreated on next app 
> arrival, all metrics restart at 0. Since Prometheus often hasn't scraped the 
> final value before removal (queue empties within seconds of the last 
> completion), Grafana shows drops in 
> {{yunikorn_queue_app\{state="completed"\}}} even though apps are completing 
> successfully.
> Before YUNIKORN-2908, terminal gauges leaked in the registry — which 
> accidentally preserved their values across queue lifecycles.
> h3. Why terminal states should not be a Gauge
> A gauge represents a value that goes up and down (e.g., currently running 
> apps). Terminal states are monotonically increasing — an app that completed 
> stays completed. A Counter is the correct Prometheus type for this semantic.
> h3. Proposed fix
> Add a new CounterVec {{yunikorn_queue_app_total}} for terminal states 
> (completed, failed, rejected). This counter is excluded from 
> {{RemoveQueueMetrics()}} — it stays in the Prometheus registry when the queue 
> is removed. On queue recreation, the existing counter is reused (via 
> Prometheus {{AlreadyRegisteredError}}), preserving accumulated values.
> The existing {{yunikorn_queue_app}} gauge remains unchanged for backward 
> compatibility.
> *Usage in Grafana:*
> {code}
> increase(yunikorn_queue_app_total{queue="root.shared.sparksynthetics", 
> state="completed"}[1h])
> {code}
> h3. FAQ
> *Will this increase memory usage?*
> Minimally. Each dynamic queue retains one CounterVec with 3 label values 
> (completed, failed, rejected) in the Prometheus registry after removal. This 
> is a few hundred bytes per unique queue path. In practice, dynamic queues are 
> created per-user or per-namespace — this is bounded and far smaller than the 
> memory already used by the queue objects themselves during their active 
> lifetime. This is also the same behavior as before YUNIKORN-2908 where all 
> metrics leaked in the registry.
> *Does this increase metric cardinality?*
> It adds 3 new time series per queue (one per terminal state). Cardinality 
> scales with the number of unique queue paths, which is already the case for 
> existing metrics. No new label dimensions are introduced.
> *Does this break backward compatibility?*
> No. The existing {{yunikorn_queue_app}} gauge is unchanged. The new 
> {{yunikorn_queue_app_total}} counter is additive — existing dashboards and 
> alerts continue to work as before.
> *Why not fix the existing gauge instead of adding a new metric?*
> The gauge semantic (value goes up and down) is fundamentally wrong for 
> terminal states. Fixing it within the gauge would mean either never 
> unregistering it (reintroducing the leak YUNIKORN-2908 fixed for resource 
> metrics) or adding special-case logic to {{UnregisterMetrics()}}. A separate 
> Counter with the correct Prometheus type is cleaner and follows Prometheus 
> naming conventions ({{_total}} suffix for counters).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to