influxdata / influxdata/kapacitor
Many unique alert ID's cause kapacitor slowdowns
- Dominant language
- Go
- Stars
- 2.4k
- Forks
- 479
- Avg merge
- 4d 16h
- Merged PRs (30d)
- 4
Description
We've noticed a pretty serious problem where many alerts triggered simultaneously cause Kapacitor to back up pretty bad processing new data. We've seen this with a least the most recent 2 releases of Kapacitor.
Given this TICK template with `period` == `7m` and `maxAgeMinutes` == `5`:
```
dbrp "telegraf"."autogen"
var period duration
var maxAgeMinutes int
var offline_threshold string
var maxAgeNanos = maxAgeMinutes * 60 * 1000000000
var templateString = '''{"meta": {"timestamp": "{{ .Time.Local.Format "2006-01-02T15:04:05.999Z" }}","tenant_id": "{{ index .Tags "institutionId" }}"},''' +
'''"source": {"name": "tick", "task": "{{ .TaskName }}"},''' +
'''"alert":{"id": "{{ .ID }}", "severity": "{{ .Level }}", "timestamp": "{{ .Time.Local.Format "2006-01-02T15:04:05.999Z" }}"{{ if eq "OK" .Level }}, "recovered": true, "incident_duration": "{{ .Duration.Seconds }}s" {{ end }}},"device": {"id": "{{ index .Tags "deviceId" }}"},''' +
'''"condition": "DEVICE_OFFLINE",''' +
'''"device_offline": {"offline_threshold": "''' + offline_threshold + '''"}}'''
batch
|query('''SELECT last("deviceType"), "institutionId", "deviceId"
FROM "telegraf"."autogen"."device-posted-status"
WHERE "institutionId" != '00000000-0000-4000-8000-000000000000' ''')
.period(period)
.every(2m)
.groupBy('institutionId', 'deviceId')
|alert()
.crit(lambda: unixNano("time") < (unixNano(now()) - maxAgeNanos))
.id('{{ .TaskName }}/{{ index .Tags "deviceId" }}')
.message(templateString)
.stateChangesOnly()
.topic('alert-device-offline')
```
If enough alerts are triggered in a given batch, the whole pipeline backs-up. It gets to the point where it appears that Kapacitor is evaluating datapoints that it queried for 20 minutes ago, which considering that lambda will always trigger an alert further exacerbating the issue:
```
query1 [avg_exec_time_ns="406.005001ms" batches_queried="49063" errors="0" points_queried="49063" working_cardinality="0" ];
query1 -> alert2 [processed="48061"]
```
You can see there that it ends-up about 1000 points behind at about 10 minutes into admittedly high-stress testing. This became a problem for us when an outage happened and we indeed had a great many things in an alert state, but it caused a feedback loop that even after recovery Kapacitor was still triggering alerts because it was so far behind in processing batch data.
I've eliminated everything but the alert phase. If everything is fine and no alerts are triggered, the nodes stay in lock step processing as batches are queried, but things start to fall behind as soon as there is any significant amount of alerting going on.
Contributor guide
Research direction
Start with the alert phase in the batch pipeline and reproduce the slowdown using the provided TICK template, focusing on the query1 -> alert2 processing metrics. Compare processing with no alerts against many simultaneous unique alert IDs. Done means alert-heavy batches no longer create a growing backlog or continue triggering alerts after recovery.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- observability
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100