Przechowywanie metryk: jak przeszliśmy z Graphite+Whisper na Graphite+ClickHouse

Cześć wszystkim! W jego ostatni artykuł Pisałem o zorganizowaniu modułowego systemu monitorowania dla architektury mikroserwisowej. Nic nie stoi w miejscu, nasz projekt stale się rozwija, a wraz z nim ilość przechowywanych metryk. Jak zorganizowaliśmy przejście z Graphite+Whisper na Graphite+ClickHouse w warunkach dużego obciążenia, przeczytaj o oczekiwaniach z nim związanych i efektach migracji pod cięciem.

Przechowywanie metryk: jak przeszliśmy z Graphite+Whisper na Graphite+ClickHouse

Zanim opowiem jak zorganizowaliśmy przejście z przechowywania metryk w Graphite+Whisper do Graphite+ClickHouse, chciałbym przekazać informację o powodach podjęcia takiej decyzji oraz o wadach Whisper, z którymi żyliśmy przez długi czas.

Problemy z grafitem i szeptem

1. Duże obciążenie podsystemu dyskowego

W momencie przejścia docierało do nas około 1.5 miliona wskaźników na minutę. Przy takim przepływie wykorzystanie dysku na serwerach wynosiło ~30%. Ogólnie rzecz biorąc, było to całkiem do zaakceptowania - wszystko działało stabilnie, było szybko pisane, szybko czytane... Dopóki jeden z zespołów programistycznych nie wprowadził nowej funkcji i nie zaczął wysyłać nam 10 milionów metryk na minutę. Wtedy podsystem dyskowy został wzmocniony i zaobserwowaliśmy 100% jego wykorzystania. Problem został szybko rozwiązany, ale pozostałości pozostały.

2. Brak replikacji i spójności

Najprawdopodobniej, podobnie jak wszyscy, którzy korzystają/używali Graphite+Whisper, przelaliśmy ten sam strumień metryk na kilka serwerów Graphite jednocześnie, aby zapewnić odporność na awarie. I nie było z tym żadnych specjalnych problemów - aż do momentu, gdy z jakiegoś powodu jeden z serwerów uległ awarii. Czasami udało nam się wystarczająco szybko podnieść uszkodzony serwer, a carbon-c-relay potrafił załadować do niego metryki ze swojej pamięci podręcznej, ale czasami nie. A potem pojawiła się luka w metrykach, którą wypełniliśmy rsync. Procedura była dość długa. Jedynym ratunkiem było to, że zdarzało się to bardzo rzadko. Okresowo pobieraliśmy także losowy zestaw metryk i porównywaliśmy je z innymi tego samego typu w sąsiednich węzłach klastra. W około 5% przypadków kilka wartości było odmiennych, z czego nie byliśmy zbyt zadowoleni.

3. Duża powierzchnia

Ponieważ w Graphite piszemy nie tylko metryki infrastrukturalne, ale także metryki biznesowe (a teraz także metryki z Kubernetesa), dość często spotykamy się z sytuacją, w której metryka zawiera tylko kilka wartości, a plik .wsp tworzony jest z uwzględnieniem wszystkich retencji okres i zajmuje wcześniej przydzieloną ilość miejsca, która dla nas wynosiła ~2MB. Problem pogłębia fakt, że z biegiem czasu podobnych plików pojawia się bardzo dużo, a przy budowaniu na ich podstawie raportów odczytywanie pustych punktów zajmuje dużo czasu i zasobów.

Od razu zaznaczę, że opisane powyżej problemy można leczyć różnymi metodami i z różną skutecznością, jednak im więcej danych zaczniesz otrzymywać, tym bardziej się one pogłębią.

Mając wszystkie powyższe (biorąc pod uwagę poprzednie Artykuł), a także stały wzrost liczby otrzymywanych metryk, chęć przeniesienia wszystkich metryk na interwał przechowywania wynoszący 30 sekund. (w razie potrzeby do 10 sekund) zdecydowaliśmy się wypróbować Graphite+ClickHouse jako obiecującą alternatywę dla Whisper.

