Zum Inhalt springen
labkompass

Logbuch#monitoring#prometheus#zeitreihen#storage

Von Prometheus auf VictoriaMetrics: 3 Jahre Historie für ein Sechstel des Platzes

Von Niclas Hennrich


BuildIm Einsatz

Selbst gebaut und in Betrieb genommen. Gehört zum Vorhaben Homelab Control Center.

Gleicher Datenbestand (vorher 197 MB)
33.6MB
Retention (vorher 30 Tage)
3Jahre
Abweichende Abfragen von 124
0

Was ich wollte: Verläufe der Homelab-Metriken über lange Zeiträume ansehen — von fünf Minuten bis über ganze Jahre. Auslöser war die neue Hardware-Ansicht im Control Center: Die Werte waren da, aber die Historie endete nach 30 Tagen.

Mein erster Gedanke war, die Werte zusätzlich in eine PostgreSQL-Tabelle zu schreiben. Das wäre der Fehler des Monats geworden.

Warum die Tabelle Unsinn war: Eine Rollup-Tabelle hätte eine Zeitreihendatenbank in einer relationalen nachgebaut — Schema, Schreib-Task, Aggregationsfenster, eigene Aufräumlogik, und danach in jeder Abfrage eine Regel, welche der beiden Quellen gerade gilt. Genau dort entstehen Widersprüche, die hinterher niemand mehr aufklärt. Vor allem aber: Das Hindernis war nie die Datenbank, sondern die Retention-Einstellung. Eine zweite Ablage hätte das nicht gelöst.

Die naive Alternative — Retention einfach auf ein Jahr hochsetzen — hätte rund 126 GB gekostet. Machbar bei 336 GB frei, aber verschwenderisch: Der Großteil davon ist Container-Rauschen, das nie jemand nach Jahren abfragt.

Was ich stattdessen gemacht habe: VictoriaMetrics spricht dieselbe Abfragesprache wie Prometheus, liest dieselbe Konfigurationsdatei und lag bei mir ohnehin hinter einer eigenen Zwischenschicht. Der Tausch berührte deshalb keine einzige aufrufende Stelle.

PrometheusVictoriaMetrics
Platz bei identischem Datenbestand197 MB33,6 MB
Retention30 Tage3 Jahre
Abweichende Abfragen (von 124)0

Die Migration selbst: 128,4 Millionen Messpunkte in 58 Sekunden.

Vorgegangen bin ich bewusst in Etappen, weil ich ein laufendes Bauteil ersetzt habe: neuen Speicher parallel starten, beide sammeln vier Minuten lang dieselben Ziele, dann acht Kernmetriken vergleichen, dann alle 124 Abfragen des Projekts gegen beide Speicher prüfen, dann erst die Historie migrieren — und erst ganz zum Schluss umschalten. Das kostete eine halbe Stunde und ersparte jedes Risiko.

Der Fehler, den ich fast geglaubt hätte: Nach der Migration meldete der neue Speicher eine CPU-Leistung von bis zu 175 Watt. Bei einer CPU, deren Grenze bei 92 Watt liegt und die normalerweise bei 31,6 Watt unter Volllast landet. Der Energiezähler schien um 3.500 Joule in 15 Sekunden zu springen.

Ursache: Der Import umfasste einen Zeitraum, den der neue Speicher zu dem Zeitpunkt bereits selbst mitgeschrieben hatte. An dieser Nahtstelle lagen zwei Datensätze übereinander, und die Ratenberechnung addierte beide. Die Lösung war nicht Deduplizierung — die hätte das Problem kaschiert — sondern ein harter Schnitt: Datenbestand verworfen, neu aufgesetzt und nur noch Daten importiert, die älter sind als das erste eigene Sample.

Was ich daraus mitnehme, in der Reihenfolge des Ärgers:

  • Physikalische Grenzen sind die beste Prüfung. Eine 35-Watt-CPU kann keine 175 Watt ziehen. Dieser eine Abgleich fand einen Fehler, den kein Testlauf gefunden hätte. Seitdem prüfe ich nach jeder Datenmigration die gesamte Historie gegen das, was physikalisch überhaupt möglich ist.
  • Bei Datenmigrationen ist Überlappung der Feind. Import und laufende Sammlung dürfen sich nicht überschneiden.
  • Messungen auf einem Rechner, der schläft, sind wertlos. Eine Stunde Fehlersuche ging für ein Artefakt drauf, das nur auf meinem Laptop existierte: Der Mac schläft, die Zähler stehen still, die Zeitstempel springen — und die Ratenberechnung rechnet fröhlich über die Lücke. Ergebnis waren −665 % CPU-Auslastung, und zwar in beiden Speichern. Der Fehler lag nie an einem von ihnen.
  • Grüne Tests beweisen keine heile Produktion. Ein Refactoring löschte mir ein ganzes Kapitel aus der Abfrage-Datei. 178 Tests blieben grün, weil die betreffenden Tests über einen Mock laufen und den echten Pfad nie anfassen. Aufgefallen ist es als HTTP 500 in Produktion.
  • Runbooks altern still mit. Nach dem Abbau zeigten fünf meiner eigenen Betriebsanleitungen auf einen Port, an dem nichts mehr antwortet. Ein Bauteil zu ersetzen heißt auch, alles zu finden, was seinen Namen oder seine Adresse kennt.
  • Eine Abstraktion zahlt sich erst beim Tausch aus. Die Zwischenschicht war seit dem ersten Tag da und wirkte lange wie überflüssige Struktur.

Nebenbei mitgenommen: Die Diagramme kennen jetzt Zeiträume von fünf Minuten bis zu einem Jahr, und alle sinnvoll live darstellbaren Hardwarewerte laufen im Sekundentakt durch den bestehenden Stream. Das kostete keine zusätzliche Last — die vollständige Exporter-Antwort wurde ohnehin jede Sekunde geholt, die betreffenden Zeilen bisher nur weggeworfen.