Hallo zusammen! In meinem Ich habe über die Organisation eines modularen Monitoring-Systems für mikroservicebasierte Architekturen geschrieben. Nichts bleibt stehen, unser Projekt wächst ständig, und die Anzahl der gespeicherten Metriken ebenfalls. Wie wir den Übergang von Graphite+Whisper zu Graphite+ClickHouse unter hoher Belastung organisiert haben, sowie unsere Erwartungen und die Ergebnisse der Migration, erfahren Sie im Folgenden.

Bevor ich erkläre, wie wir den Wechsel von der Speicherung der Metriken in Graphite+Whisper zu Graphite+ClickHouse durchgeführt haben, möchte ich die Gründe für diese Entscheidung und die Nachteile von Whisper darlegen, mit denen wir über längere Zeit gelebt haben.
Probleme mit Graphite+Whisper
1. Hohe Belastung des Speichersystems
Zum Zeitpunkt unseres Wechsels erhielten wir etwa 1,5 Millionen Metriken pro Minute. Bei diesem Datenvolumen lag die Festplattenauslastung der Server bei etwa 30 %. Insgesamt war das akzeptabel – alles lief stabil, es wurde schnell geschrieben und schnell gelesen… Bis zu dem Moment, als eines der Entwicklungsteams ein neues Feature herausbrachte und uns 10 Millionen Metriken pro Minute sendete. Da geriet das Speichersystem unter Druck, und wir sahen eine 100%ige Auslastung. Das Problem konnte schnell gelöst werden, aber der Nachgeschmack blieb.
2. Fehlende Replikation und Konsistenz
Wie alle, die Graphite+Whisper nutzen oder genutzt haben, haben auch wir denselben Datenstrom an mehrere Graphite-Server gesendet, um Ausfallsicherheit zu schaffen. Dies stellte in der Regel kein großes Problem dar – bis einer der Server aus irgendeinem Grund ausfiel. Manchmal konnten wir den ausgefallenen Server recht schnell wiederherstellen, und carbon-c-relay konnte die Metriken aus seinem Cache auf ihn übertragen, manchmal jedoch auch nicht. Dann gab es in den Metriken eine Lücke, die wir mit rsync schlossen. Der Prozess war ziemlich langwierig, aber zum Glück kam so etwas sehr selten vor. Außerdem haben wir gelegentlich einen zufälligen Satz von Metriken genommen und diese mit ähnlichen Werten auf den benachbarten Knoten des Clusters verglichen. In etwa 5 % der Fälle wichen einige Werte ab, was uns nicht besonders erfreute.
3. Großer Speicherplatzbedarf
Da wir in Graphite nicht nur Infrastruktur-, sondern auch Geschäftsmetriken (und jetzt sogar Kubernetes-Metriken) erfassen, kommt es häufig vor, dass in einer Metrik nur wenige Werte vorhanden sind, während die .wsp-Datei für den gesamten Retentionszeitraum erstellt wird und den vorab zugewiesenen Speicherplatz belegt, der bei uns etwa ~2 MB betrug. Das Problem wird zusätzlich dadurch verschärft, dass im Laufe der Zeit viele solcher Dateien entstehen, und beim Erstellen von Berichten viel Zeit und Ressourcen für das Lesen leerer Punkte benötigt werden.
Zunächst möchte ich darauf hinweisen, dass die oben beschriebenen Probleme mit verschiedenen Methoden und unterschiedlichen Effizienzgraden angegangen werden können, aber je mehr Daten bei Ihnen eingehen, desto drängender werden diese Probleme.
Unter Berücksichtigung des oben Genannten (einschließlich des vorherigen ), sowie des ständigen Anstiegs der eingehenden Metriken und dem Wunsch, alle Metriken auf einen Speicherintervall von 30 Sekunden (bei Bedarf bis zu 10 Sekunden) zu bringen, haben wir beschlossen, Graphite+ClickHouse als vielversprechende Alternative zu Whisper auszuprobieren.
Graphite+ClickHouse. Erwartungen
Nach dem Besuch mehrerer Meetups mit den Leuten von Yandex und dem Lesen , nachdem wir die Dokumentation durchforstet und passende Komponenten für die Anbindung von ClickHouse an Graphite gefunden hatten, beschlossen wir, aktiv zu werden!
Wir wollten Folgendes erreichen:
- die Auslastung des Datenspeichers von 30 % auf 5 % senken;
- den benötigten Speicherplatz von 1 TB auf 100 GB reduzieren;
- in der Lage sein, 100 Millionen Metriken pro Minute auf den Server zu empfangen;
- Datenreplikation und Ausfallsicherheit direkt 'out of the box' haben;
- nicht ein Jahr an diesem Projekt zu arbeiten und den Übergang in einem akzeptablen Zeitraum zu gestalten;
- ohne Ausfallzeiten umschalten.
Ziemlich ambitioniert, oder?
Graphite+ClickHouse. Komponenten
Für den Datenempfang über das Graphite-Protokoll und das anschließende Speichern in ClickHouse wurde gewählt (Golang).
Als Datenbank für die Speicherung von Zeitreihen wurde die neueste stabile Version 1.1.54253 von ClickHouse ausgewählt. Dabei traten Probleme auf: Es gab viele Fehlermeldungen im Log, und es war nicht ganz klar, was damit zu tun war. In der Diskussion mit (Autor von carbon-clickhouse, graphite-clickhouse und vielen, vielen anderen) wurde eine ältere Version ausgewählt. Die Fehler verschwanden - alles funktionierte einwandfrei.
Für das Lesen von Daten aus ClickHouse wurde gewählt (Golang). Als API-Schnittstelle für Graphite - (golang). Zur Organisation der Replikation zwischen den ClickHouse-Tabellen wurde . Für die Routenführung der Metriken haben wir unser heiß geliebtes (C) .
Graphite+ClickHouse. Struktur der Tabellen
„graphite“ — eine von uns entwickelte Datenbank für Überwachungstabellen.
„graphite.metrics“ — Tabelle mit dem Engine ReplicatedReplacingMergeTree (replizierbar ). In dieser Tabelle werden die Namen der Metriken und deren Pfade gespeichert.
CREATE TABLE graphite.metrics ( Date Date, Level UInt32, Path String, Deleted UInt8, Version UInt32 ) ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/replicator/graphite.metrics', 'r1', Date, (Level, Path), 8192, Version);„graphite.data“ — Tabelle mit dem Engine ReplicatedGraphiteMergeTree (replizierbar ). In dieser Tabelle werden die Werte der Metriken gespeichert.
CREATE TABLE graphite.data ( Path String, Value Float64, Time UInt32, Date Date, Timestamp UInt32 ) ENGINE = ReplicatedGraphiteMergeTree('/clickhouse/tables/replicator/graphite.data', 'r1', Date, (Path, Time), 8192, 'graphite_rollup')„graphite.date_metrics“ — Tabelle, die unter einer Bedingung gefüllt wird, mit dem Engine ReplicatedReplacingMergeTree. In diese Tabelle werden die Namen aller Metriken gespeichert, die im Laufe eines Tages auftraten. Die Gründe für die Erstellung sind im Abschnitt am Ende dieses Artikels beschrieben.
ERSTELLEN SIE EINE MATERIALISIERTE ANSICHT graphite.date_metrics ( Pfad String, Ebene UInt32, Datum Datum) MOTOR = ReplicatedReplacingMergeTree('/clickhouse/tables/replicator/graphite.date_metrics', 'r1', Datum, (Ebene, Pfad, Datum), 8192) WIE SELECT toUInt32(länge(splitByChar('.', Pfad))) AS Ebene, Datum, Pfad VON graphite.data„graphite.data_stat“ — eine bedingte, mit dem ReplicatedAggregatingMergeTree-Motor (replizierte) gefüllte Tabelle. ). In dieser Tabelle wird die Anzahl der eingehenden Metriken mit einer Aufschlüsselung bis zu 4 Ebenen der Verschachtelung aufgezeichnet.
ERSTELLEN SIE EINE MATERIALISIERTE ANSICHT graphite.data_stat ( Datum Datum, Präfix String, Zeitstempel UInt32, Anzahl AggregateFunction(count)) MOTOR = ReplicatedAggregatingMergeTree('/clickhouse/tables/replicator/graphite.data_stat', 'r1', Datum, (Zeitstempel, Präfix), 8192) WIE SELECT toStartOfMonth(now()) AS Datum, replaceRegexpOne(Pfad, '^([^.]+.[^.]+.[^.]+).*$', '1') AS Präfix, toUInt32(toStartOfMinute(toDateTime(Zeitstempel))) AS Zeitstempel, countState() AS Anzahl VON graphite.data GRUPPIEREN NACH Zeitstempel, PräfixGraphite+ClickHouse. Schema der Interaktion der Komponenten

Graphite+ClickHouse. Datenmigration
Wie wir aus den Erwartungen an dieses Projekt wissen, sollte der Übergang zu ClickHouse ohne Ausfallzeiten erfolgen, weshalb wir unsere gesamte Überwachungssystematik so transparent wie möglich auf den neuen Speicher umstellen mussten.
So haben wir das gemacht.
In carbon-c-relay wurde eine Regel hinzugefügt, um einen zusätzlichen Stream von Metriken an carbon-clickhouse eines der Server zu senden, die an der Replikation von ClickHouse-Tabellen beteiligt sind.
Wir haben ein kleines Python-Skript geschrieben, das mithilfe der Bibliothek whisper-dump alle .wsp-Dateien aus unserem Speicher gelesen und diese Daten in dem oben genannten carbon-clickhouse in 24 Streams gesendet hat. Die Anzahl der empfangenen Metrikwerte in carbon-clickhouse erreichte 125 Millionen pro Minute, und ClickHouse hat dabei keine Auslastung gezeigt.
Wir haben eine separate Datenquelle in Grafana erstellt, um die in den bestehenden Dashboards verwendeten Funktionen zu debuggen. Wir haben eine Liste der Funktionen identifiziert, die wir verwendet haben, die jedoch nicht in carbonapi implementiert waren. Diese Funktionen haben wir ergänzt und PRs an die Autoren von carbonapi gesendet (eine spezielle Danksagung an sie).
- Um die Lese-Last zu steuern, haben wir die Endpunkte in den Einstellungen der Lastverteiler von graphite-api (API-Schnittstelle für Graphite+Whisper) auf carbonapi geändert.
Graphite+ClickHouse. Ergebnisse
Die Auslastung des Datenspeichers wurde von 30% auf 1% gesenkt;

- Der Speicherplatzbedarf wurde von 1 TB auf 300 GB reduziert;
- Es ist möglich, 125 Millionen Metriken pro Minute auf den Server zu empfangen (Spitzen während der Migration);
- Wir haben alle Metriken auf einen Speicherung von dreißig Sekunden umgestellt;
- Wir haben Datenreplikation und Ausfallsicherheit erhalten;
- Wir haben ohne Ausfallzeiten umgeschaltet;
- Dafür haben wir insgesamt etwa 7 Wochen benötigt.
Graphite+ClickHouse. Probleme
In unserem Fall sind wir nicht ohne Hürden davon gekommen. Hier sind die Herausforderungen, mit denen wir nach dem Wechsel konfrontiert wurden.
- ClickHouse liest nicht immer die Konfigurationen in Echtzeit. Manchmal muss es neu gestartet werden. Zum Beispiel wird die Clusterbeschreibung für Zookeeper in der ClickHouse-Konfiguration erst nach einem Neustart des clickhouse-servers angewendet.
- Große Abfragen wurden von ClickHouse nicht verarbeitet, weshalb unsere Verbindung zu ClickHouse in graphite-clickhouse folgendermaßen aussieht:
url = "http://localhost:8123/?max_query_size=268435456&max_ast_elements=1000000" - In ClickHouse erscheinen ziemlich häufig neue stabile Versionen, die Überraschungen mit sich bringen können: Seien Sie vorsichtig.
- Dynamisch erstellte Container in Kubernetes senden eine Vielzahl von Metriken mit kurzer und zufälliger Lebensdauer. Es gibt nur wenige Punkte für solche Metriken, und Platzprobleme bestehen nicht. Bei der Erstellung von Abfragen hebt ClickHouse jedoch eine erhebliche Menge dieser Metriken aus der Tabelle ‚metrics‘ hervor. In 90 % der Fälle sind die Daten für diesen Zeitraum (24 Stunden) nicht vorhanden. Die Suche nach diesen Daten in der Tabelle ‚data‘ erfordert Zeit und führt letztendlich zu einem Timeout. Um dieses Problem zu lösen, haben wir eine separate View mit Informationen zu den Metriken erstellt, die innerhalb eines Tages aufgetreten sind. So befragen wir beim Erstellen von Berichten (Diagrammen) zu dynamisch erstellten Containern nur die Metriken, die innerhalb des angegebenen Fensters vorhanden waren, anstatt über den gesamten Zeitraum, was die Erstellung der Berichte erheblich beschleunigt hat. Für die oben beschriebene Lösung wurde , einschließlich der Implementierung für die Arbeit mit der Tabelle date_metrics.
Graphite+ClickHouse. Tags
Mit Version 1.1.0 hat Graphite offiziell . Und wir denken aktiv darüber nach, was und wie wir tun müssen, um diese Initiative im Stack graphite+clickhouse zu unterstützen.
Graphite+ClickHouse. Anomalie-Detektor
Basierend auf der oben beschriebenen Infrastruktur haben wir einen Prototyp des Anomalie-Detektors entwickelt, und er funktioniert! Mehr dazu in unserem nächsten Artikel.
Abonnieren Sie, drücken Sie den Daumen nach oben und bleiben Sie glücklich!
Quelle: habr.com