Grafit+ClickHouse. Oczekiwania

Odwiedziłem kilka spotkań chłopaków z Yandex i przeczytałem kilka artykułów na temat Habré, po przejrzeniu dokumentacji i znalezieniu rozsądnych komponentów do powiązania ClickHouse pod Graphite, zdecydowaliśmy się podjąć działania!

Chciałbym otrzymać następujące informacje:

  • zmniejszyć wykorzystanie podsystemu dyskowego z 30% do 5%;
  • zmniejszyć ilość zajmowanego miejsca z 1 TB do 100 GB;
  • móc odbierać na serwer 100 milionów metryk na minutę;
  • replikacja danych i odporność na błędy od razu po wyjęciu z pudełka;
  • nie siedź nad tym projektem przez rok i dokonaj przejścia w rozsądnym terminie;
  • przełączać bez przestojów.

Całkiem ambitne, prawda?

Grafit+ClickHouse. składniki

Aby otrzymać dane poprzez protokół Graphite, a następnie zapisać je w ClickHouse, wybrałem klikhouse z włókna węglowego (golang).

Jako bazę danych do przechowywania szeregów czasowych wybrano najnowszą wersję ClickHouse, stabilną wersję 1.1.54253. Podczas pracy z nim pojawiały się problemy: do dzienników wlewała się góra błędów i nie było do końca jasne, co z nimi zrobić. W dyskusji z Roman Łomonosow (autor carbon-clickhouse, graphite-clickhouse i wielu, wielu innych) wybrano ten starszy wydanie 1.1.54236. Błędy zniknęły - wszystko zaczęło działać z hukiem.

Wybrany do odczytu danych z ClickHouse grafit-lickhouse (golang). Jako API dla Graphite − karbonapi (golang). Do zorganizowania replikacji pomiędzy tabelami wykorzystano ClickHouse dozorca zoo. Dla metryk routingu zostawiliśmy naszego ukochanego przekaźnik węglowy-c (C) (zobacz poprzedni artykuł).

Grafit+ClickHouse. Struktura tabeli

„grafit” to baza danych, którą stworzyliśmy dla tabel monitorujących.

„graphite.metrics” - tabela z silnikiem ReplicatedReplacingMergeTree (replikowana ZastępowanieMergeTree). W tej tabeli przechowywane są nazwy metryk i ścieżki do nich.

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 silnikiem ReplicatedGraphiteMergeTree (replikacja Drzewo GraphiteMerge). Ta tabela przechowuje wartości metryczne.

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” to tabela wypełniona warunkowo z silnikiem ReplicatedReplacingMergeTree. W tej tabeli rejestrowane są nazwy wszystkich metryk napotkanych w ciągu dnia. Powody jego powstania opisano w sekcji „Problemy” na końcu tego artykułu.

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 wypełniona według warunku, z silnikiem ReplicatedAggregatingMergeTree (replikowana AgregowanieMergeTree). Ta tabela rejestruje liczbę przychodzących metryk w podziale na 4 poziomy zagnieżdżenia.

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. Schemat interakcji komponentów

Przechowywanie metryk: jak przeszliśmy z Graphite+Whisper na Graphite+ClickHouse

Grafit+ClickHouse. Migracja danych

Jak pamiętamy z oczekiwań związanych z tym projektem, przejście na ClickHouse powinno przebiegać bez przestojów, w związku z tym musieliśmy w jakiś sposób przełączyć cały nasz system monitorowania na nowy magazyn w sposób możliwie przejrzysty dla naszych użytkowników.
W ten sposób to zrobiliśmy.

  • Do carbon-c-relay została dodana reguła wysyłająca dodatkowy strumień metryk do carbon-clickhouse jednego z serwerów biorących udział w replikacji tabel ClickHouse.

  • Napisaliśmy mały skrypt w Pythonie, który korzystając z biblioteki whistle-dump, odczytał wszystkie pliki .wsp z naszej pamięci i wysłał te dane do opisanego powyżej carbon-clickhouse w 24 wątkach. Liczba akceptowanych wartości metrycznych w carbon-clickhouse osiągnęła 125 milionów/min, a ClickHouse nawet się nie spocił.

  • Stworzyliśmy osobne DataSource w Grafanie, aby debugować funkcje używane w istniejących dashboardach. Zidentyfikowaliśmy listę funkcji, z których korzystaliśmy, ale nie zostały one zaimplementowane w carbonapi. Dodaliśmy te funkcje i wysłaliśmy PR-y do autorów carbonapi (dla nich szczególne podziękowania).

  • Aby przełączyć obciążenie odczytu w ustawieniach balansera, zmieniliśmy punkty końcowe z graphite-api (interfejs API dla Graphite+Whisper) na carbonapi.

