Späť na blog

Prometheus WAL replay peklo: pomalý štart a chýbajúce alerty

Symptómy sú monitoring nočná mora:

  • Prometheus pod je Running, ale nie Ready veľmi dlho.
  • Alerty stíchnu (nie preto, že je všetko OK, ale preto, že sa nevyhodnocujú).
  • Restart (node drain, upgrade, eviction) spraví 30–90 minút “blind spot”.
  • V logoch je niečo ako “replaying WAL”.

Keď sa to deje, často to nie je sieť ani CPU. Je to startup práca TSDB: replay WAL, aby sa rebuildol in-memory head.

Testované na: Prometheus 2.48–2.53, Kubernetes 1.29–1.31, PV storage (rýchle SSD aj pomalšie network disky), high-churn clustre s remote_write.

Incident (anonymizovaný)

Mali sme plánovanú rotáciu nodov. Prometheus bol evictnutý a naschedulovaný inde. Pod nabehol rýchlo… a potom ostal NotReady.

V logoch WAL replay postupoval pomaly. Disk IO bolo pinned. Po 20 minútach prišlo OOMKilled a cyklus sa opakoval.

Root cause nebol “bug v Prometheovi”. Bola to kombinácia:

  • veľký WAL (ingestion spike + churn)
  • pomalý PV (vysoká IO latencia)
  • príliš nízky memory limit na head rebuild počas replay

Constraint: potrebovali sme monitoring späť rýchlo, ale nechceli sme “fix” cez slepé mazanie dát a stratu dôkazov.

Timeline

  • T-0: Prometheus restart počas node rotácie.
  • T+5m: pod Running, ale NotReady; alerty sa nevyhodnocujú.
  • T+10m: logy jasne ukazujú, že WAL replay dominuje štartu.
  • T+20m: WAL adresár je obrovský; disk je saturovaný; pamäť rastie.
  • T+30m: mitigácia: dočasne zvýšiť pamäť a znížiť ingestion tlak.
  • T+60m: Prometheus je Ready; alerting sa vráti.
  • T+1d: prevencia: ohraničiť churn, alerty na WAL size a restart duration, “time-to-ready” ako SLO.

Mechanizmus: prečo WAL replay dominuje štartu

Prometheus TSDB zapisuje recent samples do WAL. Pri štarte WAL segmenty replayuje, aby zrekonštruoval:

  • aktívne series metadata
  • in-memory chunk-y (head)

Je to pomalé alebo nestabilné, keď:

  • WAL je obrovský
  • disk je pomalý alebo saturuje
  • churn je vysoký (veľa nových series)
  • pamäťové limity sú príliš tesné

Nebezpečný loop:

  1. restart
  2. replay začne, pamäť rastie
  3. OOMKilled počas replay
  4. restart
  5. WAL stále veľký, repeat

Runbook: diagnostika WAL replay a bezpečné zotavenie

1) Potvrď, že je to WAL replay (nehádaj)

kubectl -n monitoring logs pod/<prometheus-pod> --since=60m | \
  rg -n "WAL|replay|TSDB|corrupt|repair|head" | tail -n 200

Hľadáš:

  • “replaying WAL”
  • progres, ktorý sa skoro nehýbe
  • OOM / corruption správy

2) Zmeraj veľkosť WAL

kubectl -n monitoring exec -it <prometheus-pod> -- sh -lc \
  "du -sh /prometheus/wal /prometheus 2>/dev/null || true; ls -1 /prometheus/wal 2>/dev/null | wc -l || true"

Operatívne sú dôležité dva signály:

  • WAL veľkosť
  • počet segmentov

3) IO-bound vs memory-bound

Praktické heuristiky:

  • IO-bound: replay ide pomaly, CPU nie je vysoké, IO latencia je vysoká
  • memory-bound: RSS rastie a končí to OOMKilled

Ak máš prístup na node:

iostat -x 1 10

Ak nie, inferuj z typu PV a z OOM cyklov.

4) Prečo WAL narástol (skutočný root cause)

Najčastejšie je to niečo z tohto:

  • high churn metriky (new series/min)
  • kardinalita explózia (label blowup)
  • remote_write backpressure a amplifikácia ingestionu
  • pomalý disk, ktorý nestíha truncation/compaction

WAL je v praxi “daňový doklad” na tvoj monitoring budget.

Bezpečné mitigácie (vyber najmenej invazívnu)

1) Dočasne zvýš memory limity

WAL replay potrebuje headroom nad steady-state. Ak sizing robíš len na steady-state, replay bude padať.

Reprezentatívny bump:

resources:
  requests:
    memory: "4Gi"
  limits:
    memory: "6Gi"

2) Dočasne zníž ingestion

Ak je WAL obrovský a replay pomalý, niekedy musíš znížiť load, aby to dobehlo:

  • zvýšiť scrape interval pre noisiest joby
  • dočasne vypnúť najhorších vinníkov
  • drop low-value metriky cez relabeling (najmä high-churn labely)

3) TSDB na rýchlejší storage (plánovaný fix)

Ak je replay IO-bound, je to storage problém. Rýchly disk je rozdiel minúty vs hodiny.

4) Last resort: zmazať WAL

Zmazanie WAL dokáže Prometheus postaviť rýchlo, ale je to data loss by design.

Ak to musíš spraviť:

  • ak sa dá, sprav snapshot TSDB dir
  • zdokumentuj presne, čo si zmazal a prečo

Čo sme zmenili (konkrétne)

1) “Time-to-ready” ako SLO

Napísali sme kontrakt:

  • po restarte musí byť Prometheus Ready do N minút

Keď to poruší, je to incident (monitoring je produkčná závislosť).

2) Zníženie churnu pri zdroji

Label budgety a churn kontrola znížili:

  • WAL growth rate
  • replay memory footprint
  • variabilitu štartu

3) Headroom pre replay peaks

Zvýšili sme pamäťový headroom a vyhli sa “tesným limitom” na tej inštancii, ktorá sa musí rýchlo zotaviť.

4) Alerty ešte predtým, než sme slepí

Guardrails, ktoré reálne používame:

  • “Prometheus NotReady viac než X minút”
  • WAL size nad threshold
  • new series/min nad threshold

Ako verifikovať

  • Prometheus je Ready v budgete po kontrolovanom restarte.
  • WAL size je bounded v steady-state.
  • Počas node drainov nie je alerting slepý dlhé okná.

Súvisiace čítanie

Súvisiace články

Citujte tento článok

Ak na článok odkazujete, pridajte pôvodnú URL a uveďte autora.

Michal Drozd. "Prometheus WAL replay peklo: pomalý štart a chýbajúce alerty". https://www.michal-drozd.com/sk/blog/prometheus-wal-replay-pomaly-start/ (Publikované 5. januára 2026).