IncidentGarden

Алерты без агрегации в PromQL

PromQL-запрос с высокой cardinality плодит тысячи алертов на один инцидент.

Антипаттерн

Писать PromQL-выражение так, чтобы оно возвращало по серии на каждый мелкий объект (партиция, pod, container, target), хотя сам факт инцидента — общий для всего узла или кластера.

Пример — алерт на недореплицированные партиции в Kafka:

- alert: UnderReplicatedPartition
  expr: kafka_topic_partition_under_replicated_partition > 0
  for: 10s
  labels:
    severity: warning
  annotations:
    summary: 'Topic has under-replicated partitions'
    description: 'Topic {{ $labels.topic }} has {{ $value }} under-replicated partition {{ $labels.partition }}'

Пока всё спокойно, алертов приходит совсем немного. Но например если у брокеров начинает сбоить SAN-хранилище, то в Prometheus сразу загорятся огромное множество алертов — по каждой партиции на каждый топик. В зависимости от размера инстанса Kafka, таких алертов могут быть сотни или тысячи на каждого брокера! Если на стороне AlertManager настроена группировка (например alertname + severity), то он соберёт их в одну группу и отправит один webhook с огромным списком alert-объектов внутри (alerts: [...]). Он будет переотправлять алерт на каждое изменение группы и/или согласно значению переменной repeat_interval. Incident Garden ограничивает размер таких хуков.

Как надо

Свернуть cardinality на уровне PromQL — агрегировать по тому уровню, на котором действует дежурный. Для Kafka — по брокеру:

- alert: UnderReplicatedPartition
  expr: sum(kafka_topic_partition_under_replicated_partition) by (instance) > 0
  for: 10s
  labels:
    severity: warning
  annotations:
    summary: 'Kafka under-replicated partitions'
    description: 'Kafka instance {{ $labels.instance }} has {{ $value }} under-replicated partition'

Теперь сбой SAN'а порождает алерт на брокер — один-десяток alert-объектов в payload, а не тысячи. Та же логика — для алертов на pod / container / target: думайте, на каком уровне принимается решение, и агрегируйте до этого уровня в PromQL.

На этой странице