Skip to content

Commit

Permalink
mimir-operations: Ensure integer auto-scaling thresholds (grafana#3512)
Browse files Browse the repository at this point in the history
* mimir-operations: Ensure integer auto-scaling thresholds

In Jsonnet logic to generate KEDA auto-scaling thresholds, ensure that
thresholds are integers since KEDA requires this.

Signed-off-by: Arve Knudsen <[email protected]>
  • Loading branch information
aknuds1 authored and mason committed Dec 16, 2022
1 parent 6521817 commit 08ed9a3
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,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)),
},
}
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)),
},
],
}),
Expand Down

0 comments on commit 08ed9a3

Please sign in to comment.