Pozdravljeni! V svojem sem pisal o organizaciji modulnega sistema spremljanja za mikroservisno arhitekturo. Nič ne miruje, naš projekt nenehno raste, prav tako tudi število shranjenih metrik. Kako smo organizirali prehod z Graphite+Whisper na Graphite+ClickHouse v pogojih visokih obremenitev, o pričakovanjih in rezultatih migracije preberite spodaj.

Preden vam povem, kako smo organizirali prehod z shranjevanja metrik v Graphite+Whisper na Graphite+ClickHouse, bi rad delil informacije o razlogih za sprejetje take odločitve in o pomanjkljivostih Whisper, s katerimi smo živeli dolgo časa.
Težave Graphite+Whisper
1. Visoka obremenitev diskovne sisteme
Ob času prehoda smo prejemali približno 1,5 milijona metrik na minuto. Pri takem toku je bila diskovna obremenitev na strežnikih približno 30%. Na splošno je bilo to precej sprejemljivo — vse je delovalo stabilno, hitro se je pisalo, hitro bralo… Dokler ena od razvojnih ekip ni uvedla nove funkcionalnosti in začela pošiljati 10 milijonov metrik na minuto. Takrat je diskovni sistem začel škripati in opazili smo 100% obremenitev. Težavo smo uspeli hitro rešiti, a ostal je grenkoben priokus.
2. Pomanjkanje replikacije in doslednosti
Verjetno kot vsi, ki uporabljajo/uporabljajo Graphite+Whisper, smo pošiljali enak tok metrik hkrati na več Graphite strežnikov z namenom ustvarjanja odpornosti na napake. S tem nismo imeli posebnih težav — do trenutka, ko je eden od strežnikov iz kakršnega koli razloga odpovedal. Včasih smo uspeli hitro ponovno zagnati odpovedani strežnik, in carbon-c-relay je uspeval nalagati metrike iz svojega predpomnilnika, včasih pa ne. In takrat so v metrikah nastale luknje, ki smo jih zapolnili z rsync-om. Postopek je bil precej dolgotrajen. Reševalo je le to, da se je to dogajalo zelo redko. Občasno smo tudi vzeli naključen nabor metrik in jih primerjali z drugimi na sosednjih vozliščih gruče. V približno 5% primerov so se nekateri podatki razlikovali, kar nas ni preveč razveselilo.
3. Velik obseg zasedenega prostora
Ko mi pišemo v Graphite ne le infrastrukturo, temveč tudi poslovne metrike (in zdaj še metrike iz Kubernetes), pogosto naletimo na situacijo, kjer v metriki obstajajo le vrednosti, .wsp datoteka pa se ustvarja ob upoštevanju celotnega obdobja zadrževanja in zaseda predviden prostor, ki je bil pri nas enak približno 2 MB. Težavo še dodatno poslabša dejstvo, da s časom nastane zelo veliko takih datotek, in pri ustvarjanju poročil o njih se porabi veliko časa in virov za branje praznih točk.
Takoj bi rad opozoril, da se z zgoraj opisanimi težavami lahko borimo na različne načine in z različno stopnjo učinkovitosti, vendar se težave ob večjem pretoku podatkov le še zaostrujejo.
Glede na vse zgoraj omenjeno (ob upoštevanju prejšnje ), pa tudi nenehno rast števila prejetih metrik in željo po prehodu na interval shranjevanja 30 sekund (po potrebi - do 10 sekund), smo se odločili poskusiti Graphite+ClickHouse kot obetavno alternativo Whisper.
Graphite+ClickHouse. Pričakovanja
Po udeležbi na več srečanjih z ekipo Yandex in branju , smo pregledali dokumentacijo in našli smiselne komponente za povezovanje ClickHouse z Graphite in se odločili za akcijo!
Želeli smo doseči naslednje:
- zmanjšati obremenitev diskovnega sistema z 30% na 5%;
- zmanjšati zaseden prostor z 1 TB na 100 GB;
- imeti sposobnost sprejemati 100 milijonov metrik na minuto na strežnik;
- replikacija podatkov in odpornost na napake out of the box;
- ne preživeti leta nad tem projektom, ampak prehoditi razumen čas;
- preklopiti brez zamanja.
Kul, mar ne?
Graphite+ClickHouse. Komponente
Za pridobivanje podatkov po protokolu Graphite in kasnejšo shranitev v ClickHouse, smo izbrali (golang).
Kot podatkovno bazo za shranjevanje časovnih vrst smo izbrali zadnjo stabilno različico ClickHouse 1.1.54253. Pri delu z njim so se pojavile težave: v dnevnikih se je pojavljalo veliko napak in ni bilo povsem jasno, kako ravnati z njimi. V razpravi z (avtor carbon-clickhouse, graphite-clickhouse in še mnogih drugih stvari) smo izbrali starejšo Napake so izginile - vse je začelo delovati odlično.
Za branje podatkov iz ClickHouse smo izbrali (golang). Kot API vmesnik za Graphite - (golang). Za organizacijo replikacije med tabelami ClickHouse smo uporabili . Za usmerjanje metrik smo pustili našo ljubljeno (C) .
Graphite+ClickHouse. Struktura tabel
“graphite” — baza podatkov, ki smo jo ustvarili za tabele monitoringa.
“graphite.metrics” — tabela z motorjem ReplicatedReplacingMergeTree (replicirana ). V tej tabeli so shranjena imena metrik in poti do njih.
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” — tabela z motorjem ReplicatedGraphiteMergeTree (replicirana ). V tej tabeli so shranjene vrednosti metrik.
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” — tabela, ki se napolni po pogojih, z motorjem ReplicatedReplacingMergeTree. V to tabelo se zapisujejo imena vseh metrik, ki so jih srečali v 24 urah. Razlogi za ustvarjanje so opisani v poglavju na koncu tega članka.
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” — tabela, ki se napolni po pogojih, z motorjem ReplicatedAggregatingMergeTree (replicirana ). V to tabelo se zapisuje število prejetih metrik, razdeljenih do 4 ravni globine.
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. Shema interakcije komponent

Graphite+ClickHouse. Migracija podatkov
Kot se spomnimo iz pričakovanj glede tega projekta, bi prehod na ClickHouse moral biti brez izpadov, zato smo morali nekako preklopiti celoten naš sistem monitoringa na novo shrambo čim bolj pregledno za naše uporabnike.
Uresničili smo to tako.
V carbon-c-relay smo dodali pravilo za pošiljanje dodatnega toka metrik v carbon-clickhouse enega od strežnikov, ki sodelujejo v replikaciji tabel ClickHouse.
Smo smo napisali skript v Pythonu, ki je z uporabo knjižnice whisper-dump prebral vse .wsp datoteke iz našega skladišča in ta podatke poslal v zgoraj omenjen carbon-clickhouse v 24 tokov. Število sprejetih vrednosti metrik v carbon-clickhouse je doseglo 125 milijonov/min, ClickHouse pa se niti ni zdel obremenjen.
Ustvarili smo ločen DataSource v Grafani z namenom odpravljanja napak funkcij, ki se uporabljajo v obstoječih nadzornih ploščah. Ugotovili smo seznam funkcij, ki smo jih uporabljali, vendar niso bile implementirane v carbonapi. Te funkcije smo dodali in poslali PR avtorjem carbonapi (posebna zahvala njim).
- Za preusmeritev bralnega bremena smo v nastavitvah uravnoteževalnikov spremenili končne točke iz graphite-api (API vmesnik za Graphite+Whisper) na carbonapi.
Graphite+ClickHouse. Rezultati
smo zmanjšali obremenitev diskovnega sistema s 30 % na 1 %;

- smo zmanjšali zaseden prostor s 1 TB na 300 GB;
- imamo možnost sprejemati do 125 milijonov metrik na minuto na strežnik (vrhovi med migracijo);
- smo prešli na tridesetsekundni interval shranjevanja metrik;
- smo pridobili replikacijo podatkov in odpornost na okvare;
- smo preklopili brez izpadov;
- za vse smo porabili približno 7 tednov.
Graphite+ClickHouse. Težave
V našem primeru ni šlo brez skritih težav. Tukaj je, s čimer smo se soočili po prehodu.
- ClickHouse ne bere vedno konfiguracij v realnem času, včasih ga je treba znova zagnati. Na primer, v primeru opisa gruče zookeeper v konfiguraciji ClickHouse — ta se ni uporabil do ponovnega zagona clickhouse-serverja.
- Veliki poizvedbi ClickHouse v našem primeru niso šli skozi, zato v naši povezavi graphite-clickhouse k ClickHouse izgleda tako:
url = "http://localhost:8123/?max_query_size=268435456&max_ast_elements=1000000" - V ClickHouse pogosto izhajajo nove različice stabilnih izdaj, v njih se lahko pojavijo presenečenja: bodite previdni.
- Dinamčno ustvarjeni kontejnerji v kubernetes pošiljajo veliko količino metrik s kratkim in slučajnim časom življenja. Točk za te metrike ni veliko, in ni težav s prostorom. Vendar pa pri gradnji poizvedb ClickHouse dvigne ogromno teh metrik iz tabele 'metrics'. V 90 % primerov podatki zanje v oknu (24 ur) niso prisotni. Čas iskanja teh podatkov v tabeli 'data' se porabi, kar na koncu privede do časovne omejitve. Da bi rešili ta problem, smo začeli voditi posebej pogled s informacijami o metrike, ki so se pojavile v zadnjih 24 urah. Tako, pri gradnji poročil (grafikonov) za dinamično ustvarjene kontejnerje, sprašujemo le tiste metrike, ki so se pojavile v okviru določenega okna, ne pa za celotno obdobje, kar je močno pospešilo gradnjo poročil zanje. Za zgoraj opisana rešitev je bila zbrana , ki vključuje implementacijo dela s tabelo date_metrics.
Graphite+ClickHouse. Oznake
Z različico 1.1.0 je Graphite uradno . In aktivno razmišljamo o tem, kaj in kako narediti, da podpiramo to pobudo v kupu graphite+clickhouse.
Graphite+ClickHouse. Detektor anomalij
Na podlagi zgoraj opisane infrastrukture smo izvedli prototip detektorja anomalij, ki deluje! O njem pa - v naslednjem članku.
Naročite se, pritisnite puščico navzgor in bodite srečni!
Izvor: habr.com

