Ich lade ein, den Bericht von Roman Khavronenko "ExtendedPromQL" zu lesen.


Kurz zu mir. Mein Name ist Roman. Ich arbeite bei CloudFlare und wohne in London. Aber ich bin auch der Maintainer von VictoriaMetrics.
Und ich bin der Autor fĂŒr Grafana und â das ist ein kleiner Proxy fĂŒr ClickHouse.

Wir beginnen mit dem ersten Teil, der âĂbersetzungsproblemeâ heiĂt, in dem ich darĂŒber sprechen werde, dass jede Sprache oder sogar einfach nur die Sprache der Kommunikation sehr wichtig ist. Denn das ist der Weg, wie Sie Ihre Gedanken einem anderen Menschen oder System mitteilen, wie Sie eine Anfrage formulieren. Die Leute im Internet streiten darĂŒber, welche Sprache besser ist â Java oder eine andere. Ich habe fĂŒr mich entschieden, dass man je nach Aufgabe wĂ€hlen muss, denn das ist alles spezifisch.

Fangen wir von vorne an. Was ist PromQL? PromQL ist die Prometheus Query Language. So formulieren wir Anfragen in Prometheus, um Zeitreihendaten zu erhalten.

Was sind Zeitreihendaten? Um es wörtlich zu nehmen, sind das drei Parameter.
Das sind:
- Worauf wir schauen.
- Wann wir darauf schauen.
- Und welchen Wert es anzeigt.

Wenn wir uns dieses Diagramm ansehen (dieses Diagramm stammt von meinem Telefon und zeigt die Statistik meiner Schritte), können wir diese Fragen schnell beantworten.
Wir schauen auf die Schritte. Wir sehen den Wert und sehen die Zeit, wann wir darauf schauen. Das bedeutet, dass wir anhand dieses Diagramms leicht sagen können, dass ich am Sonntag etwa 15.000 Schritte gemacht habe. Das sind Zeitreihendaten.

Nun lasst uns versuchen, sie in ein anderes Datenmodell in Form einer Tabelle zu âzerlegenâ (zu transformieren). Hier haben wir auch das, worauf wir schauen. Ich habe einige zusĂ€tzliche Daten hinzugefĂŒgt, die wir als Metadaten bezeichnen werden, d.h. es sind nicht ich, sondern zwei Personen, sagen wir, Jay und Silent Bob, die das gemacht haben. Das ist es, worauf wir schauen; was es anzeigt und wann es diesen Wert anzeigt.

Nun versuchen wir, all diese Daten in einer Datenbank zu speichern. Als Beispiel habe ich die ClickHouse-Syntax gewĂ€hlt. Hier erstellen wir eine Tabelle, die âStepsâ genannt wird, also das, worauf wir schauen. Es gibt die Zeit, wann wir darauf schauen; was es anzeigt und einige Metadaten, in denen wir speichern, wer das ist: Jay und Silent Bob.

Und um all dies zu visualisieren, werden wir Grafana verwenden, weil es erstens schön aussieht.

Wir werden auch dieses Plugin verwenden. DafĂŒr gibt es zwei GrĂŒnde. Erstens, weil ich es geschrieben habe. Und ich weiĂ genau, wie schwierig es ist, Zeitreihendaten aus ClickHouse zu extrahieren, um sie in Grafana anzuzeigen.

Wir werden im Graph Panel anzeigen. Das ist das beliebteste Panel in Grafana, das die AbhÀngigkeit eines Wertes von der Zeit zeigt, weshalb wir nur zwei Parameter benötigen.

Lass uns die einfachste Abfrage schreiben â wie wir die Statistik der Schritte in Grafana anzeigen, indem wir diese Daten in ClickHouse speichern, in der Tabelle, die wir erstellt haben. Und wir schreiben so eine einfache Abfrage. Wir wĂ€hlen aus den Schritten. Wir wĂ€hlen den Wert und die Zeit dieser Werte, d. h. die gleichen drei Parameter, ĂŒber die wir gesprochen haben.

