Bioyino – distribuovaný, škálovatelný agregátor metrik

Takže sbíráte metriky. Tak jak jsme my. Sbíráme také metriky. Samozřejmě nutné pro podnikání. Dnes si povíme o úplně prvním článku našeho monitorovacího systému – agregačním serveru kompatibilním se statsd bioyino, proč jsme to napsali a proč jsme opustili brubeck.

Bioyino – distribuovaný, škálovatelný agregátor metrik

Z našich předchozích článků (1, 2) můžete zjistit, že do určité doby jsme sbírali známky pomocí Brubeck. Je napsán v C. Z hlediska kódu je jednoduchý jako plug (to je důležité, když chcete přispět) a hlavně zvládá naše objemy 2 miliony metrik za sekundu (MPS) ve špičce bez problémů. Dokumentace uvádí podporu pro 4 miliony MPS s hvězdičkou. To znamená, že uvedený údaj získáte, pokud správně nakonfigurujete síť v Linuxu. (Nevíme, kolik MPS můžete získat, pokud síť ponecháte tak, jak je). Navzdory těmto výhodám jsme měli několik vážných stížností na brubeck.

Nárok 1. Github, vývojář projektu, jej přestal podporovat: zveřejňovat záplaty a opravy, přijímat naše a (nejen naše) PR. V posledních měsících (někde od února-března 2018) se činnost obnovila, ale předtím byl téměř 2 roky naprostý klid. Kromě toho se projekt připravuje pro interní potřeby Gihubu, což se může stát vážnou překážkou zavádění nových funkcí.

Nárok 2. Přesnost výpočtů. Brubeck shromažďuje celkem 65536 hodnot pro agregaci. V našem případě může pro některé metriky během období agregace (30 sekund) přijít mnohem více hodnot (1 527 392 ve špičce). V důsledku tohoto vzorkování se maximální a minimální hodnoty zdají být zbytečné. Například takto:

Bioyino – distribuovaný, škálovatelný agregátor metrik
Tak jak to bylo

Bioyino – distribuovaný, škálovatelný agregátor metrik
Jak to mělo být

Ze stejného důvodu se částky obecně počítají nesprávně. Přidejte sem chybu s 32bitovým plovoucím přetečením, které obecně pošle server do segfaultu, když obdrží zdánlivě nevinnou metriku, a vše bude skvělé. Chyba mimochodem nebyla opravena.

A konečně, Nárok X. V době psaní tohoto článku jsme připraveni jej představit všem 14 více či méně fungujícím implementacím statsd, které se nám podařilo najít. Představme si, že se nějaká jednotlivá infrastruktura rozrostla natolik, že přijmout 4 miliony MPS už nestačí. Nebo i když ještě nerostl, ale metriky jsou pro vás již tak důležité, že i krátké, 2-3minutové poklesy v grafech se již mohou stát kritickými a způsobit záchvaty nepřekonatelné deprese mezi manažery. Protože léčba deprese je nevděčný úkol, jsou zapotřebí technická řešení.

Za prvé, odolnost proti chybám, aby náhlý problém na serveru nezpůsobil v kanceláři psychiatrickou zombie apokalypsu. Zadruhé, škálování tak, aby bylo možné přijmout více než 4 miliony MPS, aniž byste se museli vrtat hluboko do linuxového síťového zásobníku a klidně narůstat „do šířky“ na požadovanou velikost.

Protože jsme měli prostor pro škálování, rozhodli jsme se začít s odolností proti chybám. "O! Odolnost proti chybám! Je to jednoduché, zvládneme to,“ pomysleli jsme si a spustili 2 servery a na každém jsme zvedli kopii brubecku. Abychom toho dosáhli, museli jsme zkopírovat provoz s metrikami na oba servery a dokonce pro to psát malá užitečnost. Vyřešili jsme tím problém s tolerancí chyb, ale... ne moc dobře. Zpočátku se vše zdálo skvělé: každý brubeck shromažďuje svou vlastní verzi agregace, zapisuje data do Graphite každých 30 sekund, přičemž přepisuje starý interval (to se provádí na straně Graphite). Pokud jeden server náhle selže, máme vždy druhý s vlastní kopií agregovaných dat. Ale tady je problém: pokud server selže, na grafech se objeví „pila“. Důvodem je skutečnost, že brubeckovy 30sekundové intervaly nejsou synchronizovány a v okamžiku havárie se jeden z nich nepřepíše. Když se spustí druhý server, stane se to samé. Docela snesitelné, ale chci lepší! Problém škálovatelnosti také nezmizel. Všechny metriky stále „létají“ na jeden server, a proto jsme omezeni na stejné 2–4 miliony MPS, v závislosti na úrovni sítě.

