
VictoriaMetrics — eine schnelle und skalierbare Datenbank zur Speicherung und Verarbeitung von Zeitreihendaten (eine Aufzeichnung besteht aus Zeitstempeln und einem Satz zugehöriger Werte, wie beispielsweise den regelmäßig abgefragten Status von Sensoren oder gesammelten Metriken).


Mein Name ist Kolobaev Pavel. DevOps, SRE, LeroyMerlin, alles als Code – das beschreibt uns: mich und die anderen Mitarbeiter von LeroyMerlin.

Es gibt eine Cloud auf Basis von OpenStack. Dort gibt es einen kleinen Link zum Tech-Radar.

Sie basiert auf Kubernetes-Hardware sowie auf allen unterstützenden Diensten für OpenStack und Logging.

Unser Entwicklungsansatz sah folgendermaßen aus. Während der Entwicklung hatten wir einen Prometheus-Operator, der die Daten innerhalb des K8s-Clusters speicherte. Er findet automatisch, was zu scrapen ist und legt es sich quasi vor die Füße.

Alle Daten müssen wir aus dem Kubernetes-Cluster herausziehen, denn wenn etwas passiert, müssen wir verstehen, was und wo ist.

Die erste Lösung – wir verwenden Federation, wenn wir einen externen Prometheus haben und durch das Federation-Mechanismus auf das Kubernetes-Cluster zugreifen.

Hier gibt es jedoch ein paar Probleme. In unserem Fall traten die Probleme auf, als wir 250.000 Metriken hatten, und als es 400.000 wurden, merkten wir, dass wir so nicht weiterarbeiten konnten. Wir haben den scrape_timeout auf 25 Sekunden erhöht.
Warum mussten wir das tun? Prometheus beginnt die Zeit für das Timeout ab dem Zeitpunkt der Abholung zu zählen. Es spielt keine Rolle, dass die Daten weiterhin fließen. Wenn in diesem angegebenen Zeitraum keine Daten übertragen wurden und die Sitzung nicht über HTTP geschlossen wird, gilt die Sitzung als gescheitert und die Daten gelangen nicht in Prometheus.

Allen sind die Grafiken vertraut, die wir erhalten, wenn Teile der Daten fehlen. Die Grafiken sind unregelmäßig, und das gefällt uns nicht.

Die nächste Möglichkeit ist das Sharding basierend auf zwei verschiedenen Prometheus-Instanzen über dasselbe Federation-Mechanismus.
Zum Beispiel einfach nach Namen shardieren. Das kann man auch verwenden, aber wir haben uns entschieden, weiterzugehen.

Wir müssen diese Shards nun irgendwie verarbeiten. Man kann promxy verwenden, das in den Shard-Bereich geht und die Daten multipliziert. Es arbeitet mit zwei Shards als einem einzigen Einstiegspunkt. So etwas kann über promxy realisiert werden, ist aber momentan zu kompliziert.

Die erste Option besteht darin, auf den Federation-Mechanismus zu verzichten, da er sehr langsam ist.
Die Entwickler von Prometheus sagen eindeutig: „Leute, verwendet andere TimescaleDB, denn wir werden die langfristige Speicherung von Metriken nicht unterstützen.“ Das ist nicht ihre Aufgabe. 
Wir notieren uns auf Papier, dass wir dennoch einen Export nach außen benötigen, um nicht alles an einem Ort zu speichern.

Ein weiterer Nachteil ist der Speicherverbrauch. Ja, ich verstehe, dass viele sagen werden, dass ein paar Gigabyte RAM im Jahr 2020 günstig sind, dennoch ist es ein Faktor.
Aktuell haben wir eine Entwicklungs- und eine Produktionsumgebung. In der Entwicklungsumgebung sind es etwa 9 Gigabyte für 350.000 Metriken. In der Produktionsumgebung sind es etwas über 14 Gigabyte für 780.000 Metriken. Dabei beträgt die Retentionszeit nur 30 Minuten. Das ist unzureichend. Ich werde erklären, warum.