Und als Ergebnis erhalten wir so ein Diagramm. Wer weiĂ, warum es so seltsam ist?

Richtig, wir mĂŒssen nach der Zeit sortieren.

Und schlieĂlich erhalten wir ein besseres, aber immer noch seltsames Diagramm. Wer weiĂ, warum? Richtig, es gibt zwei Teilnehmer, und wir geben in Grafana zwei Zeitreihen zurĂŒck, denn wenn wir uns das Datenmodell noch einmal ansehen, dann ist jede Zeitreihe eine einzigartige Kombination aus Namen und allen SchlĂŒssel-Wert-Paaren von Labels.

Deshalb mĂŒssen wir eine bestimmte Person auswĂ€hlen. Wir wĂ€hlen Jay.

Und zeichnen noch einmal. Jetzt Àhnelt das Diagramm der Wahrheit. Jetzt ist es ein normales Diagramm, und alles funktioniert gut.

Und wahrscheinlich wisst ihr, wie man ungefÀhr dasselbe bei Prometheus mit PromQL macht. UngefÀhr so. Ein bisschen einfacher. Und wir werden all das aufteilen. Wir haben Steps genommen. Und filtern nach Jay. Wir geben hier nicht an, dass wir den Wert erhalten wollen, und wir wÀhlen keine Zeit aus.

Jetzt versuchen wir, die Geschwindigkeit von Jay oder Silent Bob zu berechnen. In ClickHouse mĂŒssen wir eine runningDifference durchfĂŒhren, d. h. den Unterschied zwischen den Punktpaaren berechnen und sie durch die Zeit teilen, um die exakte Geschwindigkeit zu erhalten. Die Abfrage wĂŒrde ungefĂ€hr so aussehen.

Und sie zeigt ungefÀhr solche Werte an, d. h. Silent Bob oder Jay macht etwa 1,8 Schritte pro Sekunde.

Und in Prometheus wisst ihr auch, wie man das macht. Viel einfacher, als es vorher war.
Und um das auch weiterhin so einfach in Grafana zu machen, habe ich eine solche Wrapper hinzugefĂŒgt, die sehr Ă€hnlich wie PromQL aussieht. Sie wird Rate Macros genannt oder wie auch immer Sie es nennen möchten. In Grafana schreiben Sie einfach ârateâ, aber irgendwo tief im Hintergrund wird es zu einer solchen groĂen Abfrage transformiert. Und Sie mĂŒssen nicht einmal darauf schauen, sie ist irgendwo da, aber Sie sparen eine Menge Zeit, denn solche riesigen SQL-Abfragen zu schreiben, ist immer aufwendig. Man kann leicht einen Fehler machen und danach lange nicht verstehen, was passiert.

Und das ist eine Abfrage, die nicht einmal auf eine Folie gepasst hat, und ich musste sie sogar in zwei Spalten aufteilen. Dies ist auch eine Abfrage in ClickHouse, die dasselbe Rate macht, aber auf beide Zeitreihen: sowohl auf Silent Bob als auch auf Jay, damit wir auf unserem Dashboard zwei Zeitreihen haben. Und das ist schon sehr kompliziert, meiner Meinung nach.

Und in Prometheus wird das sum (rate) sein. FĂŒr ClickHouse habe ich ein separates Makro erstellt, das RateColumns heiĂt und wie eine Abfrage in Prometheus aussieht.

Wir haben uns das angeschaut, und PromQL sieht zwar groĂartig aus, hat aber natĂŒrlich seine EinschrĂ€nkungen.
Das sind:
- Begrenzte SELECT.
- Grenzwert-JOIN.
- Keine UnterstĂŒtzung fĂŒr HAVING.
Und wenn Sie lange damit gearbeitet haben, wissen Sie, dass es manchmal sehr schwierig ist, etwas in PromQL zu machen, wÀhrend man in SQL fast alles tun kann, denn all diese Optionen, die wir jetzt besprochen haben, hÀtten in SQL umgesetzt werden können. Aber wÀre es bequem, das zu benutzen? Und das bringt mich auf den Gedanken, dass nicht immer die mÀchtigste Sprache die bequemste sein kann.

Deshalb muss man manchmal die Sprache passend zur Aufgabe wÀhlen. Es ist wie der Kampf zwischen Batman und Superman. Offensichtlich ist Superman stÀrker, aber Batman konnte ihn besiegen, weil er praktischer war und genau wusste, was er tat.

Und der nĂ€chste Teil â das Erweitern von PromQL.

Noch einmal zu VictoriaMetrics. Was ist VictoriaMetrics? Es ist eine Zeitreihen-Datenbank, sie ist Open Source, wir vertreiben sie in Einzel- und Cluster-Versionen. Laut unseren Benchmarks ist sie die schnellste auf dem Markt und bei der Kompression ebenso, d.h. echte Menschen berichten von einer Kompression von etwa 0,4 Byte pro Punkt, wÀhrend es bei Prometheus 1,2-1,4 ist.
Wir unterstĂŒtzen nicht nur Prometheus. Wir unterstĂŒtzen InfluxDB, Graphite, OpenTSDB.
In uns kann man "schreiben", d.h. man kann alte Daten migrieren.
Und auĂerdem arbeiten wir ideal mit Prometheus und Grafana, d.h. wir unterstĂŒtzen die PromQL-Engine. Und in Grafana können Sie einfach den Prometheus-Endpunkt gegen VictoriaMetrics austauschen und alle Ihre Dashboards funktionieren wie gewohnt.
Aber Sie können auch zusÀtzliche Funktionen nutzen, die VictoriaMetrics bietet.
Wir werden schnell die Funktionen durchgehen, die wir hinzugefĂŒgt haben.

Omit interval param â Sie können den Intervallparameter in Grafana weglassen. Wenn Sie keine seltsamen Grafiken beim Zoom-in/Zoom-out im Panel erhalten möchten, wird empfohlen, die Variable $__intervalzu verwenden. Dies ist eine interne Variable von Grafana und sie wĂ€hlt selbst den Datenbereich aus. Und VictoriaMetrics kann selbst erkennen, wie dieser Bereich aussehen sollte. Sie mĂŒssen keine Ihrer Abfragen aktualisieren. Es wird viel einfacher sein.

Die zweite Funktion ist das Intervallreferencing. Sie können dieses Intervall in Ihren AusdrĂŒcken verwenden. Sie können damit multiplizieren, dividieren, ĂŒbergeben, darauf Bezug nehmen.

Als nĂ€chstes die Familie der Rollup-Funktionen. Rollup-Funktionen transformieren jede Ihrer Zeitreihen in drei separate Zeitreihen. Das sind min, max und avg. Ich finde, das ist sehr praktisch, da es manchmal bestimmte AusreiĂer (Anomalien) und Ungenauigkeiten anzeigen kann.

Und wenn Sie einfach irate oder rate durchfĂŒhren, können Sie wahrscheinlich FĂ€lle ĂŒbersehen, in denen sich die Zeitreihe nicht so verhĂ€lt, wie Sie es vorausgesetzt haben. Mit dieser Funktion ist es viel einfacher zu sehen, dass max beispielsweise sehr stark von avg abweicht.

Dann die default-Variable. Default â das bedeutet, welchen Wert wir in Grafana anzeigen mĂŒssen, wenn wir momentan keine Zeitreihe haben. Wann passiert das? Angenommen, Sie exportieren eine Metrik zu Fehlern. Und Ihre Anwendung ist so groĂartig, dass Sie bei Start keine Fehler und sogar in den nĂ€chsten drei Stunden oder sogar einem Tag keine Fehler haben. Und Sie haben Dashboards, die das VerhĂ€ltnis von Success zu Error anzeigen. Sie zeigen Ihnen nichts an, weil Sie keine Fehler-Metrik haben. Aber im Default können Sie anything angeben.

Keep_last_Value â speichert den letzten Wert der Metrik, falls sie verloren geht. Wenn Prometheus nach dem nĂ€chsten Scrape sie innerhalb von 5 Minuten nicht gefunden hat, werden wir hier ihren letzten Wert speichern und Ihre Grafiken werden nicht wieder kaputtgehen.

Scrape_interval â zeigt, wie hĂ€ufig Prometheus Daten fĂŒr Ihre Metrik sammelt, mit welcher Frequenz. Hier können Sie zum Beispiel eine Unterbrechung sehen.

Label replace â eine beliebte Funktion. Aber wir finden, dass sie etwas kompliziert ist, da sie mehrere Argumente benötigt. Und Sie mĂŒssen sich nicht nur an 5 Argumente erinnern, sondern auch an deren Reihenfolge.

Warum also nicht einfacher machen? D.h. in kleine Funktionen mit verstÀndlichem Syntax aufteilen.

Und jetzt das Interessanteste. Warum halten wir das fĂŒr erweitertes PromQL? Weil wir Common Table Expressions unterstĂŒtzen. Sie können den QR-Code scannen (), um sich Beispiele anzusehen, einschlieĂlich eines Playgrounds, in dem Sie Abfragen direkt in VictoriaMetrics ausfĂŒhren können, ohne sie installieren zu mĂŒssen, einfach im Browser.

Was ist das also? Diese Abfrage oben ist eine ziemlich beliebte Abfrage. Ich denke, in jedem Dashboard in vielen Unternehmen verwenden Sie denselben Filter fĂŒr alles. Normalerweise ist es so. Aber wenn Sie einen neuen Filter hinzufĂŒgen mĂŒssen, mĂŒssen Sie jedes Panel aktualisieren oder das Dashboard herunterladen, in JSON öffnen und eine Suchen-Ersetzen-Aktion durchfĂŒhren, was ebenfalls Zeit in Anspruch nimmt. Warum also nicht diesen Wert in einer Variablen speichern und ihn wiederverwenden? Das erscheint mir viel einfacher und verstĂ€ndlicher.

Wenn ich beispielsweise die Filter in Grafana in allen Abfragen aktualisieren muss, und das Dashboard kann riesig sein oder es kann sogar mehrere geben. Und wie wĂŒrde ich dieses Problem in Grafana lösen?

Ich löse dieses Problem so: Ich erstelle einen commonFilter und definiere darin diesen Filter, und dann verwende ich ihn in den Abfragen wieder. Aber wenn Sie es jetzt genauso machen, wird es nicht funktionieren, weil Grafana es Ihnen nicht erlaubt, Variablen innerhalb von Variablenabfragen zu verwenden. Und das ist etwas seltsam.

Deshalb habe ich eine solche Variante erstellt, die das erlaubt. Und wenn Sie interessiert sind oder eine solche Funktion möchten, unterstĂŒtzen Sie sie oder geben Sie einen Daumen nach unten, wenn Ihnen die Idee nicht gefĂ€llt.

Weiter zu PromQL erweitert. Hier definieren wir nicht nur eine Variable, sondern gleich eine gesamte Funktion. Und wir nennen sie ru (resource usage). Diese Funktion nimmt freie Ressourcen, eine Ressourcenbegrenzung und einen Filter entgegen. Der Syntax scheint einfach zu sein. Und es ist sehr leicht, diese Funktion zu verwenden und den Prozentsatz des freien Speichers zu berechnen. D.h. wie viel Speicher wir haben, welches Limit besteht und wie wir filtern. Das wĂ€re viel bequemer, wenn Sie all dies unter Verwendung der gleichen Filter schreiben wĂŒrden, da es sonst zu einer sehr groĂen Abfrage werden wĂŒrde.

Und hier ist ein Beispiel fĂŒr eine solche groĂe Anfrage. Sie stammt vom offiziellen NodeExporter-Dashboard fĂŒr Grafana. Aber ich verstehe nicht ganz, was hier passiert. Das heiĂt, natĂŒrlich verstehe ich es, wenn ich genau hinschaue, aber die Menge an Klammern kann die Motivation, sich damit auseinanderzusetzen, sofort mindern. Und warum nicht einfacher und verstĂ€ndlicher machen?

Zum Beispiel so, indem wir wichtige Dinge oder Teile in Variablen hervorheben. Und dann unsere grundlegenden Berechnungen durchfĂŒhren. Das sieht schon eher nach Programmierung aus, das ist es, was ich in Zukunft in Grafana sehen möchte.

Hier ist ein zweites Beispiel, wie wir es noch einfacher machen könnten, wenn wir diese Funktion ru bereits hĂ€tten, und die gibt es direkt in VictoriaMetrics. Und dann ĂŒbergibst du einfach den zwischengespeicherten Wert, den du in CTE deklariert hast.

Ich habe bereits darĂŒber gesprochen, wie wichtig es ist, die richtige Programmiersprache zu verwenden. Und wahrscheinlich gibt es in jeder Firma in Grafana eigene Vorgehensweisen. Und vielleicht gibst du auch deinen Entwicklern Zugang zu Grafana, und die Entwickler machen ihre eigenen Dinge. Und sie tun das alle auf unterschiedliche Weise. Ich hĂ€tte es gerne, wenn das einheitlicher wĂ€re, also auf einen gemeinsamen Standard reduziert wĂŒrde.
Angenommen, du hast nicht nur Systemingenieure, vielleicht hast du sogar Experten, DevOps oder SRE. Vielleicht hast du Experten, die wissen, was Monitoring ist, die wissen, was Grafana ist, das heiĂt, sie arbeiten seit Jahren damit und wissen genau, wie man es richtig macht. Und sie haben das schon 100 Mal geschrieben und jedem erklĂ€rt, aber irgendwie hört niemand zu.
Was wĂ€re, wenn sie ihr Wissen direkt in Grafana einbringen könnten, damit andere Benutzer die Funktionen wiederverwenden können? Und wenn sie den Prozentsatz des freien Speichers berechnen mĂŒssten, wĂŒrden sie einfach die Funktion anwenden. Was wĂ€re, wenn die Schöpfer der Exporteure zusammen mit ihrem Produkt auch eine Sammlung von Funktionen bereitstellen wĂŒrden, um mit ihren Metriken zu arbeiten, weil sie genau wissen, was das fĂŒr Metriken sind und wie man sie richtig berechnet?
Das gibt es tatsĂ€chlich nicht. Das habe ich selbst gemacht. Das ist die UnterstĂŒtzung von Bibliotheken in Grafana. Angenommen, die Leute, die den NodeExporter erstellt haben, haben das gemacht, was ich beschrieben habe. Und sie haben auch eine Sammlung von Funktionen bereitgestellt.

Das heiĂt, es sieht ungefĂ€hr so aus. Sie integrieren diese Bibliothek in Grafana, gehen in die Bearbeitung, und hier ist ganz einfach im JSON geschrieben, wie man mit dieser Metrik arbeitet. Das heiĂt, eine Art von FunktionalitĂ€ten, deren Beschreibung und in was sie sich entfalten.

Ich denke, das könnte nĂŒtzlich sein, denn dann wĂŒrden Sie in Grafana einfach so schreiben. Und Grafana âsagtâ Ihnen, dass es eine solche Funktion aus dieser Bibliothek gibt â lassen Sie sie uns verwenden. Ich denke, das wĂ€re wirklich toll.

Ein bisschen ĂŒber VictoriaMetrics. Wir machen viele interessante Dinge. Lesen Sie unsere Artikel ĂŒber Compression, ĂŒber unsere Wettbewerbe mit anderen Time Series-Datenanwendungen, unsere ErklĂ€rung, wie man mit PromQL arbeitet, weil es viele Neulinge gibt, sowie ĂŒber vertikale Skalierbarkeit und das Aufeinandertreffen mit Thanos.

Fragen:
Ich beginne meine Frage mit einer einfachen Lebensgeschichte. Als ich Grafana zum ersten Mal verwendete, schrieb ich eine sehr ĂŒberzeugende Abfrage, die 5 Zeilen lang war. Am Ende entstand ein sehr ĂŒberzeugendes Diagramm. Dieses Diagramm stand kurz davor, in die Produktion zu gehen. Aber bei genauerer Betrachtung stellte sich heraus, dass dieses Diagramm absoluten Unsinn zeigt, der mit der RealitĂ€t nichts zu tun hat, obwohl die Zahlen in den Bereich fallen, den wir erwartet haben. Und meine Frage: Wir haben Bibliotheken, wir haben Funktionen, aber wie schreiben wir Tests fĂŒr Grafana? Sie haben eine komplexe Abfrage geschrieben, von der eine GeschĂ€ftsentscheidung abhĂ€ngt â ob man einen echten Servercontainer bestellt oder nicht. Und wie wissen wir, ob diese Funktion, die das Diagramm zeichnet, der Wahrheit nahekommt? Vielen Dank.
Danke fĂŒr die Frage. Es gibt zwei Teile. Erstens habe ich den Eindruck, basierend auf meiner Erfahrung, dass die meisten Benutzer, wenn sie sich ihre Diagramme ansehen, nicht verstehen, was sie ihnen zeigen. Irgendwie sind die Leute sehr gut darin, Ausreden fĂŒr jede Anomalie zu finden, die in den Diagrammen auftaucht, selbst wenn es einen Fehler innerhalb der Funktion gibt. Und der zweite Teil â ich denke, dass die Nutzung solcher Funktionen viel besser zur Lösung Ihres Problems passen wĂŒrde, anstatt dass jeder Ihrer Entwickler seine eigene KapazitĂ€tsplanung macht und mit einer gewissen Wahrscheinlichkeit Fehler macht.
Wie ĂŒberprĂŒft man das?
Wie ĂŒberprĂŒft man das? Wahrscheinlich gar nicht.
In Form eines Tests in Grafana.
Was hat Grafana damit zu tun? Grafana ĂŒbertrĂ€gt diese Abfrage direkt an die DataSource.
Indem man ein bisschen bei den Parametern nachjustiert.
Nein, in Grafana wird nichts hinzugefĂŒgt. Es können GET-Parameter vorhanden sein, wie zum Beispiel step. Dieser wird zwar nicht explizit angegeben, kann aber ĂŒberschrieben werden oder auch nicht â er wird automatisch hinzugefĂŒgt. Hier schreiben Sie keine Tests. Ich denke, man sollte Grafana hier nicht als Quelle der Wahrheit betrachten.
Danke fĂŒr den Vortrag! Danke fĂŒr die Kompression! Sie hatten das Mapping der Variablen im Diagramm erwĂ€hnt, dass man in Grafana keine Variable in einer Variablen verwenden kann. Verstehen Sie, worauf ich hinaus will?
Ja.
Das war ursprĂŒnglich ein groĂes Problem, als ich in Grafana einen Alert erstellen wollte. Man muss den Alert fĂŒr jeden Host einzeln erstellen. Funktioniert das, was Sie gemacht haben, auch fĂŒr Alerts in Grafana?
Wenn Grafana nicht anders auf Variablen zugreift, dann â ja, wird es funktionieren. Aber mein Rat ist, das Alerting in Grafana ganz zu vermeiden; es ist besser, alertmanager zu verwenden.
Ja, ich benutze ihn, aber es schien in Grafana einfacher einzurichten zu sein, trotzdem danke fĂŒr den Rat!
Quelle: habr.com