Grafit+ClickHouse. wyniki

  • zmniejszone wykorzystanie podsystemu dyskowego z 30% do 1%;

    Przechowywanie metryk: jak przeszliśmy z Graphite+Whisper na Graphite+ClickHouse

  • zmniejszono ilość zajmowanego miejsca z 1 TB do 300 GB;
  • mamy możliwość przyjmowania na serwer 125 milionów metryk na minutę (szczyt w momencie migracji);
  • przeniósł wszystkie metryki do trzydziestosekundowego interwału przechowywania;
  • replikacja otrzymanych danych i odporność na błędy;
  • przełączane bez przestojów;
  • Ukończenie wszystkiego zajęło około 7 tygodni.

Grafit+ClickHouse. Problemy

W naszym przypadku było kilka pułapek. Z tym właśnie mieliśmy do czynienia po przejściu.

  1. ClickHouse nie zawsze ponownie odczytuje konfiguracje w locie; czasami trzeba go zrestartować. Przykładowo, w przypadku opisu klastra zookeepera w konfiguracji ClickHouse, nie był on używany do czasu ponownego uruchomienia serwera Clickhouse.
  2. Duże żądania ClickHouse nie zostały zrealizowane, więc w graphite-clickhouse nasz ciąg połączenia ClickHouse wygląda następująco:
    url = "http://localhost:8123/?max_query_size=268435456&max_ast_elements=1000000"
  3. ClickHouse dość często wydaje nowe wersje wydań stabilnych, mogą one zawierać niespodzianki: bądź ostrożny.
  4. Dynamicznie tworzone kontenery w Kubernetes wysyłają dużą liczbę metryk z krótkim i losowym czasem życia. Za takie metryki nie ma zbyt wielu punktów i nie ma problemów z przestrzenią. Ale podczas tworzenia zapytań ClickHouse pobiera ogromną liczbę tych samych danych z tabeli „metryki”. W 90% przypadków nie ma o nich żadnych danych poza oknem (24 godziny). Jednak czas poświęcany jest na wyszukiwanie tych danych w tabeli „dane”, co ostatecznie kończy się przekroczeniem limitu czasu. Aby rozwiązać ten problem, zaczęliśmy utrzymywać osobny widok z informacjami o metrykach, które napotkaliśmy w ciągu dnia. Tym samym budując raporty (wykresy) dla dynamicznie tworzonych kontenerów odpytujemy tylko te metryki, które napotkaliśmy w danym oknie, a nie za cały czas, co znacząco przyspieszyło budowę raportów na ich temat. Dla rozwiązania opisanego powyżej zebrałem grafit-clickhouse (widelec), co obejmuje implementację pracy z tabelą date_metrics.

Grafit+ClickHouse. Tagi

Wraz z wersją 1.1.0 Graphite stał się oficjalny znaczniki wsparcia. Aktywnie zastanawiamy się, co i jak zrobić, aby wesprzeć tę inicjatywę w stosie graphite+clickhouse.

Grafit+ClickHouse. Detektor anomalii

W oparciu o opisaną powyżej infrastrukturę wdrożyliśmy prototyp detektora anomalii i działa! Ale o nim więcej w następnym artykule.

Subskrybuj, naciśnij strzałkę w górę i bądź szczęśliwy!

Źródło: www.habr.com

Dodaj komentarz