Opbevaring af metrics: hvordan vi gik fra Graphite+Whisper til Graphite+ClickHouse

Hej alle sammen! I min den forrige artikel jeg skrev om organiseringen af et modulært overvågningssystem til en mikrotjenestearkitektur. Intet står stille, vores projekt vokser konstant, og antallet af gemte metrikker stiger også. Hvordan vi organiserede overgangen fra Graphite+Whisper til Graphite+ClickHouse under høje belastninger, hvad vi forventede af det, og resultaterne af migrationen, kan du læse videre om.

Opbevaring af metrics: hvordan vi gik fra Graphite+Whisper til Graphite+ClickHouse

Før jeg fortæller, hvordan vi organiserede overgangen fra opbevaring af metrikker i Graphite+Whisper til Graphite+ClickHouse, vil jeg gerne give information om årsagerne til at træffe en sådan beslutning og de ulemper ved Whisper, som vi levede med i en længere periode.

Problemer med Graphite+Whisper

1. Høj belastning på diskafdelingen

På tidspunktet for overgangen modtog vi omtrent 1,5 millioner metrikker i minuttet. Med sådan en strøm var diskudnyttelsen på serverne ~30%. Generelt var det rimeligt — alt fungerede stabilt, data blev hurtigt skrevet, og hurtigt læst… Indtil det øjeblik, hvor et af udviklingsteamsene rullede en ny funktion ud og begyndte at sende os 10 millioner metrikker i minuttet. På det tidspunkt blev diskafdelingen presset, og vi så 100% udnyttelse. Problemet blev hurtigt løst, men det satte sine spor.

2. Manglende replikation og konsistens

Sandsynligvis ligesom alle, der bruger/har brugt Graphite+Whisper, sendte vi den samme strøm af metrikker til flere Graphite-servere med det formål at skabe fejltolerance. Og der var ikke særlige problemer med det — indtil et af serverne faldt af en eller anden grund. Nogle gange nåede vi at genoprette den faldne server hurtigt, og carbon-c-relay nåede at overføre metrikkerne fra sin cache til den, og andre gange ikke. Og så var der huller i metrikkerne, som vi fyldte med rsync. Proceduren var ret lang. Det reddede os kun, at sådanne hændelser skete meget sjældent. Vi tog også lejlighedsvis et tilfældigt udvalg af metrikker og sammenlignede dem med andre på nabo-noderne i klyngen. I cirka 5% af tilfældene var flere værdier forskellige, hvilket ikke gjorde os synderligt glade.

3. Stort pladsforbrug

Da vi skriver til Graphite ikke kun infrastrukturmæssige, men også forretningsmetrikker (og nu også metrikker fra Kubernetes), oplever vi ofte situationer, hvor metrikken kun har få værdier, mens .wsp-filen oprettes med henblik på hele retention-perioden og optager den forudbestemte mængde plads, som vi havde sat til ~2MB. Problemet forværres yderligere af, at der over tid opstår mange lignende filer, og når der laves rapporter på dem, tager det meget tid og ressourcer at læse tomme punkter.

Det skal bemærkes, at de problemer, der er beskrevet ovenfor, kan tackles med forskellige metoder og med forskellig effektivitet, men jo mere data der begynder at komme til jer, jo mere intensiveres de.

Med alt det ovenstående (under hensyntagen til den tidligere artikler), samt den konstante stigning i antallet af indsamlede metrikker og ønsket om at reducere alle metrikker til en lagringsinterval på 30 sekunder (om nødvendigt - ned til 10 sekunder), besluttede vi at prøve Graphite+ClickHouse som en lovende alternativ til Whisper.

Graphite+ClickHouse. Forventninger

Efter at have deltaget i flere meetups med folk fra Yandex, læst et par artikler på Habré, gennemsøgt dokumentationen og fundet rimelige komponenter til at forbinde ClickHouse til Graphite, besluttede vi at handle!

Vi ønskede at opnå følgende:

  • sætte diskudnyttelsen fra 30% til 5%;
  • sætte det optagne plads fra 1TB til 100GB;
  • have mulighed for at modtage 100 millioner metrikker pr. minut på serveren;
  • repræsentation af data og fejlfindingsmuligheder out-of-the-box;
  • ikke bruge et år på dette projekt og foretage overgangen inden for rimelig tid;
  • skifte uden nedetid.

Ret ambitiøst, ikke?

Graphite+ClickHouse. Komponenter

For at modtage data via Graphite-protokollen og efterfølgende skrive dem til ClickHouse, blev der valgt carbon-clickhouse (golang).

Som database til opbevaring af tidsrækker blev den seneste stabile version af ClickHouse valgt, version 1.1.54253. Da vi arbejdede med det, var der problemer: loggene flød over med fejl, og det var ikke helt klart, hvad der skulle gøres med dem. I drøftelser med Roman Lomonosov (forfatter af carbon-clickhouse, graphite-clickhouse og meget, meget mere) blev der valgt en ældre version 1.1.54236.Fejlene forsvandt — alt begyndte at fungere perfekt.

For at læse data fra ClickHouse blev der valgt graphite-slickhouse (golang). Som API-grænseflade til Graphite — carbonapi (golang). For organizing replication between tables in ClickHouse, we used zookeeper. For routing metrics, we kept our beloved carbon-c-relay (C) (see the previous article).