Wir analysieren, das heißt, bei anderthalb Millionen Metriken – wir sind bereits nahe daran – erhalten wir bereits in der Planungsphase 35-37 Gigabyte RAM. Bei 4 Millionen Metriken benötigen wir dann bereits etwa 90 Gigabyte RAM. Dies wurde nach der Formel berechnet, die die Entwickler von Prometheus zur Verfügung stellen. Wir haben die Korrelation untersucht und sind zu dem Schluss gekommen, dass wir nicht bereit sind, ein paar Millionen nur für einen Überwachungsserver zu zahlen.
Wir erhalten nicht nur eine größere Anzahl an Maschinen, sondern überwachen auch die virtuellen Maschinen selbst. Je mehr virtuelle Maschinen wir haben, desto mehr verschiedene Metriken ergeben sich. Unser Cluster wird speziell in Bezug auf diese Metriken wachsen.

Mit dem Speicherplatz sieht es hier nicht so düster aus, aber es gibt noch Verbesserungsbedarf. In den letzten 15 Tagen haben wir insgesamt 120 Gigabyte erhalten, davon 100 Gigabyte komprimierte Daten und 20 Gigabyte unkomprimierte Daten. Wir hätten gerne weniger.

Daher fügen wir einen weiteren Punkt hinzu: der hohe Ressourcenverbrauch, den wir reduzieren möchten. Wir wollen nicht, dass unser Überwachungs-Cluster mehr Ressourcen benötigt als der Cluster, der für die Verwaltung von OpenStack zuständig ist.

Ein weiterer Nachteil von Prometheus, den wir festgestellt haben, ist, dass es eine Art Speicherkontingent gibt. Damit sieht es bei Prometheus deutlich schlechter aus, da es kein solches Management gibt. Eine Begrenzung im Docker ist ebenfalls keine Lösung. Wenn beispielsweise Ihr RAF ausfällt und 20-30 Gigabyte erreicht, wird es sehr lange dauern, bis es wieder hochkommt.

Das ist ein weiterer Grund, warum Prometheus für uns nicht geeignet ist; man kann den Speicherverbrauch nicht begrenzen.

Wir können ein solches Schema in Betracht ziehen. Dieses Schema ist notwendig, um ein HA-Cluster zu organisieren. Wir möchten, dass unsere Metriken jederzeit und überall verfügbar sind, selbst wenn der Server, der diese Metriken speichert, ausfällt. Daher müssen wir ein solches Schema erstellen.
Dieses Schema besagt, dass wir eine Duplizierung der Shards haben werden, und somit auch eine Verdopplung der Ressourcen, die benötigt werden. Es kann fast horizontal skaliert werden, aber trotzdem wird der Ressourcenverbrauch enorm sein.

Die Nachteile in der Reihenfolge, wie wir sie für uns aufgeschrieben haben:
- Es ist notwendig, die Metriken extern zu exportieren.
- Ein hoher Ressourcenverbrauch.
- Der Speicherverbrauch kann nicht begrenzt werden.
- Die Umsetzung von HA ist komplex und ressourcenintensiv.

Wir haben entschieden, dass wir von Prometheus als Speicherlösung Abstand nehmen.
Wir haben für uns noch zusätzliche Anforderungen festgelegt, die wir benötigen. Dazu gehören:
- Die Unterstützung von promql, da bereits vieles unter Prometheus geschrieben wurde: Abfragen, Alarme.
- Und wir haben Grafana, das ebenfalls für Prometheus als Backend geschrieben ist. Wir möchten die Dashboards nicht neu schreiben.
- Wir möchten eine ordentliche HA-Architektur aufbauen.
- Wir möchten den Verbrauch aller Ressourcen reduzieren.
- Es gibt noch einen kleinen Aspekt. Wir können verschiedene Cloud-Metrik-Collection-Systeme nicht verwenden. Wir wissen bisher nicht, was in diese Metriken fließt. Und da alles Mögliche erfasst werden kann, sind wir gezwungen, uns auf lokale Speicherungen zu beschränken.

Die Auswahl war nicht groß. Wir haben alles zusammengetragen, wo wir Erfahrung haben. Wir haben die Seite von Prometheus im Bereich Integrationen angesehen, viele Artikel gelesen und geschaut, was es sonst noch gibt. Für uns haben wir VictoriaMetrics als Ersatz für Prometheus gewählt.
Warum? Weil:
- es promql beherrscht.
- es eine modulare Architektur hat.
- es keine Änderungen in Grafana benötigt.
- Und das Wichtigste – wir planen möglicherweise, eine Metrik-Speicherung innerhalb unseres Unternehmens als Service anzubieten. Deshalb schauen wir uns im Voraus nach Einschränkungen um, damit die Nutzer alle Ressourcen des Clusters in einem begrenzten Rahmen nutzen können, da die Wahrscheinlichkeit besteht, dass er Multitenancy unterstützt.

Wir machen den ersten Vergleich. Wir nehmen denselben Prometheus innerhalb des Clusters, auf den ein externer Prometheus zugreift. Wir fügen über remoteWrite VictoriaMetrics hinzu.

Ich möchte gleich klarstellen, dass wir hier einen leichten Anstieg des CPU-Verbrauchs bei VictoriaMetrics beobachtet haben. Auf der VictoriaMetrics-Wiki stehen die optimalen Parameter. Wir haben sie überprüft. Sie haben den CPU-Verbrauch deutlich gesenkt.
In unserem Fall ist der Speicherverbrauch von Prometheus, der sich im Kubernetes-Cluster befindet, nur geringfügig gestiegen.

Wir vergleichen zwei Datenquellen mit denselben Daten. In Prometheus sehen wir all die fehlenden Daten. Bei VictoriaMetrics ist alles in Ordnung.

Testergebnisse zu Speicherplatz. Wir haben insgesamt 120 Gigabyte in Prometheus erhalten. Bei VictoriaMetrics liegt der Wert bereits bei 4 Gigabyte pro Tag. Dort wird ein etwas anderer Mechanismus verwendet als man es von Prometheus gewohnt ist. Das heißt, die Daten werden bereits gut innerhalb eines Tages, in einer halben Stunde komprimiert. Sie werden gut komprimiert, trotz der späteren Zusammenführung der Daten. Am Ende haben wir beim Speicherplatz gespart.

Auch bei unserem Speicherverbrauch sparen wir Ressourcen. Prometheus wurde zum Zeitpunkt der Tests auf einer virtuellen Maschine mit 8 Kernen und 24 Gigabyte betrieben. Prometheus beansprucht praktisch alle Ressourcen. Es wurde durch den OOM Killer beendet. Dabei wurden lediglich 900.000 aktive Metriken verarbeitet. Das sind etwa 25.000-27.000 Metriken pro Sekunde.
VictoriaMetrics wurde auf einer zweikernigen virtuellen Maschine mit 8 Gigabyte RAM gestartet. Es gelang uns, VictoriaMetrics gut arbeiten zu lassen, indem wir einige Anpassungen auf der 8-Gigabyte-Maschine vorgenommen haben. Am Ende kamen wir mit 7 Gigabyte aus. Dabei erreichten wir sogar eine höhere Inhaltsausgabe, also Metriken, als bei Prometheus.

Die CPU-Nutzung ist im Vergleich zu Prometheus erheblich besser geworden. Hier benötigt Prometheus 2,5 Kerne und VictoriaMetrics nur 0,25 Kerne. Zu Beginn – 0,5 Kerne. Mit zunehmender Nutzung erreicht es ein ganzes Kern, was jedoch äußerst selten vorkommt.

In unserem Fall fiel die Wahl auf VictoriaMetrics aus nachvollziehbaren Gründen – wir wollten sparen und haben es auch getan.

Zwei Punkte streichen wir gleich von der Liste – das Exportieren von Metriken und den hohen Ressourcenverbrauch. Damit bleibt uns noch die Entscheidung über zwei Punkte, die wir uns vorbehalten haben.

Hier sei gleich gesagt, dass wir VictoriaMetrics als ein Metrik-Speicher betrachten. Da wir jedoch wahrscheinlich VictoriaMetrics als Speicher für das gesamte Leroy bereitstellen werden, sollten wir die Nutzer, die diesen Cluster verwenden, einschränken, damit sie uns diesen nicht überlasten.
Es gibt eine hervorragende Option, mit der man nach Zeit, Datenvolumen und Ausführungszeit begrenzen kann.
Und es gibt auch eine großartige Funktion, die den Speicherverbrauch begrenzt, sodass wir das richtige Gleichgewicht finden können, um eine angemessene Geschwindigkeit und einen vernünftigen Ressourcenverbrauch zu erreichen.

