ClickHouse + Graphite: So reduzieren Sie den Speicherplatzverbrauch deutlich

ClickHouse + Graphite: So reduzieren Sie den Speicherplatzverbrauch deutlich

Grüße, Habr.

Wenn jemand das System ausnutzt Graphitnetz und es ist ein Problem mit der Speicherleistung aufgetreten Flüstern (IO, belegter Speicherplatz), dann sollte die Wahrscheinlichkeit, dass ClickHouse als Ersatz eingesetzt wurde, bei eins liegen. Diese Aussage impliziert, dass beispielsweise bereits eine Drittanbieter-Implementierung als Daemon verwendet wird, der Metriken empfängt Carbonwriter oder Go-Carbon.

ClickHouse löst die beschriebenen Probleme gut. Nachdem beispielsweise 2 TiB Daten von Whisper übertragen wurden, passen sie in 300 GiB. Ich werde nicht näher auf den Vergleich eingehen, es gibt viele Artikel zu diesem Thema. Außerdem war bis vor Kurzem nicht alles perfekt mit unserem ClickHouse-Speicher.

Probleme mit verbrauchtem Platz

Auf den ersten Blick sollte alles gut funktionieren. Nachfolgend Dokumentation, erstellen Sie eine Konfiguration für das Metrikspeicherschema (weiter unten). retention), dann erstellen Sie eine Tabelle gemäß der Empfehlung des ausgewählten Backends für graphite-web: Carbon-Clickhouse+Graphit-Clickhouse oder graphouse, abhängig davon, welcher Stapel verwendet wird. Und... die Zeitbombe explodiert.

Um zu verstehen, welches davon ist, müssen Sie wissen, wie Einfügungen funktionieren und wie Daten in Tabellen von Engines der *-Familie weiterlebenMergeTree ClickHouse (Diagramme entnommen aus Präsentationen Alexey Zatelepin):

  • Eingefügt блок Daten. In unserem Fall waren es die Kennzahlen, die eintrafen.
    ClickHouse + Graphite: So reduzieren Sie den Speicherplatzverbrauch deutlich
  • Jeder dieser Blöcke wird nach dem Schlüssel sortiert, bevor er auf die Festplatte geschrieben wird. ORDER BYbeim Erstellen der Tabelle angegeben.
  • Nach dem Sortieren, кусок (part) Daten werden auf die Festplatte geschrieben.
    ClickHouse + Graphite: So reduzieren Sie den Speicherplatzverbrauch deutlich
  • Der Server überwacht im Hintergrund, sodass nicht viele solcher Teile vorhanden sind, und startet den Hintergrund слияния (merge, im Folgenden zusammenfassen).
    ClickHouse + Graphite: So reduzieren Sie den Speicherplatzverbrauch deutlich
    ClickHouse + Graphite: So reduzieren Sie den Speicherplatzverbrauch deutlich
  • Der Server beendet automatisch die Ausführung von Zusammenführungen, sobald der aktive Datenfluss gestoppt wird партицию (partition), aber Sie können den Vorgang manuell mit dem Befehl starten OPTIMIZE.
  • Wenn nur noch ein Teil in der Partition übrig ist, können Sie die Zusammenführung nicht mit dem üblichen Befehl ausführen; Sie müssen verwenden OPTIMIZE ... FINAL

Es liegen also die ersten Kennzahlen vor. Und sie nehmen etwas Platz ein. Nachfolgende Ereignisse können je nach vielen Faktoren etwas variieren:

  • Der Partitionierungsschlüssel kann entweder sehr klein (ein Tag) oder sehr groß (mehrere Monate) sein.
  • Die Aufbewahrungskonfiguration passt möglicherweise zu mehreren wichtigen Datenaggregationsschwellenwerten innerhalb der aktiven Partition (wo Metriken aufgezeichnet werden) oder auch nicht.
  • Wenn viele Daten vorhanden sind, werden die frühesten Blöcke, die aufgrund der Zusammenführung im Hintergrund bereits riesig sein können (wenn Sie einen nicht optimalen Partitionierungsschlüssel wählen), nicht mit neuen kleinen Blöcken zusammengeführt.

Und es endet immer gleich. Der von Metriken in ClickHouse eingenommene Platz erhöht sich nur, wenn:

  • nicht bewerben OPTIMIZE ... FINAL manuell bzw
  • Fügen Sie nicht fortlaufend Daten in alle Partitionen ein, sodass früher oder später eine Hintergrundzusammenführung beginnt

Die zweite Methode scheint am einfachsten zu implementieren zu sein und ist daher falsch und wurde zuerst ausprobiert.
Ich habe ein ziemlich einfaches Python-Skript geschrieben, das in den letzten 4 Jahren für jeden Tag Dummy-Metriken gesendet und jede Stunde Cron ausgeführt hat.
Da der gesamte Betrieb von ClickHouse DBMS auf der Tatsache basiert, dass dieses System früher oder später die gesamte Hintergrundarbeit erledigen wird, aber es ist nicht bekannt, wann, konnte ich nicht auf den Moment warten, in dem die alten riesigen Teile mit der Verschmelzung beginnen würden neue kleine. Es wurde klar, dass wir nach einer Möglichkeit suchen mussten, erzwungene Optimierungen zu automatisieren.

ClickHouse + Graphite: So reduzieren Sie den Speicherplatzverbrauch deutlich

Informationen in ClickHouse-Systemtabellen

Werfen wir einen Blick auf die Tabellenstruktur Systemteile. Dabei handelt es sich um umfassende Informationen zu jedem Teil aller Tabellen auf dem ClickHouse-Server. Enthält unter anderem folgende Spalten:

  • Datenbankname (database);
  • Tabellenname (table);
  • Partitionsname und ID (partition & partition_id);
  • als das Stück erstellt wurde (modification_time);
  • minimales und maximales Datum in einem Stück (die Aufteilung erfolgt nach Tag) (min_date & max_date);

Es gibt auch einen Tisch system.graphite_retentions, mit folgenden interessanten Bereichen:

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

Also:

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

Implementierung

Diese Anfrage

SELECT
    concat(p.database, '.', p.table) AS table,
    p.partition_id AS partition_id,
    p.partition AS partition,
    -- Самое "старое" правило, которое может быть применено для
    -- партиции, но не в будущем, см (*)
    max(g.age) AS age,
    -- Количество кусков в партиции
    countDistinct(p.name) AS parts,
    -- За самую старшую метрику в партиции принимается 00:00:00 следующего дня
    toDateTime(max(p.max_date + 1)) AS max_time,
    -- Когда партиция должна быть оптимизированна
    max_time + age AS rollup_time,
    -- Когда самый старый кусок в партиции был обновлён
    min(p.modification_time) AS modified_at
FROM system.parts AS p
INNER JOIN
(
    -- Все правила для всех таблиц *GraphiteMergeTree
    SELECT
        Tables.database AS database,
        Tables.table AS table,
        age
    FROM system.graphite_retentions
    ARRAY JOIN Tables
    GROUP BY
        database,
        table,
        age
) AS g ON
    (p.table = g.table)
    AND (p.database = g.database)
WHERE
    -- Только активные куски
    p.active
    -- (*) И только строки, где правила аггрегации уже должны быть применены
    AND ((toDateTime(p.max_date + 1) + g.age) < now())
GROUP BY
    table,
    partition
HAVING
    -- Только партиции, которые младше момента оптимизации
    (modified_at < rollup_time)
    -- Или с несколькими кусками
    OR (parts > 1)
ORDER BY
    table ASC,
    partition ASC,
    age ASC

gibt jede der *GraphiteMergeTree-Tabellenpartitionen zurück, deren Zusammenführung Speicherplatz freigeben soll. Jetzt müssen Sie nur noch alle mit einer Anfrage durchgehen OPTIMIZE ... FINAL. Die endgültige Implementierung berücksichtigt auch die Tatsache, dass bei aktiver Aufzeichnung keine Berührung von Partitionen erforderlich ist.

Genau das leistet das Projekt Graphit-Ch-Optimierer. Ehemalige Kollegen von Yandex.Market haben es in der Produktion ausprobiert, das Ergebnis der Arbeit ist unten zu sehen.

ClickHouse + Graphite: So reduzieren Sie den Speicherplatzverbrauch deutlich

Wenn Sie das Programm auf einem Server mit ClickHouse ausführen, beginnt es einfach im Daemon-Modus zu arbeiten. Einmal pro Stunde wird eine Abfrage ausgeführt, die prüft, ob neue Partitionen aufgetaucht sind, die älter als drei Tage sind und optimiert werden können.

Unsere unmittelbaren Pläne bestehen darin, zumindest Deb-Pakete und wenn möglich auch RPM bereitzustellen.

Statt einer Schlussfolgerung

In den letzten mehr als 9 Monaten war ich in meinem Unternehmen tätig InnoGames Ich habe viel Zeit damit verbracht, an der Schnittstelle zwischen ClickHouse und Graphite-Web herumzubasteln. Es war eine gute Erfahrung, die zu einem schnellen Übergang von Whisper zu ClickHouse als Messwertspeicher führte. Ich hoffe, dieser Artikel ist so etwas wie der Beginn einer Reihe darüber, welche Verbesserungen wir an verschiedenen Teilen dieses Stacks vorgenommen haben und was in Zukunft getan werden wird.

Mehrere Liter Bier und Verwaltungstage wurden für die Ausarbeitung der Anfrage aufgewendet v0devil, wofür ich ihm meinen Dank aussprechen möchte. Und auch für die Durchsicht dieses Artikels.

Projektseite auf Github

Source: habr.com

Kommentar hinzufügen