Thanos

Bei Puzzle verwenden wir für das Monitoring unserer Infrastruktur seit einiger Zeit Prometheus. In diesem Blogpost möchte ich aufzeigen, wie die Funktionen eines Prometheus Monitoring Stacks durch die Verwendung von Thanos erweitert werden können.

Thanos ist, wie Prometheus auch, Teil der CNCF Landschaft und wurde im Jahr 2018 durch Fabian Reinartz und Bartłomiej Płotka ins Leben gerufen. Ziel war und ist es bis heute, die Skalierung von Prometheus zu vereinfachen. Der Fokus liegt dabei auf der Langzeitspeicherung der Metriken sowie einer globalen Sicht über alle Prometheus Instanzen (global view).

Features von Thanos

Global Query View
Thanos implementiert die Prometheus HTTP v1 API, über welche sich Metriken von mehreren Prometheus Instanzen aggregieren lassen. Wie bei Prometheus gibt es auch bei Thanos ein Web GUI, über welches sich Queries auf die API absetzen und die Resultate grafisch darstellen lassen. Thanos dedupliziert dabei auf Wunsch die Metriken von Prometheus HA Gruppen.

Unlimited Retention
Thanos pushed Prometheus Metriken in einen Object Storage (S3, Google Cloud Storage, Azure Storage Account und weitere) und bietet die Möglichkeit, Abfragen direkt auf diese Buckets abzusetzen. Dadurch können Metriken über einen fast unlimitierten Zeitraum aufbewahrt werden.

Downsampling & Compaction
Die im Object Storage gespeicherten Blöcke werden durch den Compactor in grössere Blöcke zusammengefasst. Dabei findet zusätzlich ein Downsampling der Metriken statt, wodurch Abfragen über längere Zeiträume deutlich beschleunigt werden können.

Prometheus Compatible
Aufgrund der Implementation der Prometheus Query API, kann Thanos mit Prometheus kompatiblen Tools (z.B. die Prometheus Datasource in Grafana) verwendet werden und profitiert von der Global Query View sowie dem Downsampling.

Architektur

Thanos besteht aus mehreren Komponenten, welche alle in einem einzigen Binary zusammengefasst werden. Die folgende Grafik zeigt auf, wie die einzelnen Komponenten von Thanos untereinander sowie zu externen Ressourcen (Prometheus sowie Object Storage) angebunden sind.

  • Thanos Sidecar
    Die Sidecar Komponente (unten links in der Visualisierung) benötigt auf Dateiebene Zugriff auf die Blöcke der Prometheus TSDB (time series database). Sobald Prometheus einen Block persistiert, wird dieser vom Thanos Sidecar in den konfigurierten Object Storage hochgeladen. Über eine gRPC Schnittstelle ist Thanos Sidecar mit dem der Thanos Query / Querier Komponente verbunden.
  • Thanos Query
    Der Querier implementiert die Prometheus HTTP API und stellt ein Web GUI zur Verfügung. Über dieses Interfaces nimmt der Querier PromQL Ausdrücke entgegen und ist dafür zuständig, diese Queries an die zuständigen Sidecars und Store Gateways weiterzuleiten (Fanout). Dieses wiederum fügen die Antworten zusammen und deduplizieren.

  • Store Gateway
    Der Store Gateway ist über gRPC am Querier angebunden und ermöglicht es, auf die im Object Storage gespeicherten Daten zuzugreifen.

  • Thanos Compact
    Der Compactor verbindet sich auf den Object Storage und fasst die zwei Stunden Blöcke, welche durch die Thanos Sidecars oder Thanos Receivers in den Object Storage hochgeladen werden, in grössere Blöcke zusammen. Zudem führt der Compactor ein Downsampling der Metriken durch. Dabei entstehen zusätzlich zu den Rohdaten Metriken in einer Auflösung von 5 Minuten bzw. 1 Stunde. Insgesamt nach dem Downsampling steht somit jede Metrik in den folgenden Auflösungen zur Verfügung:

    • raw – Die Auflösung entspricht dem scrape Interval (Default 1m)
    • 5m – 1 Datenpunkt pro 5 Minuten
    • 1h – 1 Datenpunkt pro Stunde

Bei einem scrape Interval von 15s reduziert sich dadurch die Anzahl der Datenpunkte um den Faktor 20 (Downsampling auf 5 Minuten) resp. 240 (Downsampling auf 1h). Durch die Verwendung dieser Daten können Abfragen über einen längeren Zeitraum massiv beschleunigt werden, da weniger Datenpunkte verarbeitet werden müssen.

  • Thanos Rule aka Ruler
    Über den Ruler können Prometheus Recording und Alerting Rules auf eine oder mehrere Query APIs abgesetzt werden. Dadurch können Rules definiert werden, welche eine globale Sicht über alle an Thanos angebundenen Prometheus Instanzen benötigen oder auf Metriken zurückgreifen, welche aufgrund der Retention von Prometheus nicht mehr in der lokalen TSDB vorhanden sind.

  • Tools
    Unter Tools versteckt sich eine ganze Reihe von kleinen aber nützlichen CLI Tools, welche zu Entwicklungs- und Debuggingzwecken eingesetzt werden können.
    So lässt sich z.B. über thanos tools bucket verify den Zustand eines Object Stores überprüfen und feststellen, ob überlappende Blöcke vorhanden sind.

Prometheus Federation

Über die Prometheus Federation lassen sich ähnliche Resultate erzielen wie durch die Verwendung von Thanos. So ist es beispielsweise ebenfalls möglich, Metriken von mehreren Prometheus Instanzen in einem einzelnen Prometheus zusammenzuführen und entsprechende Alerts auf diesen Metriken einzurichten.
Aus Performance- sowie Skalierungsrgünden ist ein solches Setup jedoch nicht resp. nur in Ausnahmefällen sinnvoll (dazu weiter unten mehr).

Dazu muss in der scrape config des parent Prometheus ein entsprechender scrape job eingerichtet werden:

scrape_configs:
  - job_name: 'federate'
    scrape_interval: 15s

    honor_labels: true
    metrics_path: '/federate'

    params:
      'match[]':
        - '{federation="1"}'

    static_configs:
      - targets:
        - 'child-prometheus-1:9090'
        - 'child-prometheus-2:9090'

Über den Parameter match[] kann definiert werden, welche Time Series von den child Prometheus gescrapt und in der TSDB des parent Prometheus gespeichert werden. In diesem Beispiel werden vom parent Prometheus nur diejenigen Metriken gescrapt, welche ein Label federation mit dem Wert 1 besitzen.

Grundsätzlich sollte die Prometheus Federation nur in Ausnahmefällen verwendet werden. Keinesfalls soll eine parent Prometheus sämtliche Metriken eines child Prometheus scrapen. Eine solche Konfiguration führt mit zunehmender Anzahl von child Prometheus unweigerlich zu Performanceproblemen, da die parent Prometheus TSDB so sämtliche Metriken aller child Prometheus enthält. Stattdessen kann mit Thanos das gleiche Resultat (global query view) erreicht werden, ohne dass es dabei zu Performance oder Skalierungsproblemen kommt.

Thanos @Puzzle

Setup
Bei Puzzle verwenden wir sowohl zur Überwachung unsere OpenShift Plattform (Infrastruktur sowie sich darauf befindliche Applikationen) als auch aller virtuellen Maschinen Prometheus. Dank Thanos können wir die Metriken aller Prometheus Instanzen unter einem einzelnen Endpunkt abrufen. Dies vereinfacht zudem die Verwaltung von Grafana Dashboards, da nur eine einzige Datasource benötigt wird.

Als Object Storage verwenden wir den S3 kompatible Object Storage unseres Cloudanbieters cloudscale.ch, in welchem wir seit Anfang Februar unsere Metriken speichern. Die Datenmenge beläuft sich dabei auf ca. 1GB/Tag, womit wir aktuell bei einer Bucketgrösse von 200GB angelangt sind.
Für das Alerting verwenden wir weiterhin die jeweiligen Prometheus Instanzen und nicht den Thanos Ruler, da wir aktuell keine Verwendung für instanzübergreifende Alerting Rules haben.

Best Practices

  • Alerting Rules möglichst lokal auf den jeweiligen Prometheus auswerten und den Thanos Ruler nur verwenden, wenn dies zwingend erforderlich ist (z.B. wenn die für die Alerting Rule relevanten Metriken über mehrere Prometheis verteilt sind).
  • Prometheus Federation nicht als Mittel gegen Skalierungsprobleme einsetzen, sondern nur für die unter dem Titel Prometheus Federation beschriebenen Zwecke.

Alternativen
Neben Thanos gibt es noch weitere Projekte, welche ähnliche Lösungsansätze verfolgen. Das prominenteste Beispiel dafür ist sicherlich Cortex, das kontroverseste wohl VictoriaMetrics. Genau wie Thanos, ist auch Cortex ein CNCF Sanbox Project, bietet jedoch zusätzlich ein multi-tenancy Feature. Zwischen Thanos und Cortex existieren drei grundlegende Unterschiede:

  1. Sample ingestion
    Cortex verwendet Prometheus in einer remote write Konfiguration, um neue Datenpunkte / Samples zu speichern. Bei Thanos hingegen werden neue Datenpunkte erst nach dem fertigstellen eines Blockes durch den Thanos Sidecar in den Object Storage geladen.

  2. Storage format
    Cortex speichert die Metriken in einem eigenen Format in einer NoSQL Datenbank oder wahlweise auf einem S3 kompatiblen Object Storage ab. Zusätzlich zu den Metriken erstellt Cortex in der NoSQL DB Indizes.
    Thanos verwendet die von Prometheus erstellten Blöcke und behält das Prometheus TSDB Format bei.

    Thanos bietet als Alternative zu der NoSQL Datenbank experimentell ebenfalls die Verwendung von Block Storage an und verwendet dazu die storage engine von Thanos. Die beiden Projekte Cortex und Thanos nähern sich dadurch weiter an und profitieren gegenseitig voneinander. Ein sehr informativer Artikel zu Block Storage in Cortex ist kürzlich auf dem Grafana Blog erschienen.

  3. Global view
    Thanos erreicht eine Global View, indem eingehende PromQL queries an alle in Frage kommenden Prometheus oder Store Gateways weitergeleitet (Fanout), die Resultate zusammengeführt und dedupliziert werden (Query time deduplication).

Bei Cortex sind alle Daten in einer zentralen Datenbank gespeichert. Die Deduplication findet während der Data Ingestion statt (Ingestion time Deduplication).

Die Unterschiede und ganz besonders auch die Gemeinsamkeiten dieser beiden Projekte werden in zwei sehr sehenswerten Vorträgen im Detail erklärt:

PromCon 2019:
PromCon 2020 (followup):

Wir haben uns bei Puzzle für die Verwendung von Thanos entschieden, weil wir nicht auf das multi-tenancy Feature angewiesen sind und uns der modulare Ansatz von Thanos sehr zweckmässig erscheint.

VictoriaMetrics

Der Vollständigkeit halber erwähne ich an dieser Stelle noch das Projekt VictoriaMetrics. Wie bereits erwähnt, wird dieses Projekt von der Community eher kontrovers aufgenommen. Die Gründe dafür sind fehlerhafte PromQL Implementationen sowie Ungenauigkeit in den gespeicherten Metriken. Die Details zu diesen Problemen finden sich z.B. im Blog von Robust Perception oder auch im kürzlich publizierten PromQL Compliance Test von PromLabs.

Ausblick

Da Thanos und Cortex beide sehr ähnliche Probleme adressieren, ist es sehr wahrscheinlich, dass die beiden Projekte in Zukunft noch näher zusammenrücken werden. Die Verwendung von Block Storage in Cortex ist ein sehr konkreter Schritt in diese Richtung. Auch für Thanos gibt es konkrete Pläne zur Integration von Cortex Bestandteilen. So existiert z.B. ein offener Vorschlag zur Integration des Cortex Query Frontend in Thanos. Man darf also gespannt sein, wie sich die Zusammenarbeit dieser Projekte künftig weiterentwicklen wird.

 

URLS:

Kommentare sind geschlossen.