Ein weiterer Punkt, den wir streichen müssen – es ist nicht möglich, den Speicherverbrauch zu begrenzen.

In den ersten Iterationen haben wir VictoriaMetrics Single Node getestet. Jetzt wechseln wir zur VictoriaMetrics Cluster-Version.
Hier haben wir die Freiheit, verschiedene Dienste in VictoriaMetrics zu verteilen, abhängig davon, auf welchen Ressourcen sie laufen und welche Ressourcen sie verbrauchen. Das ist eine sehr flexible und praktische Lösung, die wir selbst genutzt haben.

Die Hauptkomponenten der VictoriaMetrics Cluster-Version sind vmstorage. Davon kann es eine beliebige Anzahl geben. In unserem Fall sind es derzeit zwei.
Und es gibt vminsert. Dies ist ein Proxy-Server, der es uns ermöglicht, Sharding zwischen allen Speichern einzurichten, über die wir ihm berichtet haben, und er ermöglicht auch Replikation, das heißt, Sie erhalten sowohl Sharding als auch Replikation.
Vminsert unterstützt die Protokolle OpenTSDB, Graphite, InfluxDB und remoteWrite von Prometheus.

Es gibt auch vmselect. Seine Hauptaufgabe besteht darin, auf vmstorage zuzugreifen, die Daten von dort abzurufen, diese Daten zu deduplizieren und sie dem Kunden bereitzustellen.

Es gibt eine großartige Funktion namens vmagent. Wir sind sehr begeistert davon. Sie ermöglicht die Konfiguration genau wie Prometheus und funktioniert dabei auch genau so wie Prometheus. Das bedeutet, dass es Metriken von verschiedenen Entitäten und Services sammelt und sie an vminsert sendet. Was danach passiert, liegt ganz bei Ihnen.

Ein weiterer großartiger Dienst ist vmalert, der es ermöglicht, VictoriaMetrics als Backend zu nutzen, die von vminsert erhaltenen Daten an vmselect zu senden und dort zu verarbeiten. Es verarbeitet sowohl die Alarme als auch die Regeln. Im Falle von Alarmen erhalten wir einen Alarm über den Alertmanager.

Es gibt eine wmauth-Komponente. Diese könnte möglicherweise für unser Authentifizierungssystem in der Multitenancy-Version der Cluster verwendet werden, aber das ist noch nicht entschieden. Sie unterstützt remoteWrite für Prometheus und kann basierend auf der URL, oder genauer gesagt, dem zweiten Teil davon, autorisieren, um zu bestimmen, ob das Schreiben erlaubt ist oder nicht.

Außerdem gibt es vmbackup und vmrestore. Das ist im Wesentlichen die Wiederherstellung und das Backup aller Daten. Es unterstützt S3, GCS und Dateien.

Die erste Iteration unseres Clusters wurde während der Quarantäne erstellt. Zu diesem Zeitpunkt gab es noch keine Replikation, weshalb unsere Iteration aus zwei verschiedenen und unabhängigen Clustern bestand, die durch remoteWrite Daten empfingen.

Hier möchte ich anmerken, dass wir, als wir von VictoriaMetrics Single Node zu VictoriaMetrics Cluster Version wechselten, weiterhin die gleichen Ressourcen verbrauchten, d. h. der Hauptverbraucher war der RAM. So verteilten sich unsere Daten und damit der Ressourcenverbrauch.

Hier wurde bereits eine Replikation hinzugefügt. Wir haben alles in einem relativ großen Cluster zusammengefasst. Alle Daten werden sowohl shardiert als auch repliziert.
Der gesamte Cluster hat N Eingänge, d.h. Prometheus kann Daten über HAPROXY hinzufügen. Hier ist dieser Eingang. Über diesen Eingang kann man mit Grafana zugreifen.

