Skip to content

Commit

Permalink
Add startInterval and resetTime (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
jthomperoo authored Jan 15, 2023
1 parent bc5a010 commit f3c216e
Show file tree
Hide file tree
Showing 13 changed files with 192 additions and 15 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- New ability to choose a start interval for a model, e.g. a holt winters model that only starts at the next full hour.
- `startInterval` is an optional [duration](https://pkg.go.dev/time#ParseDuration) that defines the next interval to
start at. For example `1m` would start the model recording data and calculating after the next full minute has passed.
- New ability to clear a model's replica history if too much time has passed since it last recorded any data.
- `resetDuration` is an optional [duration](https://pkg.go.dev/time#ParseDuration) that defines how long should be
allowed to pass without a model recording any data, if that occurs the replica history is cleared and if a start
interval is provided a new start time is calculated. If a model is not calculated for an extended period of time
(e.g. a cluster being powered off) this allows old data to be cleared out and not used in calculations and a new
start time calculated to respect any provided interval. For example `3m` would clear the model's replica history
(and reset the start time if interval is provided) if it has been more than 3 minutes since the last data was
recorded for the model.
### Changed
- **BREAKING CHANGE** typo fixed, `ModelHistory.ReplicaHistroy` renamed to `ModelHistory.ReplicaHistory`.

## [v0.12.0] - 2023-01-15
### Changed
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ spec:
name: php-apache
minReplicas: 1
maxReplicas: 10
downscaleStabilization: 0
behavior:
scaleDown:
stabilizationWindowSeconds: 0
metrics:
- type: Resource
resource:
Expand Down
22 changes: 20 additions & 2 deletions api/v1alpha1/predictivehorizontalpodautoscaler_types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2022 The Predictive Horizontal Pod Autoscaler Authors.
Copyright 2023 The Predictive Horizontal Pod Autoscaler Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -132,6 +132,20 @@ type Model struct {
// you have multiple and to keep track of model data if you modify your model parameters.
Name string `json:"name"`

// startInterval is the next interval to start applying this model at. This allows you to make sure a model starts
// recording and being calculated only after a certain interval has passed, e.g. a Holt Winters model that only
// runs at the top of every hour.
// This value is a string duration, e.g. 2m30s is 2 minutes and 30 seconds.
// +optional
StartInterval *metav1.Duration `json:"startInterval"`

// resetDuration is how long can pass without data for the model before the model should reset.
// This is useful in case a model hasn't been calculated in a long time (e.g. a cluster being powered off) to
// prevent it from operating on old data and to ensure that the start interval is recalculated.
// This value is a string duration, e.g. 2m30s is 2 minutes and 30 seconds.
// +optional
ResetDuration *metav1.Duration `json:"resetDuration"`

// calculationTimeout is how long the PHPA should allow for the model to calculate a value in milliseconds, if it
// takes longer than this timeout it should skip processing the model.
// Default varies based on model type:
Expand Down Expand Up @@ -185,7 +199,11 @@ type ModelHistory struct {
// when determining if a model should run based on the perSyncPeriod
SyncPeriodsPassed int `json:"syncPeriodsPassed"`
// replicaHistory is a list of timestamped replicas, this data is fed into the model to calculate a predicted value.
ReplicaHistroy []TimestampedReplicas `json:"replicaHistory"`
ReplicaHistory []TimestampedReplicas `json:"replicaHistory"`
// startTime is the time after which the model should start applying and recording data. If it is before this time
// no data will be recorded and the model will be skipped.
// +optional
StartTime *metav1.Time `json:"startTime"`
}

// PredictiveHorizontalPodAutoscalerSpec defines the desired state of PredictiveHorizontalPodAutoscaler
Expand Down
21 changes: 18 additions & 3 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions docs/user-guide/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ spec:
name: php-apache
minReplicas: 1
maxReplicas: 10
behavior:
scaleDown:
stabilizationWindowSeconds: 0
metrics:
- type: Resource
resource:
Expand All @@ -171,7 +174,6 @@ spec:
historySize: 6
decisionType: "maximum"
syncPeriod: 10000
downscaleStabilization: 0
```
This autoscaler works by using the same logic that the Horizontal Pod Autoscaler uses to calculate the number of
Expand Down Expand Up @@ -221,7 +223,9 @@ syncPeriod: 10000
target and will not pick the highest across a window of time.

```yaml
downscaleStabilization: 0
behavior:
scaleDown:
stabilizationWindowSeconds: 0
```

- A single *model* is configured as a linear regression model.
Expand Down
14 changes: 13 additions & 1 deletion docs/user-guide/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Shared Configuration

All models share these three options:
All models share these properties:

- **type** - The type of the model, for example 'Linear'.
- **name** - The name of the model, must be unique and not shared by multiple models.
Expand All @@ -11,6 +11,14 @@ a base unit, with a value of `1` resulting in the model being recalculated every
recalculated every other sync period, `3` waits for two sync periods after every calculation and so on.
- **calculationTimeout** - The timeout for calculating using an algorithm, if this timeout is exceeded the calculation
is skipped. Defaults set based on the algorithm used, see below.
- **startInterval** - The [duration](https://pkg.go.dev/time#ParseDuration) that the model should start to apply from.
For example a value of `1m` would mean the model would only start to apply at the top of the next minute. This is
useful if you have seasonal data that you need the model synced to, such as Holt-Winters, which allows you to do things
like making sure the model defines the start of a Holt-Winters season as starting at midnight (with the season being)
the whole day.
- **resetDuration** - The [duration](https://pkg.go.dev/time#ParseDuration) that the model can go for without recording
any data before the data is too old and is cleared out. A new start time will be calculated from the `startInterval`
if it's provided at this point too.

All models use `syncPeriod` as a base unit, so if the sync period is defined as `10000` (10 seconds), the models will
base their timings and calculations as multiples of 10 seconds.
Expand Down Expand Up @@ -49,6 +57,8 @@ models:
- type: HoltWinters
name: simple-holt-winters
perSyncPeriod: 1
startInterval: 60s
startIntervalResetDuration: 5m
holtWinters:
alpha: 0.9
beta: 0.9
Expand Down Expand Up @@ -109,6 +119,8 @@ models:
- type: HoltWinters
name: simple-holt-winters
perSyncPeriod: 1
startInterval: 60s
startIntervalResetDuration: 5m
holtWinters:
runtimeTuningFetchHook:
type: "http"
Expand Down
5 changes: 5 additions & 0 deletions examples/dynamic-holt-winters/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ spec:
models:
- type: HoltWinters
name: HoltWintersPrediction
startInterval: 60s
resetDuration: 5m
holtWinters:
runtimeTuningFetchHook:
type: "http"
Expand Down Expand Up @@ -180,6 +182,9 @@ CPU utilization at 50% per pod.
- `models` - predictive models to apply.
- `type` - 'HoltWinters', using a Holt-Winters predictive model.
- `name` - Unique name of the model.
- `startInterval` - The model will only apply at the top of the next full minute
- `resetDuration` - The model's replica history will be cleared out if it's been longer than 5 minutes without any
data recorded (e.g. if the cluster is turned off).
- `holtWinters` - Holt-Winters specific configuration.
* `runtimeTuningFetchHook` - This is a [hook](https://predictive-horizontal-pod-autoscaler.readthedocs.io/en/latest/user-guide/hooks)
that is used to dynamically fetch the `alpha`, `beta` and `gamma` values at runtime, in this example it is using a
Expand Down
2 changes: 2 additions & 0 deletions examples/dynamic-holt-winters/phpa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ spec:
models:
- type: HoltWinters
name: HoltWintersPrediction
startInterval: 60s
resetDuration: 5m
holtWinters:
runtimeTuningFetchHook:
type: "http"
Expand Down
5 changes: 5 additions & 0 deletions examples/simple-holt-winters/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ spec:
models:
- type: HoltWinters
name: simple-holt-winters
startInterval: 60s
resetDuration: 5m
holtWinters:
alpha: 0.9
beta: 0.9
Expand All @@ -150,6 +152,9 @@ CPU utilization at 50% per pod.
- `models` - predictive models to apply.
- `type` - 'HoltWinters', using a Holt-Winters predictive model.
- `name` - Unique name of the model.
- `startInterval` - The model will only apply at the top of the next full minute
- `resetDuration` - The model's replica history will be cleared out if it's been longer than 5 minutes without any
data recorded (e.g. if the cluster is turned off).
- `holtWinters` - Holt-Winters specific configuration.
* `alpha`, `beta`, `gamma` - these are the smoothing coefficients for level, trend and seasonality
respectively.
Expand Down
2 changes: 2 additions & 0 deletions examples/simple-holt-winters/phpa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ spec:
models:
- type: HoltWinters
name: simple-holt-winters
startInterval: 60s
resetDuration: 5m
holtWinters:
alpha: 0.9
beta: 0.9
Expand Down
2 changes: 1 addition & 1 deletion hack/boilerplate.go.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2022 The Predictive Horizontal Pod Autoscaler Authors.
Copyright 2023 The Predictive Horizontal Pod Autoscaler Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,23 @@ spec:
if needs. Default value is 1 (run every sync period)
minimum: 1
type: integer
resetDuration:
description: resetDuration is how long can pass without data
for the model before the model should reset. This is useful
in case a model hasn't been calculated in a long time (e.g.
a cluster being powered off) to prevent it from operating
on old data and to ensure that the start interval is recalculated.
This value is a string duration, e.g. 2m30s is 2 minutes and
30 seconds.
type: string
startInterval:
description: startInterval is the next interval to start applying
this model at. This allows you to make sure a model starts
recording and being calculated only after a certain interval
has passed, e.g. a Holt Winters model that only runs at the
top of every hour. This value is a string duration, e.g. 2m30s
is 2 minutes and 30 seconds.
type: string
type:
description: type is the type of the model, for example 'Linear'.
To see a full list of supported model types visit https://predictive-horizontal-pod-autoscaler.readthedocs.io/en/latest/user-guide/models/.
Expand Down
Loading

0 comments on commit f3c216e

Please sign in to comment.