Pokud se nad problémem trochu zamyslíte a zároveň lopatou odkopáváte sníh, může vás napadnout následující zřejmá myšlenka: potřebujete statsd, který umí pracovat v distribuovaném režimu. Tedy takový, který implementuje synchronizaci mezi uzly v čase a metrikách. „Samozřejmě, že takové řešení pravděpodobně již existuje,“ řekli jsme a šli do Googlu…. A nic nenašli. Po procházení dokumentace pro různé statsd (https://github.com/etsy/statsd/wiki#server-implementations k 11.12.2017. prosinci XNUMX) jsme nenašli absolutně nic. Zřejmě se vývojáři ani uživatelé těchto řešení ještě nesetkali s TOLIK metrikami, jinak by určitě něco vymysleli.

A pak jsme si vzpomněli na „hračku“ statsd - bioyino, která byla napsána na hackathonu Just for Fun (název projektu vygeneroval skript před začátkem hackathonu) a uvědomili jsme si, že nutně potřebujeme vlastní statsd. Proč?

  • protože na světě je příliš málo statsd klonů,
  • protože je možné poskytnout požadovanou nebo blízkou požadované odolnosti proti chybám a škálovatelnosti (včetně synchronizace agregovaných metrik mezi servery a řešení problému odesílání konfliktů),
  • protože je možné vypočítat metriky přesněji než brubeck,
  • protože si můžete sami sbírat podrobnější statistiky, které nám brubeck prakticky neposkytl,
  • protože jsem měl šanci naprogramovat si vlastní hypervýkonnou laboratorní aplikaci v distribuovaném měřítku, která nebude úplně opakovat architekturu jiného podobného hyperforu... no, to je vše.

Na co psát? Samozřejmě v Rustu. Proč?

  • protože již existovalo prototypové řešení,
  • protože autor článku už v té době Rust znal a měl chuť do něj něco napsat do výroby s možností dát to do open-source,
  • protože jazyky s GC pro nás nejsou vhodné kvůli povaze přijímaného provozu (téměř v reálném čase) a GC pauzy jsou prakticky nepřijatelné,
  • protože potřebujete maximální výkon srovnatelný s C
  • protože Rust nám poskytuje neohroženou souběžnost, a kdybychom jej začali psát v C/C++, shrabali bychom ještě více zranitelností, přetečení bufferu, rasových podmínek a dalších děsivých slov než brubeck.

Objevil se i argument proti Rustovi. Společnost neměla žádné zkušenosti s vytvářením projektů v Rustu a nyní je také neplánujeme použít v hlavním projektu. Byly proto vážné obavy, že nic nevyjde, ale rozhodli jsme se riskovat a zkusili jsme to.

Čas vypršel...

Konečně, po několika neúspěšných pokusech, byla první pracovní verze hotová. Co se stalo? Tohle se stalo.

Bioyino – distribuovaný, škálovatelný agregátor metrik

Každý uzel přijímá svou vlastní sadu metrik a shromažďuje je a neshromažďuje metriky pro ty typy, kde je pro konečnou agregaci vyžadována jejich úplná sada. Uzly jsou mezi sebou propojeny jakýmsi distribuovaným zámkovým protokolem, který vám umožňuje vybrat mezi nimi ten jediný (tady jsme plakali), který je hoden zaslání metrik Velkému. Tento problém je v současné době řešen společností Konzul, ale do budoucna autorovy ambice sahají až do vlastní implementace Voru, kde ten nejhodnější bude samozřejmě vedoucím uzlem konsensu. Kromě konsensu uzly poměrně často (ve výchozím nastavení jednou za sekundu) posílají svým sousedům ty části předem agregovaných metrik, které se jim podařilo shromáždit za tuto sekundu. Ukazuje se, že škálování a odolnost proti chybám jsou zachovány – každý uzel stále obsahuje úplnou sadu metrik, ale metriky jsou odesílány již agregované, přes TCP a zakódované do binárního protokolu, takže náklady na duplikaci jsou ve srovnání s UDP výrazně sníženy. Navzdory poměrně velkému počtu příchozích metrik vyžaduje akumulace velmi málo paměti a ještě méně CPU. Pro naše vysoce komprimovatelné mertics je to jen několik desítek megabajtů dat. Jako další bonus nezískáme žádné zbytečné přepisy dat v Graphite, jako tomu bylo u burbecku.

Pakety UDP s metrikami jsou nevyvážené mezi uzly na síťovém zařízení prostřednictvím jednoduchého Round Robin. Síťový hardware samozřejmě neanalyzuje obsah paketů, a proto může tahat mnohem více než 4M paketů za sekundu, nemluvě o metrikách, o kterých neví vůbec nic. Pokud vezmeme v úvahu, že metriky nepřicházejí jedna po druhé v každém paketu, pak v tomto místě nepředpokládáme žádné problémy s výkonem. Pokud dojde k havárii serveru, síťové zařízení tuto skutečnost rychle (během 1-2 sekund) zjistí a vyřadí havarovaný server z rotace. V důsledku toho lze pasivní (tj. nevedoucí) uzly zapínat a vypínat prakticky bez zaznamenávání čerpání na grafech. Maximum, které ztratíme, je součástí metrik, které se objevily v poslední vteřině. Náhlá ztráta/vypnutí/přepnutí lídra stále vytvoří menší anomálii (30 sekundový interval je stále nesynchronizovaný), ale pokud mezi uzly probíhá komunikace, lze tyto problémy minimalizovat například rozesíláním synchronizačních paketů .

Něco málo o vnitřní struktuře. Aplikace je samozřejmě vícevláknová, ale architektura vláken je odlišná od architektury používané v brubecku. Vlákna v brubecku jsou stejná – každé z nich je zodpovědné za sběr i agregaci informací. V bioyino jsou pracovníci rozděleni do dvou skupin: na ty, kteří jsou zodpovědní za síť, a na ty, kteří jsou zodpovědní za agregaci. Toto rozdělení umožňuje flexibilněji spravovat aplikaci v závislosti na typu metrik: tam, kde je vyžadována intenzivní agregace, můžete přidat agregátory, kde je velký síťový provoz, můžete přidat počet síťových toků. V současné době na našich serverech pracujeme v 8 síťových a 4 agregačních tocích.

Část sčítání (odpovědná za agregaci) je docela nudná. Vyrovnávací paměti naplněné síťovými toky jsou distribuovány mezi počítací toky, kde jsou následně analyzovány a agregovány. Na vyžádání jsou uvedeny metriky pro odeslání do jiných uzlů. To vše včetně odesílání dat mezi uzly a práce s Consul probíhá asynchronně, běží na frameworku Tokio.

Mnohem více problémů při vývoji způsobila síťová část zodpovědná za příjem metrik. Hlavním cílem oddělení síťových toků do samostatných entit bylo přání zkrátit čas, který tok stráví ne pro čtení dat ze zásuvky. Možnosti využívající asynchronní UDP a pravidelné recvmsg rychle zmizely: první spotřebovává příliš mnoho CPU v uživatelském prostoru pro zpracování událostí, druhé vyžaduje příliš mnoho kontextových přepínačů. Proto se nyní používá recvmmsg s velkými nárazníky (a nárazníky, pánové důstojníci, nejsou nic pro vás!). Podpora běžného UDP je vyhrazena pro lehké případy, kdy recvmmsg není potřeba. V režimu multimessage je možné dosáhnout toho hlavního: v drtivé většině času síťové vlákno rake frontu OS - čte data ze socketu a přenáší je do vyrovnávací paměti uživatelského prostoru, jen občas přepne na předání naplněného bufferu agregátory. Fronta v socketu se prakticky nehromadí, počet zahozených paketů prakticky neroste.

Poznámka

Ve výchozím nastavení je velikost vyrovnávací paměti nastavena na poměrně velkou. Pokud se náhle rozhodnete server vyzkoušet sami, můžete se setkat s tím, že po odeslání malého počtu metrik nedorazí do Graphite a zůstanou ve vyrovnávací paměti síťového streamu. Chcete-li pracovat s malým počtem metrik, musíte v konfiguraci nastavit velikost bufsize a task-queue-size na menší hodnoty.

Na závěr pár žebříčků pro milovníky žebříčků.

Statistiky o počtu příchozích metrik pro každý server: více než 2 miliony MPS.

Bioyino – distribuovaný, škálovatelný agregátor metrik

Deaktivace jednoho z uzlů a přerozdělení příchozích metrik.

Bioyino – distribuovaný, škálovatelný agregátor metrik

Statistiky odchozích metrik: vždy posílá pouze jeden uzel – raid boss.

Bioyino – distribuovaný, škálovatelný agregátor metrik

Statistika provozu každého uzlu s přihlédnutím k chybám v různých modulech systému.

Bioyino – distribuovaný, škálovatelný agregátor metrik

Podrobnosti o příchozích metrikách (názvy metrik jsou skryté).

Bioyino – distribuovaný, škálovatelný agregátor metrik

Co s tím vším plánujeme dál? Samozřejmě, pište kód, sakra...! Projekt byl původně plánován jako open-source a takový zůstane po celou dobu své existence. Mezi naše nejbližší plány patří přechod na vlastní verzi Raftu, změna rovnocenného protokolu na přenosnější, zavedení dalších interních statistik, nové typy metrik, opravy chyb a další vylepšení.

Samozřejmě je vítán každý, kdo pomůže s rozvojem projektu: vytvořte PR, Issues, pokud to bude možné, odpovíme, zlepšíme atd.

Když už bylo řečeno, to je vše, lidi, kupte si naše slony!



Zdroj: www.habr.com

Přidat komentář