Захоўванне метрык: як мы перайшлі з Graphite+Whisper на Graphite+ClickHouse

Ўсім прывітанне! У сваёй мінулым артыкуле я пісаў аб арганізацыі модульнай сістэмы маніторынгу для мікрасэрвіснай архітэктуры. Нічога не варта на месцы, наш праект увесь час расце, і колькасць захоўваемых метрык – таксама. Як мы арганізавалі пераход з Graphite+Whisper на Graphite+ClickHouse ва ўмовах высокіх нагрузак, пра чаканні ад яго і вынікі міграцыі чытайце пад катом.

Захоўванне метрык: як мы перайшлі з Graphite+Whisper на Graphite+ClickHouse

Перш чым я раскажу, як мы арганізавалі пераход ад захоўвання метрык у Graphite+Whisper на Graphite+ClickHouse, хацелася б даць інфармацыю аб прычынах прыняцця падобнага рашэння і аб тых мінусах Whisper, з якімі мы жылі на працягу працяглага часу.

Праблемы Graphite+Whisper

1. Высокая нагрузка на дыскавую падсістэму

На момант пераходу да нас прылятала прыкладна 1.5 млн. метрык у хвіліну. З такой плынню дыскавая ўтылізацыя на серверах была роўная ~30%. У цэлым гэта было цалкам прымальна - усё працавала стабільна, хутка пісалася, хутка чыталася ... Да таго моманту, пакуль адна з каманд распрацоўкі не выкаціла новую фічу і не стала адпраўляць нам 10 млн метрык у хвіліну. Вось тады-то дыскавая падсістэма паднапружылася, і мы ўбачылі 100% утылізацыі. Праблему ўдалося хутка вырашыць, але асадак застаўся.

2. Адсутнасць рэплікацыі і кансістэнтнасці

