Bioyino - distribuirani, skalabilni agregator metrika

Dakle, prikupljate metriku. Kao što jesmo. Takođe prikupljamo metriku. Naravno, neophodno za poslovanje. Danas ćemo govoriti o prvoj vezi našeg sistema za praćenje - statsd-kompatibilnom serveru za agregaciju bioyino, zašto smo to napisali i zašto smo napustili Brubeck.

Bioyino - distribuirani, skalabilni agregator metrika

Iz naših prethodnih članaka (1, 2) možete saznati da smo do nekog vremena prikupljali ocjene koristeći Brubeck. Napisan je u C. Sa stanovišta koda, jednostavan je kao priključak (ovo je važno kada želite da doprinesete) i, što je najvažnije, obrađuje naše količine od 2 miliona metrika u sekundi (MPS) na vrhuncu bez ikakvih problema. U dokumentaciji je navedena podrška za 4 miliona MPS sa zvjezdicom. To znači da ćete dobiti navedenu cifru ako ispravno konfigurirate mrežu na Linuxu. (Ne znamo koliko MPS-a možete dobiti ako ostavite mrežu kakva jeste). Uprkos ovim prednostima, imali smo nekoliko ozbiljnih pritužbi na Brubeck.

Tvrdnja 1. Github, programer projekta, prestao ga je podržavati: objavljivati ​​zakrpe i popravke, prihvaćajući naš i (ne samo naš) PR. U posljednjih nekoliko mjeseci (negdje od februara-marta 2018.) aktivnost je nastavljena, ali prije toga je bilo skoro 2 godine potpunog zatišja. Osim toga, projekat je u izradi za interne potrebe Gihub-a, što može postati ozbiljna prepreka za uvođenje novih funkcija.

Tvrdnja 2. Tačnost proračuna. Brubeck prikuplja ukupno 65536 vrijednosti za agregaciju. U našem slučaju, za neke metrike, tokom perioda agregacije (30 sekundi), može doći mnogo više vrijednosti (1 na vrhuncu). Kao rezultat ovog uzorkovanja, maksimalne i minimalne vrijednosti su beskorisne. Na primjer, ovako:

Bioyino - distribuirani, skalabilni agregator metrika
Kao što je bilo

Bioyino - distribuirani, skalabilni agregator metrika
Kako je trebalo biti

Iz istog razloga, iznosi se uglavnom pogrešno izračunavaju. Dodajte ovdje grešku sa 32-bitnim float overflowom, koji generalno šalje server na segfault kada primi naizgled nevinu metriku, i sve postaje odlično. Bug, inače, nije ispravljen.

I, konačno, Zahtev X. U vrijeme pisanja, spremni smo ga predstaviti na svih 14 manje-više radnih statsd implementacija koje smo uspjeli pronaći. Zamislimo da je neka pojedinačna infrastruktura toliko narasla da prihvatanje 4 miliona MPS više nije dovoljno. Ili čak i ako još nije narastao, ali su vam metrike već toliko važne da čak i kratki, 2-3 minute padovi na grafikonima već mogu postati kritični i uzrokovati napade nepremostive depresije među menadžerima. Budući da je liječenje depresije nezahvalan zadatak, potrebna su tehnička rješenja.

Prvo, tolerancija grešaka, tako da iznenadni problem na serveru ne izazove psihijatrijsku zombi apokalipsu u kancelariji. Drugo, skaliranje da bi se moglo prihvatiti više od 4 miliona MPS, bez kopanja duboko u Linux mrežni stog i mirnog rasta "u širinu" do potrebne veličine.

Pošto smo imali prostora za skaliranje, odlučili smo da počnemo sa tolerancijom grešaka. „O! Tolerancije grešaka! Jednostavno je, mi to možemo”, pomislili smo i pokrenuli 2 servera, podižući kopiju brubeck-a na svakom. Da bismo to učinili, morali smo kopirati promet s metrikom na oba servera, pa čak i pisati za ovo mali uslužni program. Ovim smo riješili problem tolerancije grešaka, ali... ne baš dobro. Isprva je sve izgledalo sjajno: svaki brubeck prikuplja svoju verziju agregacije, upisuje podatke u Graphite svakih 30 sekundi, zamenjujući stari interval (ovo se radi na strani Graphite). Ako jedan server iznenada otkaže, uvijek imamo drugi sa vlastitom kopijom agregiranih podataka. Ali evo problema: ako server pokvari, na grafovima se pojavljuje „pila“. To je zbog činjenice da Brubeckovi intervali od 30 sekundi nisu sinkronizirani, a u trenutku pada jedan od njih nije prepisan. Kada se pokrene drugi server, dešava se ista stvar. Prilično podnošljivo, ali želim bolje! Problem skalabilnosti također nije nestao. Sve metrike i dalje „lete“ na jedan server, pa smo stoga ograničeni na istih 2-4 miliona MPS, u zavisnosti od nivoa mreže.