In unserem Fall ist HAPROXY der einzige Port, der Select-, Insert- und andere Dienste in diesen Cluster proxied. Es war nicht möglich, eine einzige Adresse zu erstellen; wir mussten mehrere Eingänge einrichten, da die virtuellen Maschinen, auf denen der VictoriaMetrics-Cluster läuft, in verschiedenen Zonen eines Cloud-Anbieters liegen, d.h. nicht in unserer Cloud, sondern außerhalb.

Wir haben ein Alerting-System. Wir verwenden es. Wir nutzen den Alertmanager von Prometheus. Als Kommunikationskanäle für Alerts verwenden wir Opsgenie und Telegram. In Telegram erhalten wir Meldungen von den Entwicklern, möglicherweise etwas von der Produktionsumgebung, aber meistens sind es statistische Informationen, die für die Ingenieure wichtig sind. Opsgenie hingegen wird für kritische Vorfälle genutzt. Das beinhaltet Anrufe und das Incident Management.

Die ewige Frage: „Wer überwacht die Überwachung?“. In unserem Fall überwacht die Überwachung sich selbst, denn wir nutzen vmagent auf jeder Node. Da unsere Nodes über verschiedene Rechenzentren eines Anbieters verteilt sind, hat jedes Rechenzentrum seinen eigenen Kanal, die unabhängig sind. Selbst bei einem Split-Brain-Szenario erhalten wir weiterhin Alarme. Ja, es werden mehr Alarme sein, aber lieber mehr Alarme als gar keine.

Wir schließen unsere Liste mit der Implementierung von HA ab.

Ich möchte auch die positive Erfahrung mit der Community von VictoriaMetrics hervorheben. Es war sehr angenehm. Die Leute sind hilfsbereit und versuchen, jeden vorgeschlagenen Fall zu verstehen.
Ich habe Issues auf GitHub eröffnet. Diese wurden sehr schnell gelöst. Es gibt noch ein paar Issues, die nicht ganz abgeschlossen sind, aber ich sehe bereits im Code, dass in dieser Richtung gearbeitet wird.
Der Hauptschmerz während der Iterationen für mich war, dass wenn ich eine Node abschalte, vminsert in den ersten 30 Sekunden nicht erkennen konnte, dass der Backend nicht verfügbar ist. Das ist jetzt jedoch gelöst. Innerhalb von ein oder zwei Sekunden werden die Daten bereits von allen verbleibenden Nodes abgerufen, und die Anfrage wartet nicht mehr auf die fehlende Node.

Wir haben irgendwann von VictoriaMetrics gewünscht, dass es einen VictoriaMetrics-Operator gibt. Jetzt ist er endlich da. Wir arbeiten aktiv daran, eine Schnittstelle über den VictoriaMetrics-Operator zu erstellen, um alle Vorberechnungsregeln etc. von Prometheus zu integrieren, da wir ziemlich aktiv die Regeln nutzen, die mit dem Prometheus-Operator geliefert werden.
Es gibt Vorschläge zur Verbesserung der Cluster-Implementierung. Ich habe diese oben dargelegt.
Und es wäre sehr wünschenswert, Downsampling zu haben. In unserem Fall benötigen wir Downsampling ausschließlich für die Anzeige von Trends. Grob gesagt, reicht mir eine Metrik über den Tag aus. Diese Trends sind für ein Jahr, drei Jahre, fünf Jahre oder sogar zehn Jahre notwendig. Ein einzelner Metrikwert ist völlig ausreichend.

- Wir haben wie einige unserer Kollegen die Schmerzlichkeit bei der Nutzung von Prometheus erfahren.
- Wir haben uns für VictoriaMetrics entschieden.
- Es skaliert sowohl vertikal als auch horizontal ziemlich gut.
- Wir können verschiedene Komponenten auf unterschiedliche Knoten im Cluster verteilen, deren Speicherkapazität begrenzen und zusätzliche Speicherkapazität hinzufügen usw.
Wir werden VictoriaMetrics bei uns verwenden, da es uns sehr gefällt. So war es und so ist es jetzt.

Ein paar QR-Codes zum VictoriaMetrics-Chat, meine Kontaktdaten, Tech-Radar von LeroyMerlin.
Quelle: habr.com