Хутчэй за ўсё як і ўсе, хто выкарыстоўвае/выкарыстоўваў Graphite+Whisper, мы лілі аднолькавы струмень метрык адразу на некалькі сервераў Graphite з мэтай стварэння адмоваўстойлівасці. І з гэтым асаблівых праблем не было - да моманту, калі адзін з сервераў па якой-небудзь прычыне не падаў. Часам мы паспявалі падняць які ўпаў сервер досыць хутка, і carbon-c-relay паспяваў заліваць у яго метрыкі са свайго кэша, а часам няма. І тады ў метрыках была дзірка, якую мы зацягвалі rsync`ом. Працэдура была дастаткова доўгай. Ратавала толькі тое, што адбывалася падобнае вельмі рэдка. Таксама мы перыядычна бралі рандомны набор метрык і параўноўвалі іх іншымі такімі ж на суседніх нодах кластара. Прыкладна ў 5% выпадкаў некалькі значэнняў адрозніваліся, што нас не вельмі цешыла.

3. Вялікі аб'ём займанага месца

Бо мы пішам у Graphite не толькі інфраструктурныя, але і бізнэс-метрыкі (а зараз яшчэ і метрыкі з Kubernetes), то даволі часта атрымліваем сітуацыю, пры якой у метрыцы прысутнічаюць толькі некалькі значэнняў, а .wsp-файл ствараецца з улікам усяго retention перыяду, і займае прадвыдзелены аб'ём месца, які ў нас быў роўны ~2Мб. Праблема пагаршаецца яшчэ і тым, што падобных файлаў з часам з'яўляецца вельмі шмат, і пры пабудове справаздач па іх на чытанне пустых кропак сыходзіць шмат часу і рэсурсаў.

Адразу жадалася б адзначыць што з праблемамі, апісанымі вышэй, можна дужацца рознымі метадамі і з рознай ступенню эфектыўнасці, але чым больш да вас пачынае паступаць дадзеных, тым мацней яны абвастраюцца.

Маючы ўсё вышэйпералічанае (з улікам папярэдняй артыкулы), а таксама пастаянны рост колькасці атрымоўваных метрык, жаданне перавесці ўсе метрыкі да інтэрвалу захоўвання ў 30 сек. (пры неабходнасці – да 10 сек.), мы вырашылі паспрабаваць Graphite+ClickHouse у якасці перспектыўнай альтэрнатывы Whisper.

Graphite+ClickHouse. Чаканні

Наведаўшы некалькі мітапаў рабят з Яндэкса, прачытаўшы пару артыкулаў на Хабры, Прашэрсціўшы дакументацыю і знайшоўшы разумныя кампаненты для абвязкі ClickHouse пад Graphite, мы вырашылі дзейнічаць!

Жадалася атрымаць наступнае:

  • знізіць утылізацыю дыскавай падсістэмы з 30% да 5%;
  • зменшыць аб'ём займанага месца з 1Тб да 100Гб;
  • мець магчымасць прымаць па 100 млн метрык у хвіліну ў сервер;
  • рэплікацыю дадзеных і адмоваўстойлівасць са скрынкі;
  • не сядзець над гэтым праектам год і зрабіць пераход за нейкі разумны тэрмін;
  • пераключыцца без даунтайма.

Досыць амбіцыйна, праўда?

Graphite+ClickHouse. Кампаненты

Для атрымання дадзеных па пратаколе Graphite і наступнага запісу іх у ClickHouse, быў абраны carbon-clickhouse (golang).

У якасці базы дадзеных для захоўвання часавых шэрагаў быў абраны апошні на той момант рэліз ClickHouse стабільнай версіі 1.1.54253. Пры працы з ім былі праблемы: у логі сыпала гару памылак, і было не зусім зразумела што з імі рабіць. У абмеркаванні з Раманам Ламаносавым (аўтар carbon-clickhouse, graphite-clickhouse і яшчэ шмат чаго) быў абраны больш стары рэліз 1.1.54236. Памылкі зніклі - усё стала працаваць на ўра.

Для чытання дадзеных з ClickHouse быў абраны graphite-сlickhouse (golang). У якасці API-інтэрфейсу для Graphite carbonapi (golang). Для арганізацыі рэплікацыі паміж табліцамі ClickHouse быў скарыстаны Zookeeper. Для маршрутызацыі метрык мы пакінулі намі горача каханы carbon-c-relay (с) (гл. мінулую артыкул).

Graphite+ClickHouse. Структура табліц

"graphite" - база дадзеных, створаная намі для табліц маніторынгу.

"graphite.metrics" - табліца з рухавіком ReplicatedReplacingMergeTree (рэпліцыруемы ReplacingMergeTree). У дадзенай табліцы захоўваюцца імёны метрык і шляхі да іх.

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" – табліца з рухавіком ReplicatedGraphiteMergeTree (рэпліцыруемы GraphiteMergeTree). У дадзенай табліцы захоўваюцца значэнні метрык.

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" – табліца, якая запаўняецца па ўмове, з рухавіком ReplicatedReplacingMergeTree. У гэтую табліцу запісваюцца імёны ўсіх метрыкі, якія сустрэліся за суткі. Прычыны стварэння апісаны ў раздзеле "Праблемы" у канцы гэтага артыкула.

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" - табліца, якая запаўняецца па ўмове, з рухавіком ReplicatedAggregatingMergeTree (рэпліцыруемы AggregatingMergeTree). У гэтую табліцу запісваецца колькасць уваходных метрык, з разбіўкай да 4 ўзроўню ўкладзенасці.

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. Схема ўзаемадзеяння кампанентаў

Захоўванне метрык: як мы перайшлі з Graphite+Whisper на Graphite+ClickHouse

Graphite+ClickHouse. Міграцыя дадзеных

Як мы памятаем з чаканняў ад дадзенага праекту, пераход на ClickHouse павінен быць без даунтаймаў, адпаведна, мы павінны былі нейкім чынам пераключыць усю нашу сістэму маніторынгу на новае сховішча максімальна празрыста для нашых карыстачоў.
Зрабілі мы гэта так.

  • У carbon-c-relay дадалі правіла адпраўляць дадатковы паток метрык у carbon-clickhouse аднаго з сервераў, якія ўдзельнічаюць у рэплікацыі ClickHouse табліц.

  • Напісалі невялікі скрыпт на python, які з дапамогай бібліятэкі whisper-dump вычытваў усе .wsp-файлы з нашага сховішча і адпраўляў гэтыя дадзеныя ў вышэйапісаны carbon-clickhouse у 24 струмені. Колькасць прыманых значэнняў метрык у carbon-clickhouse, дасягала ў 125 млн/мін., і ClickHouse нават не змакрэў.

  • Стварылі асобны DataSource у Grafana з мэтай адладкі функцый, якія выкарыстоўваюцца ў існуючых дашбордах. Выявілі спіс функцый, якія мы выкарыстоўвалі, але яны не былі рэалізаваны ў carbonapi. Дапісалі гэтыя функцыі, і адправілі PR`ы аўтарам carbonapi (асобны ім дзякуй).

  • Для пераключэння якая чытае нагрузкі ў наладах балансавальнікаў змянілі эндпаінты з graphite-api (API інтэрфейс для Graphite+Whisper) на carbonapi.

