Skip to content

Commit 0286121

Browse files
author
Florent Chehab
authored
Parametrized keda task concurrency in chart (#13571)
* Rely on the config.celery.worker_concurrency value to determine the number of task a keda worker can take (vs the previous 16 that was hardcoded in the query). * Updated documentation accordingly
1 parent e7a2e35 commit 0286121

4 files changed

Lines changed: 46 additions & 6 deletions

File tree

‎chart/README.md‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,11 @@ helm install --name my-release \
319319

320320
## Autoscaling with KEDA
321321

322+
*This feature is still experimental.*
323+
322324
KEDA stands for Kubernetes Event Driven Autoscaling. [KEDA](https://github.com/kedacore/keda) is a custom controller that allows users to create custom bindings
323325
to the Kubernetes [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/).
324-
We've built an experimental scaler that allows users to create scalers based on postgreSQL queries. For the moment this exists
325-
on a separate branch, but will be merged upstream soon. To install our custom version of KEDA on your cluster, please run
326+
We've built a scaler that allows users to create scalers based on postgreSQL queries and shared it with the community. This enables us to scale the number of airflow workers deployed on Kubernetes by this chart depending on the number of task that are `queued` or `running`.
326327

327328
```bash
328329
helm repo add kedacore https://kedacore.github.io/charts
@@ -349,6 +350,17 @@ helm install airflow . \
349350
--set workers.persistence.enabled=false
350351
```
351352

353+
KEDA will derive the desired number of celery workers by querying Airflow metadata database:
354+
355+
```sql
356+
SELECT
357+
ceil(COUNT(*)::decimal / {{ .Values.config.celery.worker_concurrency }})
358+
FROM task_instance
359+
WHERE state='running' OR state='queued'
360+
```
361+
362+
You should set celery worker concurrency through the helm value `config.celery.worker_concurrency` (i.e. instead of airflow.cfg or environment variables) so that the KEDA trigger will be consistent with the worker concurrency setting.
363+
352364
## Using an external redis instance
353365

354366
When using the `CeleryExecutor` or the `CeleryKubernetesExecutor` the chart will by default create a redis Deployment/StatefulSet alongside airflow.

‎chart/templates/workers/worker-kedaautoscaler.yaml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ metadata:
3636
spec:
3737
scaleTargetRef:
3838
deploymentName: {{ .Release.Name }}-worker
39-
pollingInterval: {{ .Values.workers.keda.pollingInterval }} # Optional. Default: 30 seconds
40-
cooldownPeriod: {{ .Values.workers.keda.cooldownPeriod }} # Optional. Default: 300 seconds
41-
maxReplicaCount: {{ .Values.workers.keda.maxReplicaCount }} # Optional. Default: 100
39+
pollingInterval: {{ .Values.workers.keda.pollingInterval }} # Optional. Default: 30 seconds
40+
cooldownPeriod: {{ .Values.workers.keda.cooldownPeriod }} # Optional. Default: 300 seconds
41+
maxReplicaCount: {{ .Values.workers.keda.maxReplicaCount }} # Optional. Default: 100
4242
triggers:
4343
- type: postgresql
4444
metadata:
4545
targetQueryValue: "1"
4646
connection: AIRFLOW_CONN_AIRFLOW_DB
47-
query: "SELECT ceil(COUNT(*)::decimal / 16) FROM task_instance WHERE state='running' OR state='queued'"
47+
query: "SELECT ceil(COUNT(*)::decimal / {{ .Values.config.celery.worker_concurrency }}) FROM task_instance WHERE state='running' OR state='queued'"
4848
{{- end }}

‎chart/tests/test_keda.py‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,30 @@ def test_keda_enabled(self, executor, is_created):
5555
assert "RELEASE-NAME-worker" == jmespath.search("metadata.name", docs[0])
5656
else:
5757
assert docs == []
58+
59+
@parameterized.expand(
60+
[
61+
("CeleryExecutor", 8),
62+
("CeleryExecutor", 16),
63+
("CeleryKubernetesExecutor", 8),
64+
("CeleryKubernetesExecutor", 16),
65+
]
66+
)
67+
def test_keda_concurrency(self, executor, concurrency):
68+
"""
69+
ScaledObject should only be created when set to enabled and executor is Celery or CeleryKubernetes
70+
"""
71+
docs = render_chart(
72+
values={
73+
"workers": {"keda": {"enabled": True}, "persistence": {"enabled": False}},
74+
"executor": executor,
75+
"config": {"celery": {"worker_concurrency": concurrency}},
76+
},
77+
show_only=["templates/workers/worker-kedaautoscaler.yaml"],
78+
validate_schema=False,
79+
)
80+
expected_query = (
81+
f"SELECT ceil(COUNT(*)::decimal / {concurrency}) "
82+
"FROM task_instance WHERE state='running' OR state='queued'"
83+
)
84+
self.assertEqual(expected_query, jmespath.search("spec.triggers[0].metadata.query", docs[0]))

‎chart/values.yaml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,7 @@ config:
711711
rbac: 'True'
712712
celery:
713713
default_queue: celery
714+
worker_concurrency: 16
714715
scheduler:
715716
scheduler_heartbeat_sec: 5
716717
# statsd params included for Airflow 1.10 backward compatibility; moved to [metrics] in 2.0

0 commit comments

Comments
 (0)