-
Notifications
You must be signed in to change notification settings - Fork 1.3k
docs: explain KEDA/no KEDA scaling more #6406
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,9 +34,77 @@ data: | |
|
||
``` | ||
|
||
## Configure KEDA scaling globally | ||
|
||
To configure the KEDA scaling behaviour globally for all resources you can edit the configmap `config-kafka-autoscaler` in the `knative-eventing` namespace. | ||
|
||
Note that the `min-scale` and `max-scale` parameters both refer to the number of Kafka consumers, not the number of dispatcher pods. The number of dispatcher pods in the StatefulSet is determined by `scale / POD_CAPACITY`, where `POD_CAPACITY` is an environment variable you can configure on the `kafka-controller` deployment, and defaults to `20`. | ||
```yaml | ||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: config-kafka-autoscaler | ||
namespace: knative-eventing | ||
data: | ||
# What autoscaling class should be used. Can either be keda.autoscaling.knative.dev or dispabled. | ||
class: keda.autoscaling.knative.dev | ||
# The period in seconds the autoscaler waits until it scales down | ||
cooldown-period: "30" | ||
# The lag that is used for scaling (1<->N) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably have a unit? |
||
lag-threshold: "100" | ||
# The maximum number of replicas to scale up to | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This says "replicas", but the comment above talks about "Kafka consumers" (which I assume means threads reading from a shared consumer group)? |
||
max-scale: "50" | ||
# The minimum number of replicas to scale down to | ||
min-scale: "0" | ||
# The interval in seconds the autoscaler uses to poll metrics in order to inform its scaling decisions | ||
polling-interval: "10" | ||
``` | ||
|
||
## Understanding KEDA Scaling Patterns | ||
|
||
KEDA uses different lag thresholds to determine when to scale your Kafka components: | ||
|
||
### Scaling from 0 to 1 (Activation) | ||
- **Trigger**: When consumer lag exceeds the `activation-lag-threshold` (default: 0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
- **Behavior**: KEDA activates the first replica when any messages are waiting in the Kafka queue | ||
- **Use case**: Quick response to incoming events when the system is idle | ||
|
||
### Scaling from 1 to N (Scale Up) | ||
- **Trigger**: When consumer lag exceeds the `lag-threshold` (default: 100) | ||
- **Behavior**: KEDA adds more consumer replicas based on the lag-to-threshold ratio | ||
- **Formula**: `desired_replicas = min(ceil(current_lag / lag_threshold), max_scale)` | ||
|
||
### Scaling Down and to Zero | ||
- **Trigger**: When consumer lag falls below thresholds | ||
- **Behavior**: KEDA waits for the `cooldown-period` (default: 30 seconds) before reducing replicas | ||
- **Scale to zero**: Occurs when lag is below `activation-lag-threshold` for the duration of the cooldown period | ||
|
||
### StatefulSet Pod Calculation | ||
Each resource type (KafkaSources, Triggers, etc.) has its own dispatcher StatefulSet. Within each StatefulSet, the number of dispatcher pods is calculated as: | ||
``` | ||
dispatcher_pods = ceil(total_consumers_for_resource_type / POD_CAPACITY) | ||
``` | ||
|
||
Where `POD_CAPACITY` defaults to 20, meaning each dispatcher pod can handle up to 20 Kafka consumers. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the example above, I ask because we had a few samples for Serving autoscaling where the end result was that a single request coming in for a scaled-down pod would sometimes cause 2 pods to start, because the pending request + the "spare capacity" factor ended up crossing the one-pod capacity threshold (i.e. the "spare capacity" number was exactly equal to "pod capacity", so |
||
|
||
**Important**: Each resource (KafkaSource, Trigger, Subscription) creates its own consumer group, and KEDA scales the number of consumers within that consumer group. All consumers for a given resource type are distributed across the dispatcher pods in that type's StatefulSet. | ||
|
||
To maintain a **fixed minimum number of StatefulSet pods** for a resource type, calculate the total consumers needed: | ||
``` | ||
total_consumers = sum_of_all_min_scales_for_resource_type | ||
min_dispatcher_pods = ceil(total_consumers / POD_CAPACITY) | ||
``` | ||
|
||
For example: | ||
- 2 Triggers each with `min-scale: "40"` = 80 total consumers | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
- With default `POD_CAPACITY: 20`, this creates `ceil(80/20) = 4` dispatcher pods for the Trigger StatefulSet | ||
- All 80 consumers are distributed across these 4 pods | ||
|
||
## Configure Autoscaling for a Resource | ||
|
||
If you want to customize how KEDA scales a KafkaSource, trigger, or subscription you can set annotations on the resource: | ||
If you want to customize how KEDA scales a KafkaSource, trigger, or subscription you can set annotations on the resource. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: here |
||
|
||
Note that the `min-scale` and `max-scale` parameters both refer to the number of Kafka consumers, not the number of dispatcher pods. The number of dispatcher pods in the StatefulSet is determined by `scale / POD_CAPACITY`, where `POD_CAPACITY` is an environment variable you can configure on the `kafka-controller` deployment, and defaults to `20`. | ||
|
||
```yaml | ||
apiVersion: <eventing|messaging|sources>.knative.dev/v1 | ||
|
@@ -54,7 +122,7 @@ metadata: | |
# The lag that is used for scaling (1<->N) | ||
autoscaling.eventing.knative.dev/lag-threshold: "100" | ||
# The lag that is used for activation (0<->1) | ||
autoscaling.eventing.knative.dev: "0" | ||
autoscaling.eventing.knative.dev/activation-lag-threshold: "0" | ||
spec: | ||
# Spec fields for the resource... | ||
``` | ||
|
@@ -72,3 +140,32 @@ metadata: | |
spec: | ||
# Spec fields for the resource... | ||
``` | ||
|
||
## Manual Scaling with KEDA Disabled | ||
|
||
When KEDA is disabled (either globally or for specific resources), you can manually control the number of StatefulSet pods by scaling the consumer group resources directly. | ||
|
||
Each Kafka resource creates a corresponding `ConsumerGroup` resource in the same namespace that controls the number of consumers. You can manually scale these to achieve your desired pod count: | ||
|
||
```bash | ||
# List all consumer groups in your workload namespace | ||
kubectl get consumergroups -n <your-namespace> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we use the FQN of the resource, @Cali0707 ? |
||
|
||
# Scale a specific consumer group to desired consumer count | ||
kubectl scale consumergroup <consumergroup-name> --replicas=<desired-consumer-count> -n <your-namespace> | ||
``` | ||
|
||
Consumer groups are named: `knative-trigger-<namespace>-<trigger-name>` | ||
|
||
To calculate the desired consumer count for a target number of StatefulSet pods: | ||
``` | ||
desired_consumer_count = target_pods × POD_CAPACITY | ||
``` | ||
|
||
For example, to ensure 3 dispatcher pods for a Trigger named "my-trigger" in the "default" namespace: | ||
```bash | ||
# Set consumer count to 60 (3 pods × 20 POD_CAPACITY) | ||
kubectl scale consumergroup knative-trigger-default-my-trigger --replicas=60 -n default | ||
``` | ||
|
||
**Note**: Manual scaling is persistent until you re-enable KEDA autoscaling or manually change the scale again. The StatefulSet will automatically adjust its pod count based on the consumer group replica count. |
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.
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.
(typo + inclusive language)
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.
disabled is the key we are using in the code afaik - I just took it from the repo
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.
+1 it is there since longer.