Logbuch#control-center#monitoring#prometheus#architektur
Von poll-träge zu Sekundentakt: erst Intervalle, dann ein Live-Stream
Von Niclas Hennrich · veröffentlicht · geschehen am
Selbst gebaut und in Betrieb genommen. Gehört zum Vorhaben Homelab Control Center.
- Anzeige-Latenz vorher, schlechtester Fall
- 45s
- nach dem Intervall-Tuning, schlechtester Fall
- 12s
- Live-Stream
- 1Event/s
Kurz zur Einordnung: Das Control Center ist mein selbst gebautes Mini-NOC. Seit heute läuft es dauerhaft auf optimus — und fühlte sich träge an. Werte, die sich sichtbar im Sekundenrhythmus bewegen wie bei einem UniFi-Controller, wollte ich vor allem für CPU und Netzwerk-Durchsatz.
Die Latenz war eine Kette. Prometheus-Scrape alle 15 s, Snapshot-Cache
im Backend 10 s, Frontend-Polling 20 s, dazu eine rate(...[3m])-Glättung
für CPU und Netz. Im schlechtesten Fall zeigte das Dashboard also rund 45 s
alte Werte, gemittelt über drei Minuten. An einer Stufe zu drehen bringt da
nichts — man muss alle vier anfassen.
Anlauf eins: nur Parameter. Scrape für node und cAdvisor auf 5 s
(Blackbox-Probes bleiben bei 15 s, smartctl bei 60 s, OPNsense bei 30 s),
cAdvisor-Housekeeping ebenfalls 5 s, rate-Fenster auf [1m], Cache-TTL 2 s,
Polling 5 s. Faustregel dabei: Das rate-Fenster sollte mindestens das
Vierfache des Scrape-Intervalls sein, sonst reißt bei einem ausgefallenen
Scrape die Kurve. Ergebnis: Frische 5 bis 12 s statt bis zu 45 s, verifiziert
über drei API-Aufrufe im 6-s-Abstand mit jeweils neuen Werten. Kosten: grob
das Dreifache an Prometheus-Speicher für diese Serien, unkritisch. Meine
Notiz dazu lautete noch: Push-Architektur ist für ein Ein-Personen-Dashboard
unnötig, auch UniFi pollt nur kurz und pusht dann.
Anlauf zwei, am selben Abend: Es war immer noch poll-träge. Der Denkfehler stand in meiner eigenen Notiz. „Live“ hat zwei unabhängige Achsen — Datenfrische (Scrape-Intervall) und Zustell-Latenz (Poll oder Push) — und flüssig wird es erst mit beidem. Über Prometheus geht Sekundentakt prinzipbedingt nicht, der Weg Scrape → TSDB → Query ist zu lang. Also ein bewusster Bruch zweier V1-Invarianten, dokumentiert und eng begrenzt: ein zweiter, schmaler Datenpfad nur für Momentwerte. Ein Hintergrund-Task im Backend liest sekündlich den node_exporter aller Inventory-Hosts und den Traffic-Endpunkt der OPNsense-API (denselben, den das Router-Dashboard selbst im Sekundentakt nutzt), rechnet aus Counter-Deltas 1-s-Raten (Counter-Reset ergibt keinen Wert, nie eine negative Zahl) und pusht per Server-Sent Events an das Frontend. Ein Poller für n Clients, langsame Clients werden abgehängt. Status, Alerts und History bleiben beim Prometheus-Pfad; verworfen habe ich Netdata daneben (zweites Dashboard) und Prometheus auf 1-s-Scrape (teuer, bleibt Poll-Gefühl).
Ergebnis: 1 Event pro Sekunde mit echt wechselnden Werten. Der
WAN-Empfang sprang in einem Tick von 0,76 auf 7,89 Mbit/s — genau die
Spitze, die der 3-Minuten-Durchschnitt vorher unsichtbar gemacht hat. SSE
reicht völlig: unidirektional, ein Streaming-Endpunkt, EventSource
reconnectet von selbst; WebSocket wäre Mehraufwand ohne Nutzen. Und
node_exporter sekündlich zu lesen ist billig — rund 200 KB Text, gefiltert
geparst.
Zwei Tage später geriet genau dieser Stream unter Verdacht, als der Tab der Übersicht einfror — zu Unrecht.