Mätvärdeslagring: hur vi bytte från Graphite+Whisper till Graphite+ClickHouse

Hej alla! I hans senaste artikeln Jag skrev om att organisera ett modulärt övervakningssystem för mikrotjänstarkitektur. Ingenting står stilla, vårt projekt växer ständigt, och så även antalet lagrade mätvärden. Hur vi organiserade övergången från Graphite+Whisper till Graphite+ClickHouse under höga belastningsförhållanden, läs om förväntningarna från det och resultaten av migreringen under cut.

Mätvärdeslagring: hur vi bytte från Graphite+Whisper till Graphite+ClickHouse

Innan jag berättar hur vi organiserade övergången från att lagra mätvärden i Graphite+Whisper till Graphite+ClickHouse skulle jag vilja ge information om skälen till att fatta ett sådant beslut och om nackdelarna med Whisper som vi levt med under lång tid.

Grafit+Viskningsproblem

1. Hög belastning på diskundersystemet

Vid tidpunkten för övergången anlände cirka 1.5 miljoner mätvärden till oss per minut. Med ett sådant flöde var diskutnyttjandet på servrar ~30%. I allmänhet var detta ganska acceptabelt - allt fungerade stabilt, skrevs snabbt, lästes snabbt... Tills ett av utvecklingsteamen rullade ut en ny funktion och började skicka oss 10 miljoner mätvärden per minut. Det var då diskundersystemet skärptes och vi såg 100% utnyttjande. Problemet löstes snabbt, men en rest kvarstod.

2. Brist på replikering och konsekvens

Mest troligt, som alla som använder/använder Graphite+Whisper, hällde vi samma ström av mätvärden på flera Graphite-servrar samtidigt för att skapa feltolerans. Och det var inga speciella problem med detta - tills det ögonblick då en av servrarna kraschade av någon anledning. Ibland lyckades vi plocka upp en fallen server tillräckligt snabbt, och carbon-c-relay lyckades ladda in mätvärden från sin cache till den, men ibland inte. Och så fanns det ett hål i måtten, som vi fyllde med rsync. Proceduren var ganska lång. Den enda räddande nåden var att detta hände mycket sällan. Vi tog också med jämna mellanrum en slumpmässig uppsättning mätvärden och jämförde dem med andra av samma typ på angränsande noder i klustret. I cirka 5 % av fallen var flera värden olika, vilket vi inte var särskilt nöjda med.

3. Stort fotavtryck

Eftersom vi skriver i Graphite inte bara infrastruktur, utan även affärsmått (och nu även mätvärden från Kubernetes) får vi ganska ofta en situation där måtten endast innehåller ett fåtal värden, och .wsp-filen skapas med hänsyn till all retention period, och tar upp en förtilldelad mängd utrymme, vilket för oss var ~2MB. Problemet förvärras ytterligare av det faktum att många liknande filer dyker upp med tiden, och när man bygger rapporter om dem tar det mycket tid och resurser att läsa tomma punkter.

Jag vill omedelbart notera att de ovan beskrivna problemen kan hanteras med olika metoder och med varierande grad av effektivitet, men ju mer data du börjar få, desto mer förvärras de.

Att ha allt ovanstående (med hänsyn till föregående Artikel), såväl som en konstant ökning av antalet mottagna mätvärden, önskan att överföra alla mätvärden till ett lagringsintervall på 30 sekunder. (upp till 10 sekunder vid behov), bestämde vi oss för att prova Graphite+ClickHouse som ett lovande alternativ till Whisper.

Grafit+ClickHouse. Förväntningar

Efter att ha besökt flera träffar av killarna från Yandex, efter att ha läst ett par artiklar om Habré, efter att ha gått igenom dokumentationen och hittat sunda komponenter för att binda ClickHouse under Graphite, bestämde vi oss för att vidta åtgärder!

Jag skulle vilja få följande:

  • minska användningen av diskundersystem från 30 % till 5 %;
  • minska mängden upptaget utrymme från 1 TB till 100 GB;
  • kunna ta emot 100 miljoner mätvärden per minut till servern;
  • datareplikering och feltolerans direkt;
  • Sitt inte på det här projektet i ett år och gör övergången inom en rimlig tidsram;
  • switch utan stillestånd.

Ganska ambitiöst, eller hur?

Grafit+ClickHouse. Komponenter

För att ta emot data via Graphite-protokollet och sedan spela in det i ClickHouse valde jag kol-klickhus (golang).

Den senaste versionen av ClickHouse, stabil version 1.1.54253, valdes som databas för lagring av tidsserier. Det fanns problem när man arbetade med det: ett berg av fel strömmade in i loggarna, och det var inte helt klart vad man skulle göra med dem. I diskussion med Roman Lomonosov (författare till carbon-clickhouse, graphite-clickhouse och många, många fler) den äldre valdes släpp 1.1.54236. Felen försvann – allt började fungera med en smäll.

Vald för att läsa data från ClickHouse grafit-slickhouse (golang). Som ett API för grafit − carbonapi (golang). ClickHouse användes för att organisera replikering mellan tabeller djurhållare. För ruttmätningar lämnade vi vår älskade kol-c-relä (C) (se tidigare artikel).

Grafit+ClickHouse. Tabellstruktur

"grafit" är en databas som vi skapade för att övervaka tabeller.

