Langzeitspeicherung von Prometheus-Metriken (Alexey Palazhchenko, Percona)

In kurzer Zeit hat sich Prometheus zu einem der beliebtesten Überwachungsinstrumente entwickelt. Vielen Dank insbesondere und die hohe Geschwindigkeit seiner Arbeit. Der lokale Speicher eignet sich hervorragend zum kurzfristigen Speichern von Metriken und zum Arbeiten mit diesen. Manchmal möchten Sie die Metriken über Monate und Jahre verteilt halten und dabei alte Daten automatisch abschneiden, ohne jedoch die Benutzeroberfläche für die Arbeit mit ihnen zu ändern.


Genau dazu die Entschlüsselung des Berichts von Alexey Palazhchenko auf der RootConf 2018. In dem Bericht: Prometheus, TSDB für lokalen Speicher, Prometheus für Remote-Speicher, PromQL, TSDB, Clickhouse, PromHouse, ein wenig InfluxDB.



Wen kümmert es bitte unter der Katze.


Freunde! Hallo allerseits! Ich heiße Alexey Palazhchenko. Ich arbeite bei Percona. Ich möchte Sie über die Langzeitspeicherung von Metriken in Prometheus informieren.



Ich arbeite bei Percona und mache ein Produkt namens Percona Monitoring and Management. Dies ist die Box-Lösung, die unsere Kunden für sich selbst festgelegt haben. PMM ist vollständig Open Source. Es besteht aus Prometheus, Grafana für die grafische Darstellung, einer benutzerdefinierten Abfrageanalyse-Software und unserem eigenen Wrapper, mit dem Sie einige Verwaltungsaufgaben übernehmen können. Zum Beispiel können Sie Prometheus ein Kratzziel hinzufügen. Dies sind neue Quellen, aus denen er Metriken entnimmt, ohne manuell einen Container oder eine virtuelle Maschine eingeben und die Konfigurationsdatei bearbeiten zu müssen.


Es ist wichtig zu verstehen, dass dies kein SaaS ist. Wir haben keine Produktion. Unsere Produktion befindet sich bei unseren Kunden. Daran zu experimentieren ist nicht sehr gut. Wir haben das Nächste, was man als Produktion bezeichnen könnte - dies ist https://pmmdemo.percona.com/ . Zum Zeitpunkt des Berichts musste pmmdemo.percona.com aufgrund der DSGVO geschlossen werden.


Wir liefern PMM an Kunden - eine Box-Lösung: ein Docker-Container oder eine virtuelle Maschine. Sie alle mögen Prometheus. Einige Leute, die Prometheus zum ersten Mal betrachten, stoßen auf ein Pull-Modell. Für Anfänger ist dies unpraktisch. Im Allgemeinen ein separates großes Gespräch. Sie können über Pull- oder Push-Methoden streiten. Im Durchschnitt ist dies ungefähr das Gleiche.


Einige Dinge in Prometheus sind sehr cool.


  • Prometheus-Abfragesprache ist wirklich eine coole Sache, die nirgendwo analog ist.


  • Das zweite, was Ihnen gefällt, ist die Serviceerkennung. Wenn Sie über eine dynamische Infrastruktur verfügen, Kubernetes, müssen Sie automatisch nicht alle Ziele für die Überwachung mit Ihren Händen hinzufügen. Wenn statisch - kann dies auch ganz einfach erfolgen. Sie müssen die Konfigurationsdatei verwenden.



Prometheus-Kunden mögen es. Sie wollen Metriken immer länger halten. Jemand verwendet Prometheus nur zur Betriebsüberwachung. Aber jemand möchte die Metriken länger behalten, die Dynamik beobachten und mit den Grafiken vor einem Jahr vergleichen. Gleichzeitig ist das Ziel der langfristigen Speicherung von Metriken nicht das Ziel des Prometheus-Projekts. Ursprünglich wurde es erstellt, um Metriken für kurze Zeit zu speichern. SoundCloud speichert Metriken in nur wenigen Tagen. Es gibt Mechanismen in Prometheus, die es Ihnen ermöglichen, dies länger zu tun, aber sie sind etwas seitlich angeordnet. Daher können wir eine Entscheidung für das Prometheus-Ökosystem treffen, ohne den Kern des Systems selbst zu verändern. Basierend auf ihnen können wir unsere eigene Entscheidung innerhalb desselben Ökosystems treffen.



Dies ist kein Bericht über vorgefertigte Lösungen. Dies ist ein Bericht über unsere Erfahrung, über unseren Schmerz, über unsere Versuche. Wenn Sie erwartet haben, dass Sie nach diesem Bericht das Repository oder den Docker-Container herunterladen, ausführen und es funktioniert, ist dies nicht der Fall. Aber gleichzeitig ist es nah genug daran. Wir haben einige Grundlagen. Sie sind alle Open Source. Sie können es versuchen. Sie sind noch nicht produktionsbereit. Mit den Informationen in diesem Bericht können Sie jedoch verstehen, warum und was besser gemacht werden kann. Sie können Ihre eigene Entscheidung treffen, die gut zu Ihnen passt.



Wie werden Metriken in Prometheus gespeichert? Es gibt lokalen Speicher. Es gibt Remote-Speicher. Dies sind eigentlich zwei verschiedene Welten. Sie kreuzen sich schwach. Daher ist der Bericht auch in zwei Teile gegliedert.



Wenn Sie bei einem früheren Bericht in der Haupthalle waren, wo es in Prometheus ein gutes Intro gab, wissen Sie, dass der lokale Speicher eine separate Bibliothek namens TSDB ist. TSDB hat nichts mit OpenTSDB zu tun. TSDB ist ein separates Go-Paket, das Sie von Ihrem Go-Programm aus verwenden können. Auf der Ebene der TSDB-Bibliothek gibt es keinen Client oder Server.


