Die Übersetzung des Artikels wurde speziell für die Studierenden des Kurses erstellt .
— Softwareentwickler, Go-Fan und Liebhaber komplexer Aufgaben. Er ist auch Maintainer von Prometheus und Mitbegründer der Kubernetes SIG Instrumentation. Zuvor war er Production Engineer bei SoundCloud und leitete das Monitoring-Team bei CoreOS. Derzeit arbeitet er bei Google.
— Infrastruktur-Ingenieur bei Improbable. Er interessiert sich für neue Technologien und Probleme verteilter Systeme. Er hat Erfahrung in der Low-Level-Programmierung bei Intel, war Contributor bei Mesos und hat globale SRE-Produktions-Erfahrung bei Improbable. Er arbeitet daran, die Welt der Mikrodienste zu verbessern. Seine drei Leidenschaften: Golang, Open Source und Volleyball.
Wenn Sie sich unser Flaggschiff-Produkt SpatialOS ansehen, können Sie erraten, dass Improbable eine hochdynamische Cloud-Infrastruktur globalen Maßstabs mit Dutzenden von Kubernetes-Clustern benötigt. Wir gehörten zu den Ersten, die ein Monitoring-System einsetzten . Prometheus kann Millionen von Metriken in Echtzeit überwachen und wird mit einer leistungsstarken Abfragesprache geliefert, die es ermöglicht, notwendige Informationen abzurufen.
Die Einfachheit und Zuverlässigkeit von Prometheus ist eines seiner Hauptvorteile. Doch bei einer bestimmten Skalierung sind wir auf einige Nachteile gestoßen. Um diese Probleme zu lösen, haben wir — ein Open-Source-Projekt, das von Improbable erstellt wurde, um bestehende Prometheus-Cluster nahtlos in ein einheitliches Überwachungssystem mit unbegrenzter historischer Datenspeicherung zu transformieren. Thanos ist auf Github verfügbar. .
Unsere Ziele mit Thanos
Bei einer bestimmten Skalierung treten Probleme auf, die über die Möglichkeiten von Vanilla Prometheus hinausgehen. Wie speichert man Petabytes historischer Daten zuverlässig und kostengünstig? Ist dies möglich, ohne die Antwortzeiten zu beeinträchtigen? Kann man auf alle Metriken, die auf verschiedenen Prometheus-Servern liegen, mit einer einzigen API-Anfrage zugreifen? Ist es möglich, replizierte Daten, die mit Prometheus HA gesammelt wurden, irgendwie zu kombinieren?
Um diese Fragen zu beantworten, haben wir Thanos entwickelt. In den folgenden Abschnitten wird beschrieben, wie wir an die Lösung dieser Fragen herangegangen sind, und die Ziele erklärt, die wir verfolgt haben.
Datenanfragen von mehreren Instanzen von Prometheus (globale Abfrage)
Prometheus bietet einen funktionalen Ansatz für das Sharding an. Selbst ein einzelner Prometheus-Server gewährleistet eine ausreichende Skalierbarkeit, um die Nutzer von den Komplikationen des horizontalen Shardings in nahezu allen Anwendungsfällen zu befreien.
Obwohl dies ein hervorragendes Bereitstellungsmodell ist, wird häufig der Zugriff auf Daten von verschiedenen Prometheus-Servern über eine einheitliche API oder UI – global view – benötigt. Natürlich ist es möglich, mehrere Abfragen in einem Grafana-Dashboard anzuzeigen, aber jede Abfrage kann nur auf einen Prometheus-Server ausgeführt werden. Andererseits können Sie mit Thanos Daten von mehreren Prometheus-Servern abfragen und aggregieren, da sie alle über einen einzigen Endpunkt zugänglich sind.
Früher haben wir zur Erzielung einer globalen Ansicht bei Improbable unsere Prometheus-Instanzen in eine mehrstufige . Dies bedeutete, einen einzigen Meta-Prometheus-Server zu erstellen, der einen Teil der Metriken von jedem "Blatt"-Server sammelt.

Dieser Ansatz erwies sich als problematisch. Er führte zu einer komplizierten Konfiguration, zu einer zusätzlichen potenziellen Fehlerquelle und zur Anwendung komplexer Regeln, um der föderierten Endstelle nur die benötigten Daten bereitzustellen. Darüber hinaus ermöglicht diese Art der Föderation keine echte globale Ansicht, da nicht alle Daten über eine einzige API-Anfrage abgerufen werden können.
Hierzu gehört auch die einheitliche Darstellung von Daten, die auf hochverfügbaren (high-availability, HA) Prometheus-Servern gesammelt werden. Das HA-Modell von Prometheus sammelt Daten unabhängig zweimal, was so einfach ist, dass es nicht einfacher sein könnte. Es wäre jedoch viel praktischer, eine kombinierte und deduplizierte Ansicht beider Datenströme zu verwenden.
Natürlich gibt es in hochverfügbaren Prometheus-Servern einen Bedarf. Bei Improbable nehmen wir die Datenüberwachung im Minutentakt sehr ernst, aber das Vorhandensein einer einzigen Prometheus-Instanz pro Cluster stellt einen einzelnen Fehlerpunkt dar. Jede Konfigurationsfehler oder jedes Hardwareversagen könnte potenziell zum Verlust wichtiger Daten führen. Selbst eine einfache Bereitstellung kann zu geringfügigen Ausfällen beim Metrik-Sammeln führen, da ein Neustart deutlich länger als das Scraping-Intervall dauern kann.
Zuverlässige Speicherung historischer Daten
Eine kostengünstige, schnelle und langfristige Speicherung von Metriken ist unser Traum (den die meisten Benutzer von Prometheus teilen). Bei Improbable waren wir gezwungen, die Speicherdauer der Metriken auf neun Tage (für Prometheus 1.8) einzustellen. Das bringt offensichtliche Einschränkungen mit sich, wie weit wir in der Vergangenheit schauen können.
Prometheus 2.0 ist in dieser Hinsicht besser geworden, da die Anzahl der Zeitreihen die Gesamtleistung des Servers nicht mehr beeinflusst (siehe ). Dennoch speichert Prometheus Daten auf der lokalen Festplatte. Obwohl eine hochgradig effiziente Datenkompression den Einsatz von lokalem SSD-Speicher erheblich reduzieren kann, gibt es letztendlich trotzdem eine Grenze für die Menge der gespeicherten historischen Daten.
Außerdem kümmern wir uns bei Improbable um Zuverlässigkeit, Einfachheit und Kosten. Große lokale Festplatten sind schwieriger zu betreiben und zu sichern. Sie sind teurer und erfordern mehr Werkzeuge für die Datensicherung, was zu übermäßiger Komplexität führt.
Herunterstufen
Sobald wir begannen, mit historischen Daten zu arbeiten, erkannten wir, dass es grundlegende Herausforderungen mit der O-Notation gibt, die Abfragen immer langsamer macht, wenn wir mit Daten über Wochen, Monate und Jahre arbeiten.
Eine standardmäßige Lösung für dieses Problem wäre (Downsampling) — die Reduzierung der Abtastrate eines Signals. Durch die Verringerung der Abtastrate können wir "skalieren", um einen größeren Zeitraum abzudecken und die gleiche Anzahl von Abtastungen beizubehalten, was die Reaktionsfähigkeit der Abfragen verbessert.
Das Herunterstufen alter Daten ist eine unerlässliche Anforderung jeder Lösung für die langfristige Speicherung und geht über das herkömmliche Prometheus hinaus.
Zusätzliche Ziele
Eines der ursprünglichen Ziele des Thanos-Projekts war die nahtlose Integration mit bestehenden Prometheus-Installationen. Das zweite Ziel war die einfache Bedienung mit einer minimalen Einstiegshürde. Alle Abhängigkeiten sollten sowohl für kleine als auch große Nutzer leicht erfüllbar sein, was auch eine geringe Grundgebühr impliziert.
Architektur von Thanos
Nachdem wir in dem vorherigen Abschnitt unsere Ziele aufgelistet haben, lassen Sie uns daran arbeiten und sehen, wie Thanos diese Herausforderungen angeht.
Globale Ansicht
Um eine globale Ansicht über bestehende Instanzen von Prometheus zu erhalten, müssen wir einen einheitlichen Einstiegspunkt für Anfragen mit allen Servern verbinden. Genau das macht die Komponente Thanos. . Es wird neben jedem Prometheus-Server bereitgestellt und fungiert als Proxy, der lokale Daten von Prometheus über die gRPC-Schnittstelle des Store API bereitstellt, was die Auswahl von Zeitreihendaten nach Labels und Zeitbereich ermöglicht.
Auf der anderen Seite befindet sich die horizontal skalierbare, zustandslose Komponente Querier, die etwas mehr tut, als nur auf PromQL-Anfragen über die standardmäßige Prometheus HTTP API zu antworten. Die Komponenten Querier, Sidecar und andere Thanos interagieren über .

- Der Querier verbindet sich bei Erhalt einer Anfrage mit dem entsprechenden Server des Store API, also mit unseren Sidecars, und erhält die Zeitreihendaten von den entsprechenden Prometheus-Servern.
- Anschließend kombiniert er die Antworten und führt die PromQL-Anfrage aus. Der Querier kann sowohl nicht überlappende Daten als auch duplizierte Daten von HA-Servern von Prometheus zusammenführen.
Das löst den größten Teil unseres Rätsels — die Zusammenführung von Daten von isolierten Prometheus-Servern in eine einheitliche Ansicht. Tatsächlich kann Thanos nur für diese Funktionalität genutzt werden. Es sind keine Änderungen an den bestehenden Prometheus-Servern erforderlich!
Unbegrenzte Speicherfrist!
Allerdings werden wir früher oder später die Daten speichern wollen, die über die übliche Speicherfrist von Prometheus hinausgehen. Für die Speicherung von historischen Daten haben wir ein Objektspeicher gewählt. Dieser ist in jeder Cloud sowie in lokalen Rechenzentren weit verbreitet und äußerst kostengünstig. Zudem ist praktisch jeder Objektspeicher über die gut bekannte S3 API zugänglich.
Prometheus schreibt Daten aus dem Arbeitsspeicher ungefähr alle zwei Stunden auf die Festplatte. Ein Block der gespeicherten Daten enthält alle Daten für einen festen Zeitraum und ist unveränderlich. Das ist sehr praktisch, da Thanos Sidecar einfach das Verzeichnis der Prometheus-Daten durchsuchen kann und, während neue Blöcke erscheinen, diese in die Buckets des Objektspeichers lädt.

Das Laden in den Objektspeicher direkt nach dem Schreiben auf die Festplatte ermöglicht es auch, die Einfachheit des „Scrapers“ (Prometheus und Thanos Sidecar) zu bewahren. Dies vereinfacht die Wartung, die Kosten und das Design des Systems.
Wie Sie sehen, erfolgt die Datensicherung sehr einfach. Aber wie sieht es mit dem Abruf von Daten aus dem Objektspeicher aus?
Die Thanos Store-Komponente fungiert als Proxy zum Abrufen von Daten aus dem Objektspeicher. Wie Thanos Sidecar ist sie Teil eines Gossip-Clusters und implementiert die Store-API. So können bestehende Querier sie als Sidecar betrachten, als eine weitere Quelle für Zeitreihendaten – es sind keine speziellen Konfigurationen erforderlich.

Die Blöcke der Zeitreihendaten bestehen aus mehreren großen Dateien. Das Herunterladen auf Anfrage wäre ziemlich ineffizient, und die lokale Zwischenspeicherung würde enorme Speicher- und Festplattenspeicher erfordern.
Stattdessen weiß das Store Gateway, wie man mit dem Speicherformat von Prometheus umgeht. Dank eines intelligenten Abfrageplaners und der Zwischenspeicherung nur der benötigten Indexteile der Blöcke ist es möglich, komplexe Abfragen auf ein Minimum an HTTP-Anfragen an die Dateien des Objektspeichers zu reduzieren. Damit können die Anfragen um vier bis sechs Größenordnungen reduziert und eine Antwortzeit erreicht werden, die insgesamt schwer von der Abfrage von Daten auf einem lokalen SSD zu unterscheiden ist.

Wie in der obigen Grafik gezeigt, senkt Thanos Querier die Kosten für eine einzelne Anfrage an Daten im Objektspeicher erheblich, indem es das Speicherformat von Prometheus verwendet und verwandte Daten nahe beieinander anordnet. Mit diesem Ansatz können wir viele einzelne Anfragen in eine minimale Anzahl von Bulk-Operationen zusammenfassen.
Kompaktierung und Heruntersampling
Nachdem ein neuer Block von Zeitreihendaten erfolgreich in den Objektspeicher geladen wurde, betrachten wir ihn als „historische“ Daten, die sofort über das Store Gateway verfügbar sind.
Nach einiger Zeit sammeln sich jedoch Blöcke aus einer Quelle (Prometheus mit Sidecar) an und nutzen nicht mehr das volle Potenzial der Indizierung. Um dieses Problem zu lösen, haben wir eine weitere Komponente namens Compactor eingeführt. Diese wendet einfach den lokalen Kompaktierungsmechanismus von Prometheus auf die historischen Daten im Objektspeicher an und kann als einfaches, regelmäßiges Batch-Job ausgeführt werden.

Dank einer effektiven Komprimierung stellt eine Abfrage an das Repository über einen längeren Zeitraum kein Problem in Bezug auf die Datengröße dar. Allerdings wird die potenzielle Kosten für das Entpacken von einer Milliarde Werten und deren Verarbeitung durch den Query-Handler unweigerlich zu einer signifikanten Erhöhung der Ausführungszeit der Abfrage führen. Auf der anderen Seite, da auf jeden Bildschirmpixel Hunderte von Datenpunkten entfallen, wird es unmöglich, die Daten in voller Auflösung zu visualisieren. Daher ist Downsamping nicht nur möglich, sondern führt auch nicht zu einem spürbaren Verlust an Genauigkeit.

Für das Downsamping von Daten aggregiert der Compactor kontinuierlich Daten mit einer Auflösung von fünf Minuten und einer Stunde. Für jedes unverarbeitete Fragment, das mit der TSDB-XOR-Komprimierung codiert wurde, werden verschiedene Arten von aggregierten Daten gespeichert, wie z.B. min, max oder sum für einen Block. Dies ermöglicht es dem Querier, automatisch das Aggregat auszuwählen, das für die jeweilige PromQL-Abfrage geeignet ist.
Um Daten mit reduzierter Genauigkeit zu verwenden, benötigt der Benutzer keine spezielle Konfiguration. Der Querier wechselt automatisch zwischen verschiedenen Auflösungen und unverarbeiteten Daten, wenn der Benutzer herein- oder herauszoomt. Wenn gewünscht, kann der Benutzer dies direkt über den Parameter "step" in der Abfrage steuern.
Da die Speicherkosten für ein GB gering sind, speichert Thanos standardmäßig die Rohdaten, die Daten mit einer Auflösung von fünf Minuten und einer Stunde. Es besteht keine Notwendigkeit, die Rohdaten zu löschen.
Recording-Regeln
Selbst mit Thanos sind Recording-Regeln ein wesentlicher Bestandteil des Monitoring-Stacks. Sie reduzieren die Komplexität, die Latenz und die Kosten von Abfragen. Außerdem sind sie für Benutzer nützlich, um aggregierte Daten zu Metriken zu erhalten. Thanos basiert auf einem Vanilla-Prometheus-Setup, daher ist es durchaus zulässig, Recording-Regeln und Alerting-Regeln auf einem bestehenden Prometheus-Server zu speichern. In einigen Fällen könnte dies jedoch unzureichend sein:
- Globale Alerts und Regeln (z.B. Benachrichtigung, wenn der Dienst auf mehr als zwei von drei Clustern nicht funktioniert).
- Regel für Daten außerhalb des lokalen Speichers.
- Das Bestreben, alle Regeln und Alerts an einem Ort zu speichern.

Für all diese Fälle enthält Thanos eine separate Komponente, die Ruler genannt wird, die Regel und Alarm über Thanos-Abfragen berechnet. Durch Bereitstellung der gut bekannten StoreAPI kann der Query-Knoten auf frische, berechnete Metriken zugreifen. Später werden diese auch im Objektspeicher gespeichert und sind über das Store Gateway verfügbar.
Die Macht von Thanos
Thanos ist flexibel genug, um an Ihre Anforderungen angepasst zu werden. Dies ist besonders nützlich beim Migrieren von einem einfachen Prometheus. Lassen Sie uns schnell an einem kleinen Beispiel erinnern, was wir über die Komponenten von Thanos gelernt haben. So übertragen Sie Ihr Vanilla-Prometheus in die Welt der "unbegrenzten Metrikspeicherung":

- Fügen Sie Thanos Sidecar zu Ihren Prometheus-Servern hinzu – zum Beispiel als benachbarter Container in einem Kubernetes-Pod.
- Führen Sie mehrere Replikate von Thanos Querier aus, um die Daten anzusehen. In diesem Schritt ist es einfach, Gossip zwischen Scraper und Querier einzurichten. Zur Überprüfung der Interaktion der Komponenten verwenden Sie die Metrik ‘thanos_cluster_members’.
Diese beiden Schritte reichen aus, um eine globale Ansicht und nahtlose Deduplication der Daten von potenziellen HA-Replikaten von Prometheus zu gewährleisten! Schließen Sie einfach Ihre Dashboards an den HTTP-Endpunkt des Queriers an oder verwenden Sie die Thanos UI direkt.
Wenn Sie jedoch eine Sicherung der Metriken und langfristige Speicherung benötigen, müssen noch drei weitere Schritte durchgeführt werden:
- Erstellen Sie einen AWS S3- oder GCS-Bucket. Richten Sie Sidecar so ein, dass es Daten in diese Buckets kopiert. Jetzt können die lokalen Datenspeicherungen minimiert werden.
- Implementieren Sie das Store Gateway und verbinden Sie es mit einem bestehenden Gossip-Cluster. Jetzt können Sie Anfragen an die in den Backups gespeicherten Daten senden!
- Setzen Sie den Compactor ein, um die Effizienz der Abfragen für längere Zeiträume zu steigern, indem Sie Verdichtung und Downsampling verwenden.
Wenn Sie mehr erfahren möchten, schauen Sie sich gerne unsere an und !
In nur fünf Schritten haben wir Prometheus in ein zuverlässiges Überwachungssystem mit globaler Ansicht, unbegrenzter Speicherung und potenzieller hoher Verfügbarkeit von Metriken verwandelt.
Pull-Request: Wir brauchen Sie!
Von Anfang an war es ein Open-Source-Projekt. Die nahtlose Integration mit Prometheus und die Fähigkeit, nur einen Teil von Thanos zu verwenden, machen es zu einer ausgezeichneten Wahl für die Skalierung des Überwachungssystems ohne großen Aufwand.
Wir freuen uns immer über GitHub Pull Requests und Issues. Zögern Sie nicht, uns über GitHub Issues oder Slack zu kontaktieren., wenn Sie Fragen oder Anmerkungen haben oder Ihre Erfahrungen mit uns teilen möchten! Wenn Ihnen gefällt, was wir bei Improbable tun, zögern Sie nicht, uns zu kontaktieren — !
Quelle: habr.com