Graphite+ClickHouse. Вынікі

  • знізілі ўтылізацыю дыскавай падсістэмы з 30% да 1%;

    Захоўванне метрык: як мы перайшлі з Graphite+Whisper на Graphite+ClickHouse

  • знізілі аб'ём займанага месца з 1 Тб да 300 Гб;
  • маем магчымасць прымаць па 125 млн метрык у хвіліну ў сервер (пікі ў момант міграцыі);
  • перавялі ўсе метрыкі на трыццацісекундны інтэрвал захоўвання;
  • атрымалі рэплікацыю дадзеных і адмоваўстойлівасць;
  • пераключыліся без даунтайма;
  • на ўсё выдаткавалі прыкладна 7 тыдняў.

Graphite+ClickHouse. Праблемы

У нашым выпадку не абышлося і без падводных камянёў. Вось з чым мы сутыкнуліся пасля пераходу.

  1. ClickHouse не заўсёды перачытвае канфігі на лета, часам яго трэба перазагружаць. Да прыкладу, у выпадку з апісаннем кластара zookeeper у канфігу ClickHouse – ён не ўжываўся да перазагрузкі clickhouse-server.
  2. Не праходзілі вялікія запыты ClickHouse, таму ў нас у graphite-clickhouse радок падключэння да ClickHouse выглядае вось так:
    url = "http://localhost:8123/?max_query_size=268435456&max_ast_elements=1000000"
  3. У ClickHouse даволі часта выходзяць новыя версіі стабільных рэлізаў, у іх могуць сустрэцца неспадзеўкі: будзьце ўважлівыя.
  4. Дынамічна ствараныя кантэйнеры ў kubernetes адпраўляюць вялікую колькасць метрык з кароткім і выпадковым перыядам жыцця. Пунктаў па такіх метрыках не шмат, і праблем з месцам няма. Але вось пры пабудове запытаў ClickHouse паднімае велізарную колькасць гэтых самых метрык з табліцы 'metrics'. У 90% выпадкаў дадзеныя па іх за акно (24 гадзіны) адсутнічаюць. А вось час на пошук гэтых дадзеных у табліцы 'data' затрачваецца, і ў канчатковым рахунку ўпіраецца ў таймаўт. Для таго, каб вырашыць гэтую праблему, мы сталі весці асобную юшку з інфармацыяй па метрыках, якія сустрэліся за суткі. Такім чынам, пры пабудове справаздач (графікаў) па дынамічна ствараных кантэйнерах, мы апытваем толькі тыя метрыкі, якія сустракаліся ў межах зададзенага акна, а не за ўвесь час, што ў разы паскорыла пабудову справаздач па іх. Для вышэйапісанага рашэння быў сабраны graphite-clickhouse (fork), улучальны рэалізацыю працы з табліцай date_metrics.

Graphite+ClickHouse. Тэгі

З версіі 1.1.0 Graphite стаў афіцыйна падтрымліваць тэгі. І мы актыўна думаем над тым, што і як трэба зрабіць, каб падтрымаць гэтую ініцыятыву ў стэку graphite+clickhouse.

Graphite+ClickHouse. Дэтэктар анамалій

На базе апісанай вышэй інфраструктуры, мы рэалізавалі прататып дэтэктара анамалій, і ён працуе! Але пра яго - у наступным артыкуле.

Падпісвайцеся, цісніце стрэлку уверх і будзьце шчаслівыя!

Крыніца: habr.com

Дадаць каментар