Ako malo razmislite o problemu i istovremeno kopate snijeg lopatom, onda vam može pasti na pamet sljedeća očigledna ideja: potreban vam je statsd koji može raditi u distribuiranom načinu. To jest, onaj koji implementira sinhronizaciju između čvorova u vremenu i metrici. “Naravno, takvo rješenje vjerovatno već postoji”, rekli smo i otišli u Google… I nisu našli ništa. Nakon prolaska kroz dokumentaciju za različite statsd (https://github.com/etsy/statsd/wiki#server-implementations od 11.12.2017. decembra XNUMX. godine) nismo našli apsolutno ništa. Očigledno, ni programeri ni korisnici ovih rješenja još nisu naišli na TOLIKO metrika, inače bi sigurno nešto smislili.

A onda smo se sjetili "igračke" statsd - bioyino, koja je napisana na Just for Fun hackathonu (naziv projekta je generiran skriptom prije početka hackathona) i shvatili da nam je hitno potreban vlastiti statsd. Za što?

  • jer ima premalo statsd klonova na svijetu,
  • jer je moguće pružiti željenu ili blizu željene tolerancije grešaka i skalabilnost (uključujući sinhronizaciju agregiranih metrika između servera i rješavanje problema slanja sukoba),
  • jer je moguće preciznije izračunati metriku nego što to čini Brubeck,
  • jer možete sami prikupiti detaljniju statistiku koju nam Brubeck praktički nije dao,
  • jer sam imao priliku da programiram sopstvenu hiperperformansnu distribuiranu skalu laboratorijsku aplikaciju, koja neće u potpunosti ponoviti arhitekturu drugog sličnog hiperfor... pa, to je to.

Na čemu pisati? Naravno, u Rustu. Zašto?

  • jer je već postojalo prototipno rješenje,
  • jer je autor članka već u to vrijeme poznavao Rust i bio je nestrpljiv da napiše nešto u njemu za proizvodnju uz mogućnost da ga stavi u open-source,
  • jer nam jezici sa GC-om nisu prikladni zbog prirode primljenog prometa (skoro u realnom vremenu) i GC pauze su praktički neprihvatljive,
  • jer su vam potrebne maksimalne performanse uporedive sa C
  • jer nam Rust pruža neustrašivu konkurentnost, i da smo počeli da ga pišemo na C/C++, imali bismo još više ranjivosti, prekoračenja bafera, uslova trke i drugih strašnih reči nego brubeck.

Postojao je i argument protiv Rusta. Kompanija nije imala iskustva sa kreiranjem projekata u Rustu, a sada takođe ne planiramo da ga koristimo u glavnom projektu. Stoga su postojali ozbiljni strahovi da ništa neće uspjeti, ali smo odlučili riskirati i pokušali.

Vrijeme je prolazilo...

Konačno, nakon nekoliko neuspjelih pokušaja, prva radna verzija je bila spremna. Šta se desilo? Evo šta se desilo.

Bioyino - distribuirani, skalabilni agregator metrika

Svaki čvor prima svoj vlastiti skup metrika i akumulira ih, a ne agregira metriku za one tipove gdje je njihov puni skup potreban za konačno agregiranje. Čvorovi su međusobno povezani nekom vrstom distribuiranog protokola zaključavanja, koji vam omogućava da među njima odaberete jedini (ovdje smo plakali) koji je dostojan slanja metrike Velikom. Ovaj problem trenutno rješava Konzul, ali se u budućnosti autorove ambicije protežu na vlastiti implementacija Splav, gde će najvredniji, naravno, biti konsenzus lider. Osim konsenzusa, čvorovi prilično često (podrazumevano jednom u sekundi) svojim susjedima šalju one dijelove prethodno agregiranih metrika koje su uspjeli prikupiti u toj sekundi. Ispostavilo se da su skaliranje i tolerancija grešaka očuvani - svaki čvor i dalje ima pun skup metrika, ali se metrika šalje već agregirana, preko TCP-a i kodirana u binarni protokol, tako da su troškovi dupliciranja značajno smanjeni u odnosu na UDP. Unatoč prilično velikom broju ulaznih metrika, akumulacija zahtijeva vrlo malo memorije i još manje CPU-a. Za naše visoko kompresibilne mertike, ovo je samo nekoliko desetina megabajta podataka. Kao dodatni bonus, ne dobijamo nepotrebno prepisivanje podataka u Graphite, kao što je bio slučaj sa burbeckom.

UDP paketi sa metrikom su neuravnoteženi između čvorova na mrežnoj opremi kroz jednostavan Round Robin. Naravno, mrežni hardver ne analizira sadržaj paketa i stoga može povući mnogo više od 4M paketa u sekundi, a da ne spominjemo metriku o kojoj ne zna baš ništa. Ako uzmemo u obzir da metrika ne dolazi jedan po jedan u svakom paketu, onda ne predviđamo probleme u performansama na ovom mjestu. Ako se server sruši, mrežni uređaj brzo (u roku od 1-2 sekunde) detektuje ovu činjenicu i uklanja srušeni server iz rotacije. Kao rezultat toga, pasivni (tj. ne-liderski) čvorovi se mogu uključiti i isključiti praktički bez primjećivanja povlačenja na grafikonima. Maksimum koji gubimo dio je metrike koja je došla u posljednjoj sekundi. Iznenadni gubitak/gašenje/prebacivanje lidera i dalje će stvoriti manju anomaliju (interval od 30 sekundi je još uvijek nesinhroniziran), ali ako postoji komunikacija između čvorova, ovi problemi se mogu minimizirati, na primjer, slanjem paketa za sinhronizaciju .

Malo o unutrašnjoj strukturi. Aplikacija je, naravno, višenitna, ali arhitektura navoja se razlikuje od one koja se koristi u Brubecku. Niti u brubecku su iste - svaka od njih je odgovorna i za prikupljanje i agregaciju informacija. U bioyinu radnici su podijeljeni u dvije grupe: oni koji su odgovorni za mrežu i oni koji su odgovorni za agregaciju. Ova podjela vam omogućava da fleksibilnije upravljate aplikacijom ovisno o vrsti metrike: tamo gdje je potrebna intenzivna agregacija, možete dodati agregatore, gdje ima puno mrežnog prometa, možete dodati broj mrežnih tokova. Trenutno na našim serverima radimo u 8 mrežnih i 4 toka agregacije.

Dio brojanja (odgovoran za agregaciju) je prilično dosadan. Baferi ispunjeni mrežnim tokovima distribuiraju se među tokovima brojanja, gdje se naknadno raščlanjuju i agregiraju. Na zahtjev, metrika se daje za slanje drugim čvorovima. Sve ovo, uključujući slanje podataka između čvorova i rad sa Consulom, se izvodi asinhrono, radeći na okviru tokio.

Mnogo više problema tokom razvoja izazvao je mrežni dio odgovoran za prijem metrike. Glavni cilj razdvajanja mrežnih tokova u zasebne entitete bila je želja da se smanji vrijeme koje protok troši ne za čitanje podataka iz utičnice. Opcije koje koriste asinhroni UDP i regularni recvmsg brzo su nestale: prva troši previše CPU-a korisničkog prostora za obradu događaja, druga zahtijeva previše prebacivanja konteksta. Stoga se sada koristi recvmmsg sa velikim tamponima (a odbojnici, gospodo oficiri, nisu vam ništa!). Podrška za redovni UDP rezervisana je za lake slučajeve u kojima recvmmsg nije potreban. U načinu rada s više poruka moguće je postići glavnu stvar: ogromnu većinu vremena mrežna nit hvata red čekanja OS - čita podatke iz utičnice i prenosi ih u međuspremnik korisničkog prostora, samo povremeno prelazi na davanje ispunjenog bafera u agregatori. Red u utičnici se praktički ne akumulira, broj ispuštenih paketa praktički ne raste.

primjedba

U zadanim postavkama, veličina bafera je postavljena na prilično veliku. Ako iznenada odlučite sami isprobati server, možete naići na činjenicu da nakon slanja malog broja metrika neće stići u Graphite, ostajući u baferu mrežnog toka. Da biste radili s malim brojem metrika, morate postaviti bufsize i task-queue-size na manje vrijednosti u konfiguraciji.

Na kraju, neke karte za ljubitelje grafikona.

Statistika o broju dolaznih metrika za svaki server: više od 2 miliona MPS.

Bioyino - distribuirani, skalabilni agregator metrika

Onemogućavanje jednog od čvorova i preraspodjela dolaznih metrika.

Bioyino - distribuirani, skalabilni agregator metrika

Statistika o izlaznim metrikama: uvijek šalje samo jedan čvor - šef racije.

Bioyino - distribuirani, skalabilni agregator metrika

Statistika rada svakog čvora, uzimajući u obzir greške u različitim sistemskim modulima.

Bioyino - distribuirani, skalabilni agregator metrika

Detalji dolaznih metrika (nazivi metrika su skriveni).

Bioyino - distribuirani, skalabilni agregator metrika

Šta planiramo dalje sa svim ovim? Naravno, napiši kod, prokletstvo...! Prvobitno je planirano da projekat bude otvorenog koda i tako će ostati do kraja života. Naši neposredni planovi uključuju prelazak na našu vlastitu verziju Rafta, promjenu ravnopravnog protokola na prenosiviji, uvođenje dodatne interne statistike, nove vrste metrike, ispravke grešaka i druga poboljšanja.

Naravno, svi su dobrodošli da pomognu u razvoju projekta: kreiramo PR, probleme, po mogućnosti ćemo odgovoriti, poboljšati itd.

Uz to, narode, to je sve, kupite naše slonove!



izvor: www.habr.com

Dodajte komentar