"graphite.metrics" - tabell med ReplicatedReplacingMergeTree-motorn (replikerad Ersätter MergeTree). Den här tabellen lagrar namnen på mätvärden och sökvägar till dem.

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" - tabell med ReplicatedGraphiteMergeTree-motorn (replikerad GraphiteMergeTree). Den här tabellen lagrar metriska värden.

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" är en villkorligt ifylld tabell med motorn ReplicatedReplacingMergeTree. Den här tabellen registrerar namnen på alla mätvärden som påträffades under dagen. Skälen till dess skapande beskrivs i avsnittet "Problem" i slutet av denna 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" - en tabell fylld enligt tillstånd, med motorn ReplicatedAggregatingMergeTree (replikerad AggregatingMergeTree). Den här tabellen registrerar antalet inkommande mätvärden, uppdelat på fyra kapslingsnivåer.

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, Prefix

Grafit+ClickHouse. Komponentinteraktionsdiagram

Mätvärdeslagring: hur vi bytte från Graphite+Whisper till Graphite+ClickHouse

Grafit+ClickHouse. Datamigrering

Som vi minns från förväntningarna från det här projektet borde övergången till ClickHouse ske utan stillestånd, därför var vi på något sätt tvungna att byta hela vårt övervakningssystem till den nya lagringen så transparent som möjligt för våra användare.
Så här gjorde vi det.

  • En regel har lagts till carbon-c-relay för att skicka ytterligare en ström av mätvärden till carbon-clickhouse på en av servrarna som deltar i replikeringen av ClickHouse-tabeller.

  • Vi skrev ett litet skript i python, som med hjälp av whisper-dump-biblioteket läste alla .wsp-filer från vår lagring och skickade dessa data till det ovan beskrivna carbon-clickhouse i 24 trådar. Antalet accepterade metriska värden i carbon-clickhouse nådde 125 miljoner/min, och ClickHouse svettades inte ens.

  • Vi skapade en separat DataSource i Grafana för att felsöka funktioner som används i befintliga instrumentpaneler. Vi identifierade en lista över funktioner som vi använde, men de implementerades inte i carbonapi. Vi lade till dessa funktioner och skickade PR till författarna till carbonapi (särskilt tack till dem).

  • För att ändra läsbelastningen i balanseringsinställningarna ändrade vi ändpunkterna från grafit-api (API-gränssnitt för Graphite+Whisper) till carbonapi.

Grafit+ClickHouse. resultat

  • minskad användning av diskundersystem från 30 % till 1 %;

    Mätvärdeslagring: hur vi bytte från Graphite+Whisper till Graphite+ClickHouse

  • minskat mängden upptaget utrymme från 1 TB till 300 GB;
  • vi har förmågan att ta emot 125 miljoner mätvärden per minut till servern (toppar vid tidpunkten för migreringen);
  • överförde alla mätvärden till ett trettio sekunders lagringsintervall;
  • mottagen datareplikering och feltolerans;
  • kopplade utan driftstopp;
  • Det tog cirka 7 veckor att slutföra allt.

Grafit+ClickHouse. Problem

I vårt fall fanns det några fallgropar. Detta är vad vi mötte efter övergången.

  1. ClickHouse läser inte alltid om konfigurationer i farten, ibland måste den startas om. Till exempel, när det gäller beskrivningen av zookeeper-klustret i ClickHouse-konfigurationen, användes den inte förrän clickhouse-servern startades om.
  2. Stora ClickHouse-förfrågningar gick inte igenom, så i graphite-clickhouse ser vår ClickHouse-anslutningssträng ut så här:
    url = "http://localhost:8123/?max_query_size=268435456&max_ast_elements=1000000"
  3. ClickHouse släpper ganska ofta nya versioner av stabila utgåvor, de kan innehålla överraskningar: var försiktig.
  4. Dynamiskt skapade behållare i kubernetes skickar ett stort antal mätvärden med en kort och slumpmässig livslängd. Det finns inte många poäng för sådana mätvärden, och det finns inga problem med utrymmet. Men när man bygger frågor, plockar ClickHouse upp ett stort antal av samma mätvärden från tabellen "metrics". I 90% av fallen finns det inga uppgifter om dem utanför fönstret (24 timmar). Men tid ägnas åt att söka efter dessa data i "data"-tabellen, och slutligen uppstår en timeout. För att lösa detta problem började vi upprätthålla en separat vy med information om mätvärden som påträffades under dagen. Sålunda, när vi bygger rapporter (grafer) för dynamiskt skapade behållare, frågar vi bara de mätvärden som påträffades inom ett givet fönster, och inte för hela tiden, vilket avsevärt snabbade upp konstruktionen av rapporter om dem. För lösningen som beskrivs ovan samlade jag grafit-klickhus (gaffel), som inkluderar implementeringen av att arbeta med tabellen date_metrics.

Grafit+ClickHouse. Taggar

Med version 1.1.0 blev Graphite officiellt stödtaggar. Och vi funderar aktivt på vad och hur vi ska göra för att stödja detta initiativ i grafit+klickhusstacken.

Grafit+ClickHouse. Anomalidetektor

Baserat på infrastrukturen som beskrivs ovan har vi implementerat en prototyp av en anomalidetektor, och det fungerar! Men mer om honom i nästa artikel.

Prenumerera, tryck på uppåtpilen och var glad!

Källa: will.com

Lägg en kommentar