Graphite+ClickHouse. Table Structure

“graphite” — a database created by us for monitoring tables.

“graphite.metrics” — a table with the ReplicatedReplacingMergeTree engine (replicated ReplacingMergeTree). This table stores metric names and their paths.

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” — a table with the ReplicatedGraphiteMergeTree engine (replicated GraphiteMergeTree). This table stores metric values.

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” — a conditionally filled table with the ReplicatedReplacingMergeTree engine. This table stores all metric names encountered over the day. The reasons for its creation are described in the section “Problems” at the end of this article.

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” — a conditionally filled table with the ReplicatedAggregatingMergeTree engine (replicated AggregatingMergeTree). This table stores the number of incoming metrics, broken down to 4 levels of nesting.

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

Graphite+ClickHouse. Interaction Scheme of Components

Opbevaring af metrics: hvordan vi gik fra Graphite+Whisper til Graphite+ClickHouse

Graphite+ClickHouse. Data Migration

As we remember from the expectations of this project, the transition to ClickHouse should be without downtime, accordingly, we had to somehow switch our entire monitoring system to the new storage as transparently as possible for our users.
We did it like this.

  • In carbon-c-relay, we added a rule to send an additional stream of metrics to carbon-clickhouse from one of the servers participating in the replication of ClickHouse tables.

  • Vi har skrevet et lille script i Python, der ved hjælp af biblioteket whisper-dump læste alle .wsp-filer fra vores lager og sendte disse data til den ovenfor nævnte carbon-clickhouse i 24 tråde. Antallet af modtagne metriks værdier i carbon-clickhouse nåede op på 125 millioner/min., og ClickHouse blev slet ikke påvirket.

  • Vi oprettede en separat DataSource i Grafana med det formål at debugge funktioner, der anvendes i de eksisterende dashboards. Vi identificerede en liste over funktioner, som vi brugte, men som ikke var implementeret i carbonapi. Vi tilføjede disse funktioner og sendte PR'er til forfatterne af carbonapi (en særlig tak til dem).

  • For at skifte den læsende belastning ændrede vi indstillingerne for balancererne fra graphite-api (API interface til Graphite+Whisper) til carbonapi.

Graphite+ClickHouse. Resultater

  • vi sænkede diskens udnyttelse fra 30% til 1%;

    Opbevaring af metrics: hvordan vi gik fra Graphite+Whisper til Graphite+ClickHouse

  • vi reducerede den optagede plads fra 1 TB til 300 GB;
  • vi har mulighed for at modtage 125 millioner metrics pr. minut i serveren (toppe under migrationen);
  • vi har overført alle metrics til et tredive sekunders opbevaringsinterval;
  • vi har opnået datagendannelse og fejlrobusthed;
  • vi skiftede uden nedetid;
  • alt i alt brugte vi cirka 7 uger.

Graphite+ClickHouse. Problemer

I vores tilfælde var der også nogle faldgruber. Her er hvad vi stødte på efter overgangen.

  1. ClickHouse læser ikke altid konfigurationer i realtid, nogle gange skal det genstartes. For eksempel med beskrivelsen af kluster zookeeper i ClickHouse-konfigurationen - den blev ikke anvendt før genstart af clickhouse-server.
  2. Store forespørgsler til ClickHouse gik ikke igennem, derfor ser vores forbindelse til ClickHouse sådan ud i graphite-clickhouse:
    url = "http://localhost:8123/?max_query_size=268435456&max_ast_elements=1000000"
  3. I ClickHouse udkommer der ret ofte nye versioner af stabile udgivelser, og der kan være overraskelser: vær opmærksom.
  4. Dynamisk genererede containere i Kubernetes sender et stort antal målinger med korte og tilfældige livscyklusser. Der er ikke mange punkter for disse målinger, og der er ikke pladsproblemer. Men når vi opbygger forespørgsler, trækker ClickHouse et kæmpe antal af disse målinger fra tabellen ‘metrics’. I 90% af tilfældene mangler data for dem over vinduet (24 timer). Tiden brugt på at finde disse data i tabellen ‘data’ er dog betydelig og ender ofte med at støde ind i timeout. For at løse dette problem begyndte vi at føre en separat visning med information om målinger, der blev registreret over en dag. På den måde, når vi konstruerer rapporter (grafer) for dynamisk genererede containere, forespørger vi kun de målinger, der blev registreret inden for det angivne vindue, i stedet for hele tiden, hvilket har betydeligt forkortet tiden for rapportopbygningen. graphite-clickhouse (fork), som inkluderer implementeringen af arbejde med tabellen date_metrics.

Graphite+ClickHouse. Tags

Fra version 1.1.0 begyndte Graphite officielt at understøtte tags. Og vi overvejer aktivt, hvad og hvordan vi skal gøre for at understøtte denne initiativ i stakken graphite+clickhouse.

Graphite+ClickHouse. Anomalidetektor

Baseret på den beskrevne infrastruktur har vi implementeret en prototype af en anomalidetektor, og den fungerer! Men om det – i næste artikel.

Tilmeld dig, tryk på pilen opad og vær glad!

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster