ClickHouse + Graphite: wie man den benötigten Speicherplatz auf Festplatten erheblich reduziert.

ClickHouse + Graphite: wie man den benötigten Speicherplatz auf Festplatten erheblich reduziert.

Ich begrüße Sie, habr.

Wenn jemand das System nutzt graphite-web und auf ein Speicherleistungsproblem gestoßen ist whisper (IO, verbrauchter Speicherplatz), dann sollte die Wahrscheinlichkeit, dass ein Blick auf ClickHouse als Alternative geworfen wurde, gegen eins streben. Diese Aussage impliziert, dass bereits eine Drittanbieterimplementierung als Metrik-Daemon verwendet wird, zum Beispiel carbonwriter oder go-carbon.

ClickHouse löst die beschriebenen Probleme gut. Zum Beispiel passten nach dem Übertragen von 2TiB Daten aus whisper 300GiB hinein. Ich werde nicht näher auf den Vergleich eingehen, es gibt genügend Artikel zu diesem Thema. Außerdem war unser ClickHouse-Speicher bis vor kurzem nicht perfekt.

Probleme mit dem verbrauchten Speicherplatz

Auf den ersten Blick sollte alles gut funktionieren. Wir folgen Dokumentation, erstellen eine Konfiguration für das Metrikspeicher-Schema (siehe retention), und erstellen dann eine Tabelle gemäß den Empfehlungen des gewählten Backends für graphite-web: carbon-clickhouse+graphite-clickhouse oder graphouse, je nachdem, welcher Stack verwendet wird. Und… da wird eine Zeitbombe aktiviert.

Um zu verstehen, welche, muss man wissen, wie Einfügungen und der weitere Lebenszyklus von Daten in Tabellen der *MergeTree ClickHouse (Diagramme stammen aus der Präsentation von Alexey Zatelepin):

  • Ein Block von Daten wird eingefügt. In unserem Fall sind das die eingehenden Metriken. Jeder solcher Block wird vor der Speicherung auf der Festplatte nach dem Schlüssel
    ClickHouse + Graphite: wie man den benötigten Speicherplatz auf Festplatten erheblich reduziert.
  • ORDER BY , der beim Erstellen der Tabelle angegeben wurde, sortiert.Nach der Sortierung wird
  • ein Stück (part) von Daten auf die Festplatte geschrieben. (partDer Server überwacht im Hintergrund, dass es nicht zu viele solcher Stücke gibt, und startet im Hintergrund
    ClickHouse + Graphite: wie man den benötigten Speicherplatz auf Festplatten erheblich reduziert.
  • Zusammenführungen merge (, also Merge-Vorgänge.Der Server hört auf, selbst Merges zu starten, wenn keine Daten mehr aktiv in die
    ClickHouse + Graphite: wie man den benötigten Speicherplatz auf Festplatten erheblich reduziert.
    ClickHouse + Graphite: wie man den benötigten Speicherplatz auf Festplatten erheblich reduziert.
  • Partition partition () fließen, aber man kann den Vorgang manuell mit dem BefehlOPTIMIZE Wenn in der Partition nur noch ein Stück übrig ist, kann man nicht mit einem normalen Befehl zusammenführen, man muss.
  • OPTIMIZE ... FINAL So, die ersten Metriken kommen an. Und sie nehmen einen gewissen Platz in Anspruch. Nachfolgende Ereignisse können je nach vielen Faktoren variieren:

Der Partitionierungsschlüssel kann sowohl sehr klein (Tag) als auch sehr groß (mehrere Monate) sein.

  • Der Partitionierungsschlüssel kann sowohl sehr klein (ein Tag) als auch sehr groß (mehrere Monate) sein.
  • Die Retention-Konfiguration kann mehrere bedeutende Aggregationsschwellen innerhalb der aktiven Partition (wohin Metriken geschrieben werden) enthalten oder auch nicht.
  • Wenn es sehr viele Daten gibt, werden die frühesten Teile, die durch Hintergrund-Merges bereits riesig sein können (bei der Auswahl eines suboptimalen Partitionierungsschlüssels), nicht mit den frischen kleinen Teilen zusammengeführt.

Und letztendlich endet alles gleich. Der Platz, den Metriken in ClickHouse einnehmen, wächst nur, wenn:

  • nicht angewendet wird So, die ersten Metriken kommen an. Und sie nehmen einen gewissen Platz in Anspruch. Nachfolgende Ereignisse können je nach vielen Faktoren variieren: manuell oder
  • keine Daten ständig in alle Partitionen eingefügt werden, um irgendwann einen Hintergrund-Merge zu starten.

Die zweite Methode scheint am einfachsten umsetzbar zu sein und ist daher wahrscheinlich falsch und wurde zuerst ausprobiert.
Ich habe ein ausreichend einfaches Skript in Python geschrieben, das gefälschte Metriken für jeden Tag der letzten 4 Jahre gesendet hat und stündlich über Cron ausgeführt wurde.
Da die gesamte Arbeit von ClickHouse DBMS darauf basiert, dass dieses System irgendwann die gesamte Hintergrundarbeit erledigen wird, aber unklar ist, wann, konnte ich nicht auf den Moment warten, an dem die alten riesigen Teile mit den neuen kleinen zu mergen begannen. Es wurde klar, dass ich einen Weg finden musste, um erzwungene Optimierungen zu automatisieren.

ClickHouse + Graphite: wie man den benötigten Speicherplatz auf Festplatten erheblich reduziert.

Informationen in den Systemtabellen von ClickHouse

Lassen Sie uns einen Blick auf die Struktur der Tabelle system.parts. Dies ist umfassende Informationen über jedes Teil aller Tabellen auf dem ClickHouse-Server. Sie enthält unter anderem folgende Spalten:

  • Datenbankname (database);
  • Tabellenname (Tabelle);
  • Name und ID der Partition () fließen, aber man kann den Vorgang manuell mit dem Befehl & partition_id);
  • Wann das Stück erstellt wurde (modification_time);
  • Minimales und maximales Datum im Stück (Partitionierung erfolgt nach Tagen) (min_date & max_date);

Es gibt auch eine Tabelle system.graphite_retentions, mit folgenden interessanten Feldern:

  • Datenbankname (Tables.database);
  • Tabellenname (Tables.table);
  • Alter der Metrik, wann die nächste Aggregation angewendet werden soll (age);

Also:

  1. Wir haben eine Tabelle der Teile und eine Tabelle der Aggregationsregeln.
  2. Wir kombinieren ihre Schnittmenge und erhalten alle Tabellen *GraphiteMergeTree.
  3. Wir suchen alle Partitionen, in denen:
    • mehr als ein Stück
    • oder der Zeitpunkt gekommen ist, die nächste Aggregationsregel anzuwenden, und modification_time älter als dieser Zeitpunkt ist.

Implementierung

Diese Abfrage

WÄHLEN
    concat(p.database, '.', p.table) AS tabelle,
    p.partition_id AS partition_id,
    p.partition AS partition,
    -- Die "älteste" Regel, die auf
    -- eine Partition angewendet werden kann, aber nicht in der Zukunft, siehe (*)
    max(g.age) AS alter,
    -- Anzahl der Teile in der Partition
    countDistinct(p.name) AS teile,
    -- Die älteste Metrik in der Partition wird als 00:00:00 des folgenden Tages akzeptiert
    toDateTime(max(p.max_date + 1)) AS max_time,
    -- Wann die Partition optimiert werden sollte
    max_time + alter AS rollup_time,
    -- Wann das älteste Stück in der Partition aktualisiert wurde
    min(p.modification_time) AS updated_at
VON system.parts AS p
INNER JOIN
(
    -- Alle Regeln für alle Tabellen *GraphiteMergeTree
    WÄHLEN
        Tabellen.database AS database,
        Tabellen.table AS tabelle,
        alter
    VON system.graphite_retentions
    ARRAY JOIN Tabellen
    GROUP BY
        database,
        tabelle,
        alter
) AS g ON
    (p.table = g.tabelle)
    UND (p.database = g.database)
WO
    -- Nur aktive Teile
    p.active
    -- (*) Und nur Zeilen, wo die Aggregationsregeln bereits angewendet werden sollten
    UND ((toDateTime(p.max_date + 1) + g.age) < now())
GROUP BY
    tabelle,
    partition
HAVING
    -- Nur Partitionen, die jünger sind als der Optimierungszeitpunkt
    (updated_at  1)
ORDER BY
    tabelle ASC,
    partition ASC,
    alter ASC

gibt jede der Partitionen der Tabellen *GraphiteMergeTree zurück, deren Zusammenführung zu einer Freigabe von Speicherplatz führen sollte. Es bleibt nur noch, sie alle mit einer Anfrage zu durchlaufen. So, die ersten Metriken kommen an. Und sie nehmen einen gewissen Platz in Anspruch. Nachfolgende Ereignisse können je nach vielen Faktoren variieren:In der endgültigen Implementierung wurde auch berücksichtigt, dass Partitionen mit aktiven Aufzeichnungen nicht berührt werden müssen.

Genau das macht das Projekt graphite-ch-optimizer. Ehemalige Kollegen von Yandex.Market haben es im Produkt getestet, das Ergebnis kann weiter unten gesehen werden.

ClickHouse + Graphite: wie man den benötigten Speicherplatz auf Festplatten erheblich reduziert.

Wenn das Programm auf einem Server mit ClickHouse gestartet wird, läuft es einfach im Dämonenmodus. Einmal pro Stunde wird eine Anfrage ausgeführt, um zu überprüfen, ob neue Partitionen älter als drei Tage aufgetaucht sind, die optimiert werden können.

In naher Zukunft – die Bereitstellung von mindestens deb-Paketen, und möglichst auch rpm.

Zum Abschluss

In den vergangenen neun Monaten habe ich in meiner Firma InnoGames viel Zeit verbracht, indem ich an der Schnittstelle von ClickHouse und graphite-web gearbeitet habe. Das war eine gute Erfahrung, deren Ergebnis der bevorstehende Übergang von whisper zu ClickHouse als Metrik-Speicher ist. Ich hoffe, dass dieser Artikel eine Art Beginn eines Zyklus ist, wie wir verschiedene Teile dieses Stacks verbessert haben und was in Zukunft getan werden wird.

Für die Entwicklung der Anfrage wurden mehrere Liter Bier und Admin-Tage zusammen mit v0devil, wofür ich ihm meinen Dank aussprechen möchte. Und auch für das Durchsehen dieses Artikels.

Projektseite auf GitHub

Quelle: habr.com

60GB SSD 8Gb DDR4