Diese Bibliothek ist für die Arbeit mit Zeitreihendaten optimiert. Beispielsweise verfügt die TSDB über eine Delta-Codierung, mit der Sie nicht die Nummern selbst, sondern die Änderungen zwischen diesen Nummern speichern können. Auf diese Weise können Sie 1 Byte anstelle von 16 Byte speichern. 1 Byte für die Zeit und 1 Byte für den Wert. Das heißt, Sie speichern aufgrund dieser guten Komprimierung durchschnittlich 1 oder 2 Bytes genau.


TSDB ist für Pull-Modelle optimiert. Daten werden nur dort hinzugefügt. Prometheus kann keine historischen Daten schreiben. Hierfür gibt es keine API. Das maximale Delta beträgt ungefähr 5 Minuten. Wenn die Daten älter sind, werden sie nicht akzeptiert.


In der TSDB ist kein Downsampling von tsdb # 313 integriert. Es gibt ein offenes Thema, in dem darüber diskutiert wurde, dass es im Allgemeinen Projekte gibt, die Prometheus etwas bewirken, und dass es dort ein Downsampling gibt. Bisher besteht die Lösung darin, dass TSDB kein Downsampling hinzufügt.



Wie würden wir Daten von TSDB erhalten? TSDB ist eine Datenbank auf der Festplatte. Sie können damit arbeiten, wenn Sie ein Go-Programm schreiben. Wenn Sie jedoch kein Programm in Go schreiben, gibt es eine JSON-API, mit der Sie Abfrageabfragen durchführen können. Wenn Sie jemals Prometheus verwendet und mindestens einmal ein Diagramm erstellt haben, kennen Sie die Standard-Abfrage-API, in der es einen Abfrageparameter gibt, in dem Sie jede PromQL-Abfrage und optional die Zeit ausführen können. Wenn keine Zeit vorhanden ist, wird die aktuelle Zeit verwendet.


Auf der Folie wird eine bestimmte Abfrage hervorgehoben, die Sie im wirklichen Leben selten sehen. Das ist ein Hack. Dies ermöglicht es uns, alle Metriken von Prometheus herauszuholen. Wie funktioniert es Auf der Ebene von PromQL wird gesagt, dass es unmöglich ist, einen solchen Ausdruck zu schreiben, der alle Zeitreihen abfängt. Dies ist direkt in den Regeln geschrieben. Eine andere Regel besagt, dass Sie keinen Matcher erstellen können, in dem alle Werte leer sind. Wenn Sie einfach geschweifte Klammern schreiben, funktioniert dies nicht. Wenn Sie schreiben, dass der Name nichts entspricht (kein leerer Wert), funktioniert dies nicht. Aber dies ist ein echter Hack, mit dem Sie dies tun können. Es ist jedoch nicht einmal besonders dokumentiert. Es gibt Kommentare im Code selbst, dass dies funktioniert.


Die zweite Abfrage ist query_range, die dasselbe tut, aber Sie Daten in einem Bereich und mit einem Schritt zurückgibt. Im Wesentlichen wird für jeden Schritt vom Anfang bis zum Ende mehrmals eine Abfrage durchgeführt. Dies ist die API zum Zeichnen von Grafiken. Die erste API verwendet, um Sofortwerte abzurufen.



Wir haben eine API zum Abrufen von Metadaten. Wenn wir alle Namen der Metriken erhalten möchten, führen wir eine Abfrage wie diese durch, wobei match ein Array von Metriken ist. Es mag mehrere Argumente geben, aber in diesem Fall übergeben wir die gleiche Übereinstimmung, die uns alles zurückgibt.


Die zweite Meta-API, die den Wert aller Labels zurückgibt. Wenn wir eine Liste aller Jobs sehen möchten, schreiben wir anstelle von label_name einen Job und erhalten diese Liste. Diese APIs geben JSON an uns zurück.



Es gibt eine weitere API, die alle Metriken von Prometheus selbst in einem Format zurückgibt, das für Exporteure typisch ist. Das Format heißt expfmt. In Prometheus selbst gibt es eine Federation-API, mit der Sie eine solche Anfrage stellen können. Wofür ist das? Die einfachste Option: Wenn Sie Code haben, der bereits mit expfmt funktioniert, müssen Sie ihn nicht neu trainieren, um mit einer benutzerdefinierten JSON-API zu arbeiten. Dieses Format ist viel einfacher zu streamen, denn wenn Sie JSON irgendwo auf der obersten Ebene des Objekts haben, müssen Sie dieses Objekt meistens als Ganzes analysieren. Hier kann es Zeile für Zeile erfolgen.


Das Wichtigste ist, dass es sich um eine separate API handelt. Es funktioniert genau wie ein echter Export. Sie können den anderen Prometheus nehmen, um ihn abzukratzen. Dies ist ein regulärer Job mit den üblichen Parametern. Sie müssen den Parameter - Abfrage-URL übergeben. Wenn Sie eine Curl-Anfrage stellen, erhalten Sie diese hier. Wir erhalten alle Metriken für den aktuellen Zeitwert. Die einzige Einschränkung: Sie müssen honor_labels festlegen, damit Prometheus, der einen anderen Prometheus über diese API verschrottet, den Wert der Job- und Instanzbezeichnung nicht beeinträchtigt. Mit dieser Federation-API können Sie alle Daten von einem Prometheus auf einen anderen laden.



Wie kann das genutzt werden?


Das Wichtigste ist, dass Sie dies nicht tun müssen. TSDB ist für verschiedene Betriebsarten optimiert. Wenn Sie einen Prometheus haben, der viele Daten kratzt, dann macht er viele I / O. Wenn Sie die Verbund-API verwenden, erhöht sich die Menge der Eingabe um das Zweifache. Es gibt Nuancen. Abhängig davon, wie oft Sie am Verbund kratzen und wie oft Sie die Ziele kratzen. Wenn die Zeit nicht geändert wurde, verdoppelt dies die Last wirklich. Wenn Sie also Ihren Prometheus skalieren und die Föderation aktivieren möchten, werden Sie ihn töten. Die Last wird sich verdoppeln.


