New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixing scheduling latency metrics #64316
Fixing scheduling latency metrics #64316
Conversation
/retest |
/assign shyamjvs |
cmd/kube-scheduler/app/server.go
Outdated
@@ -225,7 +227,16 @@ func buildHandlerChain(handler http.Handler, authn authenticator.Request, authz | |||
func newMetricsHandler(config *componentconfig.KubeSchedulerConfiguration) http.Handler { | |||
pathRecorderMux := mux.NewPathRecorderMux("kube-scheduler") | |||
configz.InstallHandler(pathRecorderMux) | |||
pathRecorderMux.Handle("/metrics", prometheus.Handler()) | |||
//metrics.Register() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you remove this commented code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
cmd/kube-scheduler/app/server.go
Outdated
@@ -243,7 +254,15 @@ func newHealthzHandler(config *componentconfig.KubeSchedulerConfiguration, separ | |||
healthz.InstallHandler(pathRecorderMux) | |||
if !separateMetrics { | |||
configz.InstallHandler(pathRecorderMux) | |||
pathRecorderMux.Handle("/metrics", prometheus.Handler()) | |||
defaultMetricsHandler := prometheus.Handler().ServeHTTP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of duplicating the same code as above, could you move this part into a separate function?
Like here - https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/server/routes/metrics.go#L44
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pkg/scheduler/metrics/metrics.go
Outdated
@@ -25,23 +25,26 @@ import ( | |||
|
|||
const schedulerSubsystem = "scheduler" | |||
|
|||
const BindingType = "binding" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please put these 3 values within a single const block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pkg/scheduler/metrics/metrics.go
Outdated
const SchedulingAlgorithmType ="scheduling_algorithm" | ||
const E2eSchedulingType = "e2e_scheduling" | ||
|
||
type resettableCollector interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this should be called a resettableCollector
(because it's just a collector, and not all of them are resettable). Can't you directly just use a prometheus.Collector?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pkg/scheduler/metrics/metrics.go
Outdated
) | ||
SchedulingAlgorithmLatency = prometheus.NewHistogram( | ||
prometheus.HistogramOpts{ | ||
OperationLatency = prometheus.NewSummaryVec( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you name this variable as SchedulingLatency
instead? That'll make it more clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pkg/scheduler/metrics/metrics.go
Outdated
Name: "scheduling_algorithm_latency_microseconds", | ||
Help: "Scheduling algorithm latency", | ||
Buckets: prometheus.ExponentialBuckets(1000, 2, 15), | ||
Name: "operation_latency_microseconds", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you rename this to scheduling_latencies_summary
instead? (to keep up with the naming convention used for apiserver)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pkg/scheduler/metrics/metrics.go
Outdated
Help: "Scheduling algorithm latency", | ||
Buckets: prometheus.ExponentialBuckets(1000, 2, 15), | ||
Name: "operation_latency_microseconds", | ||
Help: "operation latency", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest writing something more descriptive in the Help string. Like "Scheduling latency in microseconds split by sub-parts of the scheduling operation".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pkg/scheduler/metrics/metrics.go
Outdated
Name: "operation_latency_microseconds", | ||
Help: "operation latency", | ||
// Make the sliding window of 5h. | ||
// TODO: The value for this should be based on our SLI definition (medium term). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change:
our -> some
medium -> long
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pkg/scheduler/metrics/metrics.go
Outdated
}, | ||
[]string{"operationType"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just operation
is enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
test/e2e/framework/metrics_util.go
Outdated
switch sample.Metric[model.MetricNameLabel] { | ||
case "scheduler_scheduling_algorithm_latency_microseconds": | ||
switch sample.Metric["operationType"] { | ||
case "scheduling_algorithm": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please replace these hard-coded strings with their corresponding const vars you defined above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
test/e2e/framework/metrics_util.go
Outdated
@@ -520,6 +524,53 @@ func VerifySchedulerLatency(c clientset.Interface) (*SchedulingLatency, error) { | |||
return latency, nil | |||
} | |||
|
|||
func ResetSchedulerLatency(c clientset.Interface) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename this to ResetSchedulerLatencyMetrics
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
6162545
to
fe35b2a
Compare
fe35b2a
to
8f31bb6
Compare
pkg/scheduler/metrics/metrics.go
Outdated
const schedulerSubsystem = "scheduler" | ||
const ( | ||
SchedulerSubsystem = "scheduler" | ||
SchedulingLatencyName = "scheduling_latencies_summary" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's too useful to have this const. Maybe just put the string directly inside the metric definition (like other metrics)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we want to have operation types as a consts and and metric name as a string? Shouldn't we have coherent style - all strings or all consts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you have a valid point there.
So ideally we should make all hard-coded strings in files as global constants (so we only define the 'real' string once and later on only have references to it). However, moving too many things to global consts makes the file larger and harder to read. So the rule I'm usually following is to make a string const only if it's referenced enough times (3-4) in the codebase, so it's worth it. But this is subjective :)
pkg/scheduler/metrics/metrics.go
Outdated
SchedulerSubsystem = "scheduler" | ||
SchedulingLatencyName = "scheduling_latencies_summary" | ||
|
||
OperationLabel = "opertion" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
operation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also can we rename this variable to OperationType
and change the below ones to simply Binding
, SchedulingAlgorithm
, etc? Will make the meaning more clearer imo.
test/e2e/framework/metrics_util.go
Outdated
@@ -130,6 +131,8 @@ func (m *MetricsForE2E) SummaryKind() string { | |||
return "MetricsForE2E" | |||
} | |||
|
|||
var SchedulingLatencyMetricName = model.LabelValue(schedulerMetric.SchedulerSubsystem + "_" + schedulerMetric.SchedulingLatencyName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it'll be cleaner to have sth similar to apiserver like this:
var InterestingSchedulerMetrics = []string{
"scheduler_whatever"
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that scheduler latency metric has a special handling (other metrics will have different structure/labels). Always at some point you will need to verify if name == SCHEDULER_METRIC_NAME. That's why I prefer having variable to having value in array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. However, isn't it the same for apiserver metrics too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. The apiserver e2e metric are group of metrics with the some structure, so none of those metric requires special handling.
The apiserver latency metrics are more similar to scheduler latency metric. However in this case, metric names are compared to explicit strings.
test/e2e/framework/metrics_util.go
Outdated
@@ -521,6 +528,53 @@ func VerifySchedulerLatency(c clientset.Interface) (*SchedulingMetrics, error) { | |||
return latency, nil | |||
} | |||
|
|||
func ResetSchedulerLatencyMetrics(c clientset.Interface) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see some overlap of this function with getSchedulingLatency()
. Can we somehow unify them?
test/e2e/scalability/density.go
Outdated
@@ -442,6 +440,7 @@ var _ = SIGDescribe("Density", func() { | |||
|
|||
uuid = string(utiluuid.NewUUID()) | |||
|
|||
framework.ExpectNoError(framework.ResetSchedulerLatencyMetrics(c)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, let's name this function as ResetSchedulerMetrics
(as we may expand it in future to reset more metrics than just latency).
/approve |
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: krzysied, shyamjvs, wojtek-t The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/kind cleanup |
These metrics are important for our tests. @jberkus could you please approve for milestone? |
Approving as scalability sig lead |
[MILESTONENOTIFIER] Milestone Pull Request: Up-to-date for process Pull Request Labels
|
Automatic merge from submit-queue (batch tested with PRs 63328, 64316, 64444, 64449, 64453). If you want to cherry-pick this change to another branch, please follow the instructions here. |
const schedulerSubsystem = "scheduler" | ||
const ( | ||
// SchedulerSubsystem - subsystem name used by scheduler | ||
SchedulerSubsystem = "scheduler" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renaming metrics is a breaking change. It is not backward compatible and is going to break monitoring systems that rely on these metrics. This PR should be reverted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's a valid concern and also the option I was initially suggesting in #63493 (comment). I've cc'd there sig-scheduling and you - following lazy consensus since there weren't any objections :)
So, what do you think about re-adding the old metric alongside the new one (instead of replacing it)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't this metric broken anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so.. IIUC we were just not capturing the values properly in our test framework (which expects summary instead of histogram).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're going to add "aliases" for metrics, I think we should make more of a push toward prometheus best practices. The various histograms in this file and their relationships are a bit confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @misterikkit. Some of these names were not following Prometheus best practices. The new ones introduces in this PR are not following those best practices either. We should definitely keep the old ones for backward compatibility and maybe add new aliases based on the best practices.
@krzysied Did you have a chance to revert the changes to the metrics names? |
@bsalamat @misterikkit Does the following sgty:
And to clarify, this is not a question of "aliases" - the new metrics aren't just a name change, they're introducing summary-type metrics (like mentioned above). And the reason is we want to have accurate percentiles of scheduling latencies for measuring the performance better (some context here - #63493 (comment)) And wrt naming the new metrics, sure we can change the name.. that's not a problem. Could you point us to what best practices you're referring? |
@krzysied can make the changes based on what we agree above. |
Ahh, I failed to notice the distinction. I guess the sliding window is a more useful view of performance over the last N minutes, but is that better for observing health in a live cluster?
|
I've created the PR #64838 that re-introduces old metrics and changes new one to satisfy prometheus best practice. @bsalamat @misterikkit Could you please take a look and give an option as to whether this change looks good to you? |
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Adding summary metric for scheduling latency **What this PR does / why we need it**: Re-introduces histogram metrics for the backward compatibility. Changes SchedulingLatency metric to satisfy prometheus best practice. ref #64316 **Release note**: ```release-note NONE ```
What this PR does / why we need it:
Allows to measure and to display scheduling latency metrics during tests. Provides new functionality of resetting scheduler latency metrics.
Which issue(s) this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close the issue(s) when PR gets merged):Fixes #63493
Special notes for your reviewer:
E2eSchedulingLatency, SchedulingAlgorithmLatency, BindingLatency are now available
as subtypes of OperationLatency.
Release note: