Hallo iedereen! In mijn Ik schreef over het organiseren van een modulair monitoringssysteem voor microservices-architectuur. Niets staat stil, ons project groeit voortdurend, net als het aantal opgeslagen metrics. Hoe we de overstap van Graphite+Whisper naar Graphite+ClickHouse hebben georganiseerd onder hoge belastingen, wat we daarvan verwachtten en de resultaten van de migratie lees je hieronder.

Voordat ik vertel hoe we de overstap van het opslaan van metrics in Graphite+Whisper naar Graphite+ClickHouse hebben georganiseerd, wil ik graag informatie geven over de redenen voor deze beslissing en de nadelen van Whisper waarmee we gedurende lange tijd hebben geleefd.
Problemen met Graphite+Whisper
1. Hoge belasting van het opslag systeem
Op het moment van de overstap ontvingen we ongeveer 1,5 miljoen metrics per minuut. Met zo'n stroom was de schijfutilisatie op de servers ongeveer 30%. Over het algemeen was dit behoorlijk acceptabel â alles werkte stabiel, het werd snel geschreven en snel gelezen... Tot het moment dat een van de ontwikkelteams een nieuwe functie uitrolde en ons 10 miljoen metrics per minuut begon te sturen. Toen kwam de schijfondersteuning onder druk te staan, en zagen we 100% utilisatie. Het probleem kon snel worden opgelost, maar de nasleep bleef.
2. Gebrek aan replicatie en consistentie
Waarschijnlijk, zoals iedereen die Graphite+Whisper gebruikt of heeft gebruikt, stuurden we een gelijke stroom metrics naar meerdere Graphite-servers om redundantie te creĂ«ren. En daar waren geen grote problemen mee â tot het moment dat een van de servers om wat voor reden dan ook uitviel. Soms konden we de uitgevallen server snel opstarten, en carbon-c-relay slaagde erin om metrics uit zijn cache naar deze server te sturen, en soms ook niet. En toen waren er hiaten in de metrics, die we met rsync vulden. Het proces was vrij tijdrovend. Het enige wat ons redde, was dat dit heel zeldzaam gebeurde. Periodiek namen we ook een willekeurige set metrics en vergeleken deze met andere vergelijkbare op aangrenzende knooppunten van de cluster. In ongeveer 5% van de gevallen verschilden enkele waarden, wat ons niet erg vrolijk maakte.
3. Grote hoeveelheid gebruikte ruimte
Aangezien we in Graphite niet alleen infrastructuur- maar ook zakelijke metrics schrijven (en nu ook metrics uit Kubernetes), komen we vaak in situaties waarin een metric slechts enkele waarden bevat, terwijl het .wsp-bestand wordt aangemaakt rekening houdend met de hele retention periode en een vooraf bepaalde hoeveelheid ruimte in beslag neemt, die bij ons ongeveer ~2MB was. Het probleem wordt nog verergerd doordat er in de loop van de tijd veel van dergelijke bestanden ontstaan, en bij het opstellen van rapporten over hen, kost het veel tijd en middelen om lege punten te lezen.
Allereerst willen we opmerken dat we op verschillende manieren en met verschillende degrees van effectiviteit de hierboven beschreven problemen kunnen bestrijden, maar naarmate er meer data binnenkomt, verergeren ze alleen maar.
Met al het bovenstaande in gedachten (rekening houdend met het vorige ), evenals de constante groei van het aantal ontvangen metrics, en de wens om alle metrics over te zetten naar een opslaginterval van 30 seconden (indien nodig tot 10 seconden), hebben we besloten om Graphite+ClickHouse als een veelbelovende alternatieve oplossing voor Whisper te proberen.
Graphite+ClickHouse. Verwachtingen
Na enkele meetups met jongens van Yandex, het lezen , de documentatie te doorzoeken en geschikte componenten te vinden om ClickHouse aan Graphite te koppelen, hebben we besloten om in actie te komen!
We wilden het volgende bereiken:
- discosystemen gebruiken van 30% tot 5%;
- de hoeveelheid in beslag genomen ruimte verlagen van 1TB naar 100GB;
- de mogelijkheid hebben om 100 miljoen metrics per minuut op de server te ontvangen;
- data replicatie en fouttolerantie uit de doos;
- niet langer dan een jaar aan dit project werken en de overgang binnen een redelijke termijn maken;
- overschakelen zonder downtime.
Vrij ambitieus, nietwaar?
Graphite+ClickHouse. Componenten
Voor het verkrijgen van data via het Graphite-protocol en de daaropvolgende opslag in ClickHouse, werd gekozen voor (golang).
Als database voor de opslag van tijdreeksen werd de laatste stabiele release van ClickHouse 1.1.54253 gekozen. Bij het werken hiermee waren er problemen: de logs genereerden een enorme hoeveelheid fouten en het was niet helemaal duidelijk wat ermee te doen. In overleg met (auteur van carbon-clickhouse, graphite-clickhouse en nog veel meer) werd een oudere . De fouten verdwenen â alles werkte perfect.
Voor het lezen van gegevens uit ClickHouse werd gekozen voor (golang). Als API-interface voor Graphite â (golang). Voor het organiseren van replicatie tussen ClickHouse-tabellen werd gebruikgemaakt van . Voor de routering van metrics hebben we onze geliefde (C) .
Graphite+ClickHouse. De structuur van de tabellen
âgraphiteâ â een database die we hebben gemaakt voor monitoringtabellen.
âgraphite.metricsâ â tabel met de motor ReplicatedReplacingMergeTree (gerepliceerd ). In deze tabel worden de namen van metrics en de paden ernaartoe opgeslagen.
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â â tabel met de motor ReplicatedGraphiteMergeTree (gerepliceerd ). In deze tabel worden de waarden van de metrics opgeslagen.
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â â een tabel die op voorwaarde wordt ingevuld, met de motor ReplicatedReplacingMergeTree. In deze tabel worden de namen van alle metrics die in de afgelopen 24 uur zijn tegengekomen, opgeslagen. De redenen voor het creĂ«ren worden beschreven in de sectie aan het einde van dit artikel.
CREATE MATERIALIZED VIEW graphite.date_metrics ( Path String, Level UInt32, Date Date) ENGINE = ReplicatedReplacingMergeTree('\/clickhouse\/tables\/replicator\/graphite.date_metrics', 'r1', Date, (Level, Path, Date), 8192) AS SELECT toUInt32(length(splitByChar('.', Path))) AS Level, Date, Path FROM graphite.dataâgraphite.data_statâ â een tabel die op voorwaarde wordt ingevuld, met de motor ReplicatedAggregatingMergeTree (gerepliceerd ). In deze tabel wordt het aantal binnenkomende metrics geregistreerd, met een splitsing tot 4 niveaus van diepte.
CREATE MATERIALIZED VIEW graphite.data_stat ( Date Date, Prefix String, Timestamp UInt32, Count AggregateFunction(count)) ENGINE = ReplicatedAggregatingMergeTree('\/clickhouse\/tables\/replicator\/graphite.data_stat', 'r1', Date, (Timestamp, Prefix), 8192) AS SELECT toStartOfMonth(now()) AS Date, replaceRegexpOne(Path, '^([^.]+.[^.]+.[^.]+).*$', '1') AS Prefix, toUInt32(toStartOfMinute(toDateTime(Timestamp))) AS Timestamp, countState() AS Count FROM graphite.data GROUP BY Timestamp, PrefixGraphite+ClickHouse. Schema van de interactie tussen componenten