Zweiter Moment. Sie überspringen Daten. Sie erhalten einen Datenkonflikt. Warum so? Diese API ist, wie fast jede API in Prometheus, nicht atomar. Wenn neue Daten eintreffen, endet ein neues Scraping in dem Moment, in dem Ihre Verbundanforderung noch ausgeführt wird. Sie können Daten für eine Zeitreihe und neue Daten für eine andere abrufen. Wenn es sich um eine nicht verwandte Zeitreihe handelt, ist sie im Allgemeinen nicht beängstigend. Wenn Sie jedoch eine Zusammenfassung oder ein Histogramm haben, das auf expfmt-Ebene durch mehrere grundlegende Metriken dargestellt wird, besteht eine Inkonsistenz zwischen diesen.



Wie können wir dieses atomare Problem lösen? Prometheus verfügt über Aufzeichnungsregeln, mit denen Sie aus einer vorhandenen Zeitreihe eine neue Zeitreihe erstellen können. Dies kann weniger häufig durchgeführt werden. Dies ist eine Möglichkeit zum Downsampling. Verschrotten Sie beispielsweise das Ziel jede Sekunde, aber dann möchten wir die node_cpu-Aggregation in einer Minute durchführen. Durch Gruppieren in Prometheus 2.0 können Sie diese Aggregationen nacheinander durchführen. Regeln, die sich in derselben Gruppe befinden, werden streng nacheinander ausgeführt. Zu diesem Zeitpunkt gibt es kein Atomitätsproblem, es gibt kein Problem, dass sich die Daten im Prozess ändern. Dies löst jedoch nicht das Problem der Tatsache, dass einige andere Daten zulässig sind, die logisch damit verbunden sind, aber aus Sicht des Datenmodells nicht verbunden sind. Es gibt noch keine reine Atomizität. Zu diesem Thema gibt es ein offenes Thema. Sie können Schnappschüsse machen. Sie können eine PromQL-Abfrage an die TSDB-Datenbank senden und alle Stichproben, die kleiner als ein Wert der Zeit sind, die mit der Auswertung begonnen hat, aus den erhaltenen Werten löschen. Dies wäre der einfachste Weg, aber bisher wurde dies nicht getan.


Es ist wichtig zu verstehen, dass die Aufzeichnungsregeln auf dem unteren Prometheus und nicht auf dem des Verbandes durchgeführt werden müssen. Andernfalls überspringen Sie Spitzen, und Ihre Überwachung funktioniert nicht ordnungsgemäß.



Wie können wir diese Kombination dieser Dinge verwenden, um Downsampling und Langzeitspeicherung durchzuführen?


Der erste. Wir haben gerade einen Verband gegründet und alle Daten von diesem Prometheus heruntergeladen. Dieser seltsame reguläre Ausdruck ist wie ein Zoidberg - es ist eigentlich nur ein Doppelpunkt. Ein Sternchen links und rechts vom Doppelpunkt. Wir verwenden den Standardnamen für Aufzeichnungsregeln, der der Mitte einen Doppelpunkt hinzufügt. Beim Teilen des ursprünglichen Namens wird links eine Aggregationsebene und rechts eine Funktion angezeigt. Eine normale Doppelpunktmetrik nicht. Wenn es einen Doppelpunkt gibt, ist dies ein Zeichen dafür, dass dies eine Aggregation ist. Danach verwenden wir diesen Metriknamen in unserem Diagramm. Wenn wir möchten, dass unser Zeitplan, unser Dashboard in grafana, mit dem Haupt-Prometheus und mit denen, die höher sind, zusammenarbeitet, können wir den Ausdruck oder verwenden . Wir nehmen entweder die eine oder die andere Metrik, je nachdem, welche. Wir können betrügen und Relabeling verwenden, um die neue Metrik in den alten Namen umzubenennen. Dies ist ein ziemlich gefährlicher Ansatz. Sie können reguläre Anhänge falsch buchstabieren und es kommt zu einem Zeitreihenkonflikt. Prometheus schreibt viele Warnungen in das Protokoll. Sie werden dies sehen, aber es kann ziemlich schwierig sein, den Grund zu finden. Wenn dies jedoch sorgfältig durchgeführt wird, z. B. indem diese regulären Ausdrücke programmgesteuert generiert werden, funktioniert dies. Als nächstes haben Sie ein reguläres Dashboard, in dem nur node_cpu verwendet wird. Je nachdem, welcher Prometheus verwendet wird, erhalten Sie entweder Rohdaten oder aggregierte Daten.



Wie gesagt, Aufnahmeregeln können ganz einfach generiert werden. Wir bekommen einfach alle Zeitreihen durch die API, die ich bereits gezeigt habe. Wir erstellen Regeln und diese Regeln müssen die richtigen Funktionen und Operatoren verwenden. Dort muss keine Rate mit Messgerät verwendet werden. Dies wird nicht richtig funktionieren. Es sollte nur mit count verwendet werden. Auf der Ebene, auf der Sie arbeiten, verfügen Sie möglicherweise nicht über Informationen zu Datentypen. Zum Beispiel, wenn Sie expfmt verwenden. Es gibt Informationen zu den Typen. Wenn die JSON-API nicht vorhanden ist. Infolgedessen hat der Ausdruck, den Sie automatisch generieren, möglicherweise keine physikalische Bedeutung. Daher können Sie dort entweder eine weiße oder eine schwarze Liste verwenden. Generieren Sie abhängig davon entweder die Regel, die Sie benötigen, oder werfen Sie die Regeln aus, die keinen Sinn ergeben. Es gibt ein Promtool-Tool, mit dem Sie überprüfen können, ob die von Ihnen generierten Regeln und die von Ihnen generierte Konfiguration sinnvoll sind. Es hat die richtige Syntax.



