Skip to content
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

mimir-operations: Ensure integer auto-scaling thresholds #3512

Merged
merged 4 commits into from
Nov 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
* [ENHANCEMENT] Added `$._config.usageStatsConfig` to track the installation mode via the anonymous usage statistics. #3294
* [ENHANCEMENT] The query-tee node port (`$._config.query_tee_node_port`) is now optional. #3272
* [ENHANCEMENT] Add support for autoscaling distributors. #3378
* [ENHANCEMENT] Make auto-scaling logic ensure integer KEDA thresholds. #3512
* [BUGFIX] Fixed query-scheduler ring configuration for dedicated ruler's queries and query-frontends. #3237 #3239

### Mimirtool
Expand Down
8 changes: 4 additions & 4 deletions operations/mimir-tests/test-autoscaling-generated.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -510,10 +510,10 @@ spec:
timeoutSeconds: 1
resources:
limits:
memory: 4Gi
memory: 6Gi
requests:
cpu: "2"
memory: 2Gi
cpu: 2
memory: 3.2Gi
volumeMounts:
- mountPath: /etc/mimir
name: overrides
Expand Down Expand Up @@ -1760,7 +1760,7 @@ spec:
metricName: cortex_distributor_memory_hpa_default
query: max_over_time(sum(container_memory_working_set_bytes{container="distributor",namespace="default"})[15m:])
serverAddress: http://prometheus.default:9090/prometheus
threshold: "2147483648"
threshold: "3435973836"
type: prometheus
---
apiVersion: keda.sh/v1alpha1
Expand Down
7 changes: 7 additions & 0 deletions operations/mimir-tests/test-autoscaling.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,11 @@ mimir {
autoscaling_distributor_min_replicas: 3,
autoscaling_distributor_max_replicas: 30,
},

local k = import 'ksonnet-util/kausal.libsonnet',
distributor_container+::
// Test a non-integer memory request, to verify that this gets converted into an integer for
// the KEDA threshold
k.util.resourcesRequests(2, '3.2Gi') +
k.util.resourcesLimits(null, '6Gi'),
}
36 changes: 22 additions & 14 deletions operations/mimir/autoscaling.libsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@
//
// Read more:
// https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#algorithm-details
threshold: trigger.threshold,
//
// We also have to ensure that the threshold is an integer (represented as a string)
threshold: std.toString(std.parseInt(trigger.threshold)),
aknuds1 marked this conversation as resolved.
Show resolved Hide resolved
},
}
for trigger in config.triggers
Expand Down Expand Up @@ -141,17 +143,23 @@
// Simple method to convert binary multiples.
// Only works for limited set of SI prefixes (as below).

if std.endsWith(str, 'Ki') then (
std.parseJson(std.rstripChars(str, 'Ki')) * std.pow(2, 10)
) else if std.endsWith(str, 'Mi') then (
std.parseJson(std.rstripChars(str, 'Mi')) * std.pow(2, 20)
) else if std.endsWith(str, 'Gi') then (
std.parseJson(std.rstripChars(str, 'Gi')) * std.pow(2, 30)
) else if std.endsWith(str, 'Ti') then (
std.parseJson(std.rstripChars(str, 'Ti')) * std.pow(2, 40)
) else (
str
)
// Utility converting the input to a (potentially decimal) number of bytes
local siToBytesDecimal(str) = (
if std.endsWith(str, 'Ki') then (
std.parseJson(std.rstripChars(str, 'Ki')) * std.pow(2, 10)
) else if std.endsWith(str, 'Mi') then (
std.parseJson(std.rstripChars(str, 'Mi')) * std.pow(2, 20)
) else if std.endsWith(str, 'Gi') then (
std.parseJson(std.rstripChars(str, 'Gi')) * std.pow(2, 30)
) else if std.endsWith(str, 'Ti') then (
std.parseJson(std.rstripChars(str, 'Ti')) * std.pow(2, 40)
) else (
std.parseJson(str)
)
);

// Round down to nearest integer
std.floor(siToBytesDecimal(str))
),

local cpuToMilliCPUInt(str) = (
Expand Down Expand Up @@ -256,8 +264,8 @@
// To scale out relatively quickly, but scale in slower, we look at the max memory utilization across all distributors over 15m.
query: 'max_over_time(sum(container_memory_working_set_bytes{container="%s",namespace="%s"})[15m:])' % [name, $._config.namespace],

// threshold is expected to be a string, so use '' to cast any ints returned by siToBytes.
threshold: siToBytes(distributor_memory_requests) + '',
// threshold is expected to be a string
threshold: std.toString(siToBytes(distributor_memory_requests)),
aknuds1 marked this conversation as resolved.
Show resolved Hide resolved
},
],
}),
Expand Down