Pozdrav svima! U svom sam pisao o organizaciji modularnog sustava nadzora za mikroservisnu arhitekturu. Ništa ne stoji, naš projekt neprestano raste, a broj pohranjenih metrika također. Kako smo organizirali prijelaz s Graphite+Whisper na Graphite+ClickHouse u uvjetima visokih opterećenja, o našim očekivanjima i rezultatima migracije pročitajte u nastavku.

Prije nego što vam ispričam kako smo organizirali prijelaz s pohrane metrika u Graphite+Whisper na Graphite+ClickHouse, želio bih dati informacije o razlozima donošenja takve odluke i o minusima Whispere s kojima smo živjeli dugo vremena.
Problemi Graphite+Whisper
1. Visoko opterećenje na disketnoj podjeli
U trenutku prijelaza, primali smo oko 1,5 milijuna metrika u minuti. S takvim protokom, iskorištenost diska na serverima iznosila je ~30%. U cjelini, to je bilo prilično prihvatljivo — sve je radilo stabilno, brzo je pisano, brzo je čitano… Do onog trenutka kada je jedan od razvojnih timova lansirao novu funkcionalnost i počeo nam slati 10 milijuna metrika u minuti. Tada je disketna podjela bila pod velikim opterećenjem, i vidjeli smo 100% iskorištenosti. Problem smo brzo riješili, ali ostao je loš osjećaj.
2. Nedostatak replikacije i konzistentnosti
Vjerojatno kao i svi koji koriste/koristili Graphite+Whisper, slali smo isti protok metrika na nekoliko Graphite servera s ciljem stvaranja otpornosti na greške. I s tim nije bilo posebnih problema — sve do trenutka kada je jedan od servera iz nekog razloga pao. Ponekad smo uspjeli brzo podići srušeni server, i carbon-c-relay je uspio ulijevati metrike iz svoje predmemorije, a ponekad nismo. A tada je u metrikama nastala rupa, koju smo popunjavali rsync-om. Postupak je bio prilično dug. Spašavalo nas je to što se takvo nešto događalo vrlo rijetko. Također, povremeno smo uzeli nasumični skup metrika i usporedili ih s drugim takvima na susjednim čvorovima klastera. U otprilike 5% slučajeva nekoliko vrijednosti se razlikovalo, što nas nije previše veselilo.
3. Velika količina zauzetog prostora
Budući da u Graphite pišemo ne samo infrastrukturne, već i poslovne metrike (a sada i metrike iz Kubernetes-a), često se suočavamo sa situacijom u kojoj metrika sadrži samo nekoliko vrednosti, a .wsp datoteka se kreira uzimajući u obzir ceo period zadržavanja, zauzimajući unapred dodeljenu količinu prostora, koja je kod nas bila otprilike 2MB. Problem se dodatno pogoršava time što s vremenom dolazi do pojave velikog broja takvih datoteka, a za izradu izveštaja na njih se troši mnogo vremena i resursa.
Odmah želim napomenuti da se sa problemima opisanim iznad može boriti na različite načine i sa različitim stepenima efikasnosti, ali što više podataka počne dolaziti, to se problemi jače manifestuju.
Imajući sve gore navedeno (uzimajući u obzir prethodno ), kao i stalni rast broja primljenih metrika, želju da sve metrike prebacimo na interval zadržavanja od 30 sekundi (po potrebi — do 10 sekundi), odlučili smo da isprobamo Graphite+ClickHouse kao perspektivnu alternativu Whisper.
Graphite+ClickHouse. Očekivanja
Posetivši nekoliko mitinga sa momcima iz Yandex-a, pročitavši , pretražujući dokumentaciju i pronalazeći razumna rešenja za povezivanje ClickHouse-a sa Graphite-om, odlučili smo da delujemo!
Želeli smo postići sledeće:
- smanjiti upotrebu diskovnog sistema sa 30% na 5%;
- smanjiti zauzeto mesto sa 1TB na 100GB;
- imati mogućnost prihvatanja po 100 miliona metrika u minutu na server;
- replikaciju podataka i otpornost na greške iz kutije;
- ne provoditi godinu dana na ovom projektu i izvršiti prelazak u razumnom roku;
- prebaciti se bez zastoja.
Dosta ambiciozno, zar ne?
Graphite+ClickHouse. Komponente
Za dobijanje podataka putem Graphite protokola i njihovu naknadnu pohranu u ClickHouse, izabran je (golang).
Kao baza podataka za pohranu vremenskih serija izabran je poslednji stabilni release ClickHouse-a verzije 1.1.54253. Prilikom rada sa njim došlo je do problema: logovi su bili puni grešaka, i nije bilo baš jasno šta s njima raditi. U razgovoru sa (autor carbon-clickhouse, graphite-clickhouse i još mnogo, mnogo toga) izabran je stariji . Greške su nestale — sve je počelo savršeno raditi.
Za čitanje podataka iz ClickHouse-a izabran je (golang). Kao API interfejs za Graphite — (golang). Za organizaciju replikacije između tablica ClickHouse korišten je . Za usmjeravanje metrika ostavili smo naš omiljeni (C) .
Graphite+ClickHouse. Struktura tablica
“graphite” — baza podataka koju smo stvorili za tablice nadgledanja.
“graphite.metrics” — tablica s motorom ReplicatedReplacingMergeTree (replikativni ). U ovoj tablici pohranjuju se imena metrika i putanje 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” — tablica s motorom ReplicatedGraphiteMergeTree (replikativni ). U ovoj tablici pohranjuju se vrijednosti metrika.
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” — tablica koja se popunjava prema uvjetu, s motorom ReplicatedReplacingMergeTree. Ova tablica bilježi imena svih metrika koje su se pojavile tijekom dana. Razlozi stvaranja opisani su u odjeljku na kraju ovog č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” — tablica koja se popunjava prema uvjetu, s motorom ReplicatedAggregatingMergeTree (replikativni ). U ovu tablicu bilježi se broj dolaznih metrika, razvrstan do 4 razine dubine.
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 komponenti

Graphite+ClickHouse. Migracija podataka
Kao što se sjećamo iz očekivanja ovog projekta, prijelaz na ClickHouse trebao je biti bez zastoja, stoga smo morali na neki način prebaciti cijeli naš sustav nadgledanja na novu pohranu s maksimalnom transparentnošću za naše korisnike.
Učinili smo to na ovaj način.
U carbon-c-relay dodali smo pravilo za slanje dodatnog toka metrika u carbon-clickhouse jednog od servera koji sudjeluju u replikaciji ClickHouse tablica.
Napisali smo mali skript na Pythonu koji je pomoću biblioteke whisper-dump čitao sve .wsp datoteke iz našeg spremišta i slanja tih podataka u ranije opisani carbon-clickhouse u 24 niti. Broj primljenih mjernih vrijednosti u carbon-clickhouse postigao je 125 milijuna/min, a ClickHouse se čak nije ni znojio.
Izradili smo zasebni DataSource u Grafani s ciljem ispitivanja funkcionalnosti korištenih u postojećim kontrolnim pločama. Utvrdili smo popis funkcija koje koristimo, ali koje nisu bile implementirane u carbonapi. Dodali smo te funkcije i poslali PR-ove autorima carbonapi (njihove zahvalnice).
- Za prebacivanje čitanja opterećenja u postavkama uravnoteživača promijenili smo krajnje točke s graphite-api (API sučelje za Graphite+Whisper) na carbonapi.
Graphite+ClickHouse. Rezultati
smanjena iskorištenost diskovnog sustava sa 30% na 1%;

- smanjena veličina zauzetog prostora s 1 TB na 300 GB;
- imamo mogućnost primanja do 125 milijuna mjernih vrijednosti u minuti na server (vrhunac tijekom migracije);
- prebacili smo sve mjere na interval skladištenja od trideset sekundi;
- dobili smo replikaciju podataka i otpornost na kvarove;
- prebacili smo se bez vremena zastoja;
- za sve smo potrošli otprilike 7 tjedana.
Graphite+ClickHouse. Problemi
U našem slučaju, nije prošlo bez zamki. Ovo su s čime smo se susreli nakon prijelaza.
- ClickHouse ne čita uvijek konfiguracije u hodu, ponekad ga je potrebno ponovno pokrenuti. Na primjer, u slučaju opisa klastera zookeeper u konfiguraciji ClickHouse — nije se primjenjivao do ponovnog pokretanja clickhouse-servera.
- Veliki upiti nisu prolazili kroz ClickHouse, pa u našem graphite-clickhouse stringu za povezivanje s ClickHouse izgleda ovako:
url = "http://localhost:8123/?max_query_size=268435456&max_ast_elements=1000000" - U ClickHouse često dolaze nove verzije stabilnih izdanja, u njima mogu biti iznenađenja: budite oprezni.
- Dinamički stvoreni kontejneri u Kubernetesu šalju veliku količinu metrika s kratkim i nasumičnim vremenom trajanja. Broj točaka za takve metrike nije velik i nema problema s prostorom. No, prilikom izrade upita ClickHouse preuzima ogromnu količinu tih metrika iz tablice 'metrics'. U 90% slučajeva podaci za njih unutar vremenskog okvira (24 sata) nedostaju. Međutim, vrijeme provedeno u traženju tih podataka u tablici 'data' se potroši, što na kraju rezultira timeoutom. Kako bismo riješili ovaj problem, počeli smo održavati zaseban pregled s informacijama o metrama koje su se pojavile tijekom dana. Tako, prilikom izrade izvještaja (grafova) o dinamički stvorenim kontejnerima, interrogiramo samo one metrike koje su se pojavile unutar zadanog okvira, a ne za cijelo vrijeme, što je znatno ubrzalo kreiranje izvještaja o njima. Za ovo rješenje je prikupljen , uključujući implementaciju rada s tablicom date_metrics.
Graphite+ClickHouse. Oznake
Od verzije 1.1.0 Graphite je službeno . I aktivno razmišljamo o tome što i kako treba učiniti da bismo podržali ovu inicijativu u Graphite+ClickHouse stogu.
Graphite+ClickHouse. Detektor anomalija
Na temelju opisane infrastrukture, implementirali smo prototip detektora anomalija, i on radi! No, o njemu - u sljedećem članku.
Pretplatite se, pritisnite strelicu prema gore i budite sretni!
Izvor: habr.com