Wenn wir Grafana haben und es mehrere Prometheus gibt, müssen wir wissen, an welchen Prometheus die Anfrage gesendet werden soll. Wie würden wir das machen?


Eine Möglichkeit besteht darin, einen speziellen Proxy zu erstellen, der die Zeit in der Anfrage anzeigt, und abhängig davon Prometheus auszuwählen. Die Abfragen haben eine Startzeit und eine Endzeit. Abhängig davon können Sie das Routing mit Ihren Händen durchführen. Man könnte eine Art Programm schreiben, das dies tut. In der Praxis wird dies von nginx mit dem lua-Modul oder einem kleinen Programm durchgeführt.



Brauchen wir wirklich eine API? Können wir direkt mit TSDB arbeiten? Es gibt eine Nuance. Erstens, wenn wir versuchen, TSDB zu verwenden, die jetzt von Prometheus verwendet wird, können wir dies nicht tun. Es gibt eine spezielle Sperrdatei, die dies verhindert. Wenn wir Code schreiben, der dies ignoriert, und versuchen, Daten zu lesen oder zu schreiben, werden wir sie garantiert beschädigen. Außerdem sogar lesen. Was kann getan werden? Wir können Daten über die API lesen und TSDB nebeneinander erstellen. Stoppen Sie dann Prometheus und ersetzen Sie es durch TSDB. Gleichzeitig können wir die Leistung beeinträchtigen, wenn wir alle Daten über die API lesen. Ich werde etwas später darüber sprechen.


Die zweite Option. Sie können diese Dateien kopieren (Hot Backup erstellen), dh kopieren, wie sie sind. Ja, sie werden beschädigt. Beim Öffnen wird eine Warnung angezeigt, dass die Daten beschädigt sind. Sie müssen repariert werden. Sie können neue Daten verlieren. Aber es ist uns egal. Wir wollen ein Downsampling alter Daten. Downsampling kann mit PromQL durchgeführt werden. Aber es gibt eine Nuance. Es ist viel schwieriger, es von Prometheus abzureißen als TSDB. Wenn Sie mit Go und Abhängigkeitsmanagement ein wenig vertraut sind, ist der Anbieter PromQL ein großer Schmerz. Ich würde dich nicht beraten. Vermeiden Sie dies wenn möglich.



Wir gehen zum Remote Storage über. Hat jemand mit Remote Storage in Prometheus gearbeitet? Ein paar Hände. Remote Storage ist eine API, die es schon lange gibt. Jetzt in Version 2.2 Remote Storage - als experimentell markiert. Darüber hinaus ist bekannt, dass sich die Remote Storage API definitiv ändern wird.


Mit Remote Storage können Sie nur mit Rohdaten arbeiten. Es gibt kein PromQL am Eingang oder Ausgang. Wenn Sie lesen, können Sie nicht die volle Leistung von PromQL nutzen. Es pumpt im Wesentlichen alle Daten aus dem Remotespeicher aus, die der Bedingung entsprechen. Weiter funktioniert PromQL bereits mit ihnen. Dies hat einen ziemlich großen Overhead. Sie müssen viele Daten über das Netzwerk pumpen. Daher wird in Prometheus 2.3, das noch nicht veröffentlicht wurde, aber bereits verzögert wurde, ein Hinweis gelesen. Wir werden etwas später darüber sprechen.


Noch keine API für Metadaten. Sie können keine API erstellen, die alle Zeitreihen vom Remotespeicher zurückgibt. Wenn Sie eine Anfrage an die Prometheus-API stellen, wird diese nicht an den Remotespeicher weitergeleitet. Sie erhalten die Zeitreihe zurück, die sich in der lokalen Datenbank befindet. Wenn Ihre lokale Datenbank deaktiviert ist, erhalten Sie 0 zurück. Dies kann etwas unerwartet sein. Jetzt verwendet diese API ProtoBuf und wird in Zukunft definitiv auf gRPC geändert. Sie haben es noch nicht getan, weil gRPC HTTP2 benötigt. Und in der Praxis hatten sie Probleme mit ihm.



Die Schreib-API sieht folgendermaßen aus. Die Anfrage enthält eine Reihe von Beschriftungen. Der Satz von Beschriftungen identifiziert die Zeitreihen nur eindeutig. __name__ ist eigentlich nur ein Label mit einem speziellen Namen. Und Samples sind eine Reihe von Zeit und Werten - int64 und float64. Bei der Aufnahme ist die Reihenfolge unwichtig. Es wird davon ausgegangen, dass die Datenbank, die dies in sich selbst schreibt, alles richtig macht. Prometheus kann einige Optimierungen vornehmen und diese nicht erneut sortieren. Dementsprechend ist eine Schreibanforderung nur ein paar Zeitreihen.



Die Schreibkonfiguration hat eine ziemlich flexible Konfiguration. Es gibt viele Optionen zum Konfigurieren der Schreibgleichzeitigkeit. Was Prometheus Shards nennt, sind im Wesentlichen wettbewerbsfähige Anfragen. Sie können die maximale Anzahl von Samples in einer Anforderung, die maximale Anzahl paralleler Anforderungen, das Zeitlimit, die Wiederholung und das Backoff begrenzen. Für viele Datenbanken jeweils 100 Stichproben - dies kann sehr klein sein. Wenn Sie ClickHouse wie wir verwenden, muss der Wert natürlich stark erhöht werden. Andernfalls ist es sehr ineffizient.



Die Remote-Lese-API sieht folgendermaßen aus. Es ist nur ein Zeitraum von Anfang bis Ende und ein Match-Set.



Match ist im Wesentlichen eine Sammlung von Namens- und Wertepaaren - eine reguläre Bezeichnung und eine Bedingungsart. Im Vergleich dazu gibt es Gleichheiten, Ungleichungen oder reguläre Ausdrücke. Dies ist die übliche Zeitreihenauswahl, die Sie in PromQL sehen. Hier gibt es keine Funktionen.



Die Antwort sind einige Zeitreihen, die dieser Abfrage entsprechen. Hier sollten die Proben nach Zeit sortiert werden. Auch dies hilft Prometheus, ein wenig CPU zu sparen - keine Notwendigkeit zu sortieren. Es wird jedoch davon ausgegangen, dass Ihre Datenbank dies tun sollte. In den meisten Fällen wird dies der Fall sein, da höchstwahrscheinlich ein Index rechtzeitig erstellt wird.



Prometheus 2.3 führte einen Lesehinweis ein. Was ist das? Dies ist eine Gelegenheit, Prometheus mitzuteilen, welche interne Funktion, die mit der angeforderten Zeitreihe arbeitet, angewendet wird. Dies kann entweder eine Funktion oder ein Aggregationsoperator sein. Es kann Rate sein. Das heißt, es heißt func, aber tatsächlich kann es eine Summe sein, die aus Sicht von PromQL überhaupt keine Funktion ist. Dies ist der Operator. Und ein Schritt. Im vorherigen Beispiel gab es eine Rate von 1 Minute. Hier ist die Rate eine Funktion und eine Minute in Millisekunden als Schritt. Dieser Hinweis kann von der entfernten Datenbank ignoriert werden. Gleichzeitig gibt es in der Antwort keinen Hinweis darauf, ob sie ignoriert wurde oder nicht.



Wie ist die Konfiguration von Lesen?


Erstens gibt es eine solche Konfiguration erforderlich_Matchers. Auf diese Weise können Sie eine Remotespeicheranforderung senden, die dem Ausdruck entspricht. Um aggregierte Daten aus dem Remotespeicher zu lesen, müssen Sie eine Abfrage verwenden, die einen Doppelpunkt enthält.


Es gibt eine Option, mit der Sie aktuelle Daten aus dem Remotespeicher in der TSDB lesen oder nicht lesen können. Normalerweise gibt es in der Standardkonfiguration eine kleine lokale TSDB, die auf die lokale Festplatte geschrieben wird. Sie lagert dort mehrere Stunden oder mehrere Tage. Die Daten, die Sie jetzt verwenden und die für Warnungen verwendet werden, die zum Erstellen des Dashboards verwendet werden, werden nur von der lokalen TSDB gelesen. Es ist schnell, erlaubt uns aber nicht, viele Daten zu speichern.


Alte historische Daten werden aus dem Remotespeicher gelesen. Dies macht deutlich, wie Local Storage und Remote Storage miteinander kommunizieren. Es erfolgt keine Deduplizierung.


Im Wesentlichen was passiert. Daten werden aus dem lokalen Speicher entnommen, Daten werden aus dem Remotespeicher entnommen, wenn read_recent aktiviert ist. Sie verschmelzen einfach miteinander. Es scheint, dass dies kein Problem ist. Wenn davon ausgegangen wird, dass wir die letzten Daten nicht heruntergesampelt haben, sind dies genau die gleichen Daten, sie stimmen vollständig mit den lokalen Daten überein. Wir haben doppelt so viele Stichproben. Wir sollten keine Funktionen beeinflussen. Nicht wirklich. Es gibt eine irate () -Funktion und ein Paar für das Messgerät, das uns die Differenz zwischen den letzten beiden Werten zurückgibt. Sie blickt auf den angegebenen Zeitraum zurück, verwendet aber nur die letzten beiden Werte. Wenn die letzten beiden Werte dieselbe Zeit haben, ist die Differenz Null. Dies ist ein Fehler und es ist fast unmöglich, ihn zu finden. Es wurde erst vor vier Tagen repariert. Dies ist ein Ticket für alle Interessierten.



Interessanterweise wurde Remote Read von Prometheus seit Version 1.8 implementiert. Auf diese Weise können Sie die Daten des alten Prometheus lesen, wenn Sie auf Version 2.x migrieren. Der offizielle Weg empfiehlt, es als Remote Read zu verbinden. Die Daten werden nach Bedarf abgezogen.


Remote Read kann verwendet werden, um das Abfrage-Routing ohne Proxy durchzuführen. Auf einer der vorherigen Folien habe ich gezeigt, dass wir je nach Zeit auf dem einen oder anderen Prometheus routen können. Ebenso können wir dies vermeiden. Schließen Sie einfach den Prometheus an, der unten gelesen wird - und die Daten werden von dort gelesen. Es gibt jedoch eine Änderung der Tatsache, dass natürlich viele Daten gepumpt werden. Vor allem, wenn Sie keinen Abfragehinweis verwenden.



Warum Clickhouse?


  • Für unsere Forschungslösung haben wir uns für ClickHouse entschieden, weil wir uns das schon lange angesehen haben. Wir haben Leute, die ständig mit der Datenbankleistung beschäftigt sind und ständig neue Datenbanken überprüfen. Unser Unternehmen beschäftigt sich mit OpenSource-Datenbanken.


  • Wir mögen die rohe Leistung sehr. Die Leistung in Bezug auf CPU, Zeit usw. ist sehr gut. Die meisten dieser Systeme sprechen von unendlicher Skalierbarkeit, aber wenig von Effizienz für einen einzelnen Server. Viele unserer Kunden speichern Metriken auf zwei Servern.


  • Integrierte Replikation, Sharding.


  • GraphiteMergeTree ist eine spezielle Engine zum Speichern von Graphitdaten. Anfangs interessierte er sich sehr für uns.




Die Engine ist für das Aufrollen (Ausdünnen und Aggregieren / Mitteln) von Graphitdaten vorgesehen.


Graphite speichert die vollständigen Daten in ClickHouse und kann sie empfangen. Außerdem wird angegeben, dass MergeTree bei der Ausdünnung von GraphiteMergeTree ohne Ausdünnung verwendet wird. Das Gefühl ist, dass die Daten immer voll sind, sie werden nicht überschrieben, es ist nur eine Optimierung des Lesens. Aber insgesamt ist es nicht schlecht. Wenn wir lesen, pumpen wir die Daten nicht aus, sie werden automatisch aggregiert, wir erhalten ein paar Daten - das ist gut. Der Nachteil für uns ist, dass alle Daten gespeichert werden.


Ich habe mich Anfang des Monats auf den Bericht vorbereitet. Jemand kommt in einem Telegramm-Chat und fragt: "GraphiteMergeTree-Daten-Downsample"? Ich schreibe schon nein. Die Dokumentation sagt nein. Die andere Person im Chat antwortet jedoch: "Ja, Sie müssen Optimize aufrufen." Lauf, überprüfe - ja die Wahrheit. Die Dokumentation ist im Wesentlichen ein Fehler. Dann habe ich den Quellcode gelesen, überprüft, es stellt sich heraus, dass es Optimize, Optimize Final gibt. Optimize final wurde ursprünglich speziell für GraphiteMergeTree erstellt. Eigentlich macht er Downsampling. Aber es muss mit seinen Händen gerufen werden.


GraphiteMergeTree hat ein anderes Datenmodell. Er hat keine Etiketten. Es funktioniert nicht sehr gut, alles effektiv im Namen der Metriken zu schreiben.


Namensmetriken werden in einer Tabelle gespeichert. Der Name der Metriken hat eine andere Länge. Dies führt dazu, dass bei einer Indexsuche nach dem Namen der Metrik dieser Index nicht so effektiv ist, als ob dieser Index einen festen Längenwert hätte, da die Länge unterschiedlich ist. Weil Sie eine Dateisuche durchführen müssen. Es ist unmöglich, genau anzugeben, wo gelandet werden soll, um eine binäre Suche durchzuführen.



Deshalb machten sie ihr eigenes Schema. Die Folie zeigt, wie wir Zeitreihen in der Datenbank speichern. Das Datum, das ClickHouse benötigt, ist ein Fingerabdruck. Wenn Sie sich die Quellen von Prometheus oder TSDB angesehen haben, wissen Sie, dass der Fingerabdruck im Wesentlichen eine kurze, schnelle Prüfsumme der vollständigen Namenszeitreihen ist. Fingerabdruck ist eine Kombination aller Beschriftungen, Tasten und Werte. Ein Name ist eine reguläre Bezeichnung. Aus Kompatibilitätsgründen verwenden wir denselben Algorithmus. Etwas zu belasten kann bequem sein. Der Fingerabdruck ist derselbe und es kann in der TSDB und in unserem Speicher überprüft werden, ob sie gleich sind. Beschriftungen werden in einem speziellen JSON gespeichert, mit dem ClickHouse mit seinen Standardfunktionen arbeiten kann. Dies ist kompaktes JSON ohne Leerzeichen mit leicht vereinfachter Benennung. Diese Tabelle wird während des Betriebs nicht verwendet. Es wird immer im Speicher unserer eigentlichen Lösung gespeichert, die PromHouse heißt. Es wird nur verwendet, wenn wir den Server starten, um herauszufinden, um welche Zeitreihen es sich handelt. Sie wird abgezogen. Sobald neue Zeitreihen eintreffen, zeichnen wir sie dort auf. Alle mehreren PromHouse-Instanzen können dieselbe Tabelle lesen. ReplacingMergeTree sagt uns, dass diese Zeitreihen - es gibt mehrere verschiedene Instanzen - dieselbe Zeitreihe schreiben. Sie werden sich streiten - und hier wird es kein Problem geben.



Wir speichern Proben sehr effizient in einer separaten Tabelle. Bei einem festen Längenwert ist dieser Fingerabdruck gleich, Zeit und Wert. Wir erhalten 24 Bytes pro Probe. Es hat eine streng feste Länge. Jede Spalte wird separat gespeichert. Eine Fingerabdrucksuche ist effektiv, da wir wissen, dass die Größe festgelegt ist. Es gibt kein Problem wie bei GraphitmergeTree, wenn es sich um eine Zeichenfolge handelt. Wir verwenden benutzerdefinierte Partitionierung. Primärer Fingerabdruckindex und nach Zeit.


24 Bytes ist eine vereinfachte Version. In der Tat komprimiert es gut. In der Tat verbraucht weniger Platz. In unseren letzten Tests beträgt das Kompressionsverhältnis ungefähr 1 zu 42.



Wie können wir manuelles Downsampling durchführen, wenn wir GraphiteMergeTree haben, aber nicht das gleiche, wie wir möchten? In der Tat können wir es von Hand tun. Wie zuvor Sharding, Partitionierung, wenn nichts eingebaut war. Wir machen mit unseren Händen einen neuen Tisch. Wenn eine Zeitprobe zu uns kommt, bestimmen wir, an welche Tabelle wir schreiben.


Wir wählen aus der Abfrage die Zeit aus, aus der die Tabelle gelesen werden soll. Wenn das Lesen an der Grenze erfolgt, lesen wir mehrere Tabellen. Als nächstes halten wir diese Daten. Man könnte dafür die Ansicht verwenden. Erstellen Sie beispielsweise eine Ansicht für mehrere Tabellen, damit diese in einer einzigen Abfrage gelesen werden kann. In ClickHouse gibt es jedoch einen Fehler: Das Prädikat aus der Ansicht wird nicht in die Abfragen eingesetzt. Wenn Sie eine Anfrage in der Ansicht stellen, wird sie daher an alle Tabellen gesendet. Ansicht können wir nicht verwenden.


Wie machen wir Downsampling? Wir erstellen eine temporäre Tabelle. Kopieren Sie die Einfügung mit den richtigen Funktionen in ausgewählte Daten.


Wir machen eine Umbenennung, die unter der globalen Sperre atomar ist. Wir benennen die vorhandene Tabelle in die alte um. Neu zu bestehen. Wir lassen den alten Tisch fallen. Wir haben Daten für 148 Tage bereits Downsampling. Was ist das Problem hier? Einfügen in sieht schön aus. In der Tat müssen wir die richtigen Funktionen anwenden, die richtige Aggregation zu tun. In der Praxis kann dies nicht mit einer großen Anfrage durchgeführt werden. Selbst einige große Anfragen können nicht gestellt werden. Dies muss aus Code erfolgen. Der Code sendet eine große Anzahl kleiner Anforderungen. Wir haben unser Bestes getan, um dies bei großen Anfragen zu tun, aber dies ist nicht sehr effektiv. Das Downsampling von Daten von einem Tag dauert bisher weniger als einen Tag. Je nach Datenmenge kann dies lange dauern.



ClickHouse wird aktualisiert / gelöscht. Löschen hat schon die erste Version bekommen. Wenn das Aktualisieren / Löschen funktioniert, kann unser Downsampling-Datenschema vereinfacht werden.


Zweitens hat ClickHouse die Aufgabe, eine benutzerdefinierte Komprimierung durchzuführen (Delta, Delta zu Delta). Dies ist, was TSDB tut. Dies ist gut für Zeitreihendaten geeignet. Dies ist besonders nützlich, wenn wir die Art der Komprimierung abhängig von den Datentypen auswählen können. Zum Beispiel ein Zähler, der nur wächst - dafür ist eine Delta-Delta-Komprimierung geeignet. Ein Messgerät, das um die Größe schwankt, sodass das Delta gut funktioniert.



Es gibt andere Speicher, die funktionieren. Es gibt InfluxDB, die sofort funktioniert. Es ist üblich, ihn wegen seiner Geschwindigkeit zu schelten, aber was sofort funktioniert und Sie nichts tun müssen, ist gut.


Es gibt OpenTSDB und Graphite, die nur schreibgeschützt sind. Der Standardadapter von Prometheus funktioniert nicht wirklich.


Es gibt eine CrateDB. Es gibt eine TimescaleDB, die PostgreSQL für Zeitreihendatenbanken gibtelt. Sie sagen, es funktioniert gut, aber wir selbst haben es nicht versucht.


Es gibt Cortex, das auch als Frankenstein-Projekt bekannt war. Das beschreibt ihn sehr gut. Dies sind die Leute, die versuchen, eine Entscheidung zu treffen, die auf der Prometheus-Föderation basiert. Sie speichern Daten in S3.


Es gibt Thanos.


  • Er hat eine sehr interessante Architektur. Es gibt Prometheus, der lokale TSDB verwendet. Zwischen ihnen wird ein Cluster erstellt. Neben jedem Prometheus befindet sich ein spezielles Side-Car, das Anfragen über Remote-Lese- und Remote-Schreib-API entgegennimmt. Er leitet diese Anfragen an Prometheus weiter. Prometheus kann seine Remote-Lese- und Remote-Schreib-APIs verwenden. Alle Side-Cars sind miteinander verbunden und zwischen benutzerdefinierten API-Mastern über gRPC ist die Replikation verfügbar, es erfolgt eine erneute Schattierung.
  • Anspruchsvolle Architektur.
  • Es ist ziemlich feucht. Vor ein paar Monaten fiel es von einem halben Tritt ab, als es anfing.


Bei Verwendung des Pull-Modells werden nicht viele Daten geschrieben. Sie müssen ein ganzes Jahr warten, um die jährlichen Daten einzugeben. Wir versuchen sie irgendwie dort zu schreiben.


In Prometheus gibt es kein Remote-Schreiben. Daher funktioniert das Schreiben vieler Daten in die lokale TSDB nicht.


Das zweite Problem. Wenn wir Daten für Stresstests generieren, zittern sie oft gut. Wenn wir beispielsweise vorhandene Daten verwenden und 100 Instanzen generieren, und dies sind dieselben Daten, ist der Komprimierungskoeffizient dort so schön, dass sie in Wirklichkeit nicht auftreten.



Wir haben einen gefälschten Exporteur geschrieben, der aussieht wie ein regulärer Exporteur, den Prometheus zusammenhalten kann:


  • Wenn der Schrott hereinkommt, geht er zu einem vorgelagerten Exporteur. Nimmt Daten daraus.
  • Erzeugt viele Instanzen. Nehmen wir an, 1 ist ein Scrapie und wir erhalten 100 am Ausgang.
  • Ändert die Daten geringfügig: plus minus 10% für Zähler und Messgerät.
  • Die einfachen Werte 0 oder 1 werden nicht geändert. Wenn eine UP-Metrik antwortet, wird angezeigt, ob der Dienst ausgeführt wird: Ja - 1 oder Nein - 0. Und es ist nicht ganz klar, was 098 UP bedeutet.
  • Wir ändern keine ganzen Zahlen in echte und umgekehrt.
  • Es gibt nur Daten im üblichen expfmt-Format.


Ein Promload-Tool, das Daten lädt. Daten lesen:


  • Kann aus Dateien in einem eigenen Format lesen
  • Vielleicht von Remote Read
  • Kann von einem Exporteur lesen

Schreibt in verschiedenen Formaten. Einschließlich in / dev / null, wenn wir genau testen möchten, wie schnell das Lesen funktioniert.


Jetzt ist es ein Lasttest-Tool nicht nur für PromHouse, sondern auch für jede Lösung, die Remote Read oder Prometheus verwendet.