Graphite+ClickHouse. Gegevensmigratie
Zoals we ons herinneren van de verwachtingen voor dit project, moet de overgang naar ClickHouse zonder downtime plaatsvinden, wat betekent dat we op de een of andere manier ons hele monitoringssysteem zo transparant mogelijk voor onze gebruikers naar het nieuwe opslagmedium moeten schakelen.
Zo hebben we dat gedaan.
In carbon-c-relay hebben we een regel toegevoegd om een extra stroom metrics naar carbon-clickhouse van een van de servers die deelnemen aan de replicatie van ClickHouse-tabellen te sturen.
We wrote a small script in Python that used the whisper-dump library to read all .wsp files from our storage and send this data to the aforementioned carbon-clickhouse in 24 streams. The number of metric values accepted by carbon-clickhouse reached 125 million per minute, and ClickHouse didnât even sweat.
We created a separate DataSource in Grafana with the aim of debugging functions used in existing dashboards. We identified a list of functions that we used but were not implemented in carbonapi. We wrote these functions and sent PRs to the authors of carbonapi (many thanks to them).
- To switch the read load in the load balancer settings, we changed the endpoints from graphite-api (API interface for Graphite+Whisper) to carbonapi.
Graphite+ClickHouse. Results
reduced disk subsystem utilization from 30% to 1%;

- reduced the occupied space from 1 TB to 300 GB;
- we have the capability to accept 125 million metrics per minute to the server (peaks during migration);
- we switched all metrics to a thirty-second storage interval;
- we achieved data replication and fault tolerance;
- we switched without downtime;
- we spent about 7 weeks on everything.
Graphite+ClickHouse. Issues
In our case, we encountered some pitfalls. Hereâs what we faced after the transition.
- ClickHouse does not always reread configs on the fly; sometimes it needs to be restarted. For example, in the case of the zookeeper cluster description in the ClickHouse config â it was not applied until clickhouse-server was restarted.
- Large ClickHouse queries didnât go through, so our graphite-clickhouse connection string to ClickHouse looks like this:
url = "http://localhost:8123/?max_query_size=268435456&max_ast_elements=1000000" - New stable releases of ClickHouse come out quite often, and they may contain surprises: be cautious.
- Dynamisch aangemaakte containers in Kubernetes verzenden een groot aantal metrics met een korte en willekeurige levensduur. Er zijn niet veel punten voor zulke metrics, en er zijn geen problemen met opslag. Maar bij het opbouwen van verzoeken haalt ClickHouse een enorme hoeveelheid van deze metrics op uit de tabel 'metrics'. In 90% van de gevallen zijn gegevens voor deze metrics in het venster (24 uur) afwezig. De tijd die nodig is om deze gegevens in de tabel 'data' te zoeken, wordt besteed en komt uiteindelijk tegen een time-out aan. Om dit probleem op te lossen, zijn we begonnen met het onderhouden van een aparte view met informatie over de metrics die gedurende de dag zijn aangetroffen. Zo vragen we bij het opstellen van rapporten (grafieken) over dynamisch aangemaakte containers alleen de metrics op die binnen het opgegeven venster zijn aangetroffen, in plaats van over de hele tijd, wat het opbouwen van rapporten aanzienlijk heeft versneld. Voor de hierboven beschreven oplossing is verzameld , inclusief de implementatie van het werken met de tabel date_metrics.
Graphite+ClickHouse. Labels
Vanaf versie 1.1.0 ondersteunt Graphite officieel . En we denken actief na over wat en hoe we moeten doen om deze initiatieven in de stack graphite+clickhouse te ondersteunen.
Graphite+ClickHouse. Anomaliedetector
Op basis van de hierboven beschreven infrastructuur hebben we een prototype van een anomaliedetector gerealiseerd, en het werkt! Maar daarover meer in het volgende artikel.
Abonneer je, druk op de pijl omhoog en wees gelukkig!
Bron: habr.com