Wir möchten das Lese-Caching hinzufügen, da der Engpass in unseren Tests häufig der gefälschte Exporteur war, der lange Zeit Daten generiert hat. Wir könnten sie zwischenspeichern. Lass sie unrealistisch gut sein. Aber wir werden nicht langsamer. Wir mussten nicht tagelang auf Stresstests warten.


Eine Art Filterung im laufenden Betrieb, eine Art Modifikation im laufenden Betrieb.


Native Unterstützung für TSDB. Um mit der Datenbank auf der Festplatte und nicht über die API zu arbeiten.


Konzentrieren Sie sich auf die Genauigkeit der Migration. Ich habe einmal pmmdemo.percona.com gesetzt: verbunden, alle Metriken erhalten. Wenn Sie dies auf native Weise tun, öffnet Prometheus die TSDB, löst alle Zeitreihen von der Festplatte aus, erhöht die Indizes, crawlt dann in Blockdateien und stellt fest, dass sie tatsächlich vorhanden sind. An diesem Punkt kann sich einfach alles hinlegen.


Der naive Ansatz besteht darin, die gesamte Zeitreihe zu nehmen und von den alten Daten in die neuen zu lesen. In diesem Moment wird er sich hinlegen. Sie müssen das Gegenteil tun. Zuerst müssen Sie die Zeitreihenliste mit einigen Abfragen mit regulären Ausdrücken abrufen. Zum Beispiel eine Zeitreihe, die mit A beginnt. Dann geben Sie mir eine Zeitreihe, die mit B beginnt. Laden Sie sie dann genau nach Metriken, nicht nach Zeit. Das ist unlogisch, aber so funktioniert es. Dies ist eine Nuance, wenn Sie so etwas tun. Wenn Sie sehen, dass OOM Killer dort passiert ist, werden Sie wissen, dass es an Ihnen liegt.



Bei den Ergebnissen der Lasttests werden keine Grafiken angezeigt. Das Testen der Last nimmt viel Zeit in Anspruch und leider ist aufgrund eines Konfigurationsfehlers alles schief gelaufen. Daher haben die Ergebnisse nicht geklappt.


Wir werden auf dem Percona-Blog schreiben, wenn wir Lasttests durchführen.


Ich kann die Ergebnisse ohne Grafiken sagen. Die Aufnahme war linear. Das Lesen sprang und war nicht sehr schnell. Das Lesen der aktuellen Daten ist für uns nicht sehr wichtig. Sie können durch Lesehinweise beschleunigt werden. Sie können read_recent aktivieren, um das Lesen zu verbessern. Und für alte Daten funktioniert dies gut.



Die Menschen wollen eine langfristige Lagerung. Es gibt eine solche Nachfrage. Wir haben auf der PromCon über PromHouse gesprochen. Dort war es ein sehr heißes Thema. Thanos entwickelt sich aktiv weiter.


Es ist jetzt schon möglich. Dafür gibt es eine Lösung. Es gibt eine API. Es gibt einige Integrationen. All dies muss jedoch mit einer Datei abgeschlossen werden. Keine produktionsfertigen Lösungen.



Links, wo man suchen muss. Der erste Link ist das PromHouse-Repository. Das zweite Glied ist, wo er sich wahrscheinlich bewegen wird. Jetzt in einem Repository gibt es mehrere verschiedene Dinge? nicht sehr eng verwandt. Daher müssen Sie sie übertragen.


Unser Blog enthält Informationen zur Leistung und einige Neuigkeiten.


Fragen:


Frage: Haben Sie die Gerüchte über InfluxDB überprüft?


Antwort: Er war nicht sehr gut. Er wurde viel besser. Alle diese Geschichten über die Tatsache, dass InfluxDB langsam ist und auseinander fällt - sie handeln von der alten Version. Die aktuelle Version ist stabil. Würde ich nicht sagen dass es schnell geht. Aber es funktioniert stabil. Vorteile von InfluxDB meiner Meinung nach:


  • Erstens müssen Sie in der Nähe nichts unternehmen, da InfluxDB sofort funktioniert.
  • Zweitens können Sie in ClickHouse wie in anderen datenbankbasierten Lösungen, jedoch nicht in TSDB, eine Ihnen vertraute Abfragesprache verwenden. Die Abfragesprache InfluxDB ähnelt SQL. Sie können Analysen durchführen, was unter PromQL schwierig ist. Wenn Sie TimeScaleDB verwenden, gibt es echtes SQL.

Frage: Funktioniert die GraphiteMergeTree-Engine nur zum Aufzeichnen? Wenn wir Diagramme anzeigen möchten, muss Grafana auf Graphite eingerichtet werden, um die Langzeitspeicherung anzuzeigen?


Antwort: Ja. Die Integration in Prometheus selbst funktioniert nur für die Aufnahme. Er schreibt nur Daten. Von Grafana aus geht es also zu Graphit.


Frage: Und er verliert Etiketten, wenn er schreibt?


Antwort: Es gibt eine Konfiguration, die angibt, was mit ihnen zu tun ist, wie sie einzufügen sind und wo sie einzufügen sind.


Informationen aus dem Publikum: Avito sagte, dass sie ihre Lösung für Aufnahmen von Prometheus bis Graphite schreiben.


Frage: Es wurde der Schluss gezogen, dass bei der Aufzeichnung auf einem Langzeitspeicherserver alles in Ordnung ist.


Es gibt einen Fluss von einer Million Metriken (5 Minuten oder 15 Minuten). raid 6 sata ?


: PMM — . downsampling c 14 1 . , . . . .


: IOPS ?


: .


:


: . , . , , .


: InfluxDB, InfluxDB?


: read_recent. , remote storage. InfluxDB . . read_recent , .


: , Prometheus. InfluxDB. Grafana Prometheus. Prometheus PromQL , InfluxDB?


: .


: Prometheus InfluxDB Grafana?


: . Prometheus 2.2 , .


PS : valyala gecube
, .

Source: https://habr.com/ru/post/de441136/


All Articles