Kështu që ju mblidhni metrikë. Siç jemi ne. Ne gjithashtu mbledhim metrikë. Sigurisht, e nevojshme për biznes. Sot do të flasim për lidhjen e parë të sistemit tonë të monitorimit - një server grumbullimi i pajtueshëm me statsd
Nga artikujt tanë të mëparshëm (
Pretendimi 1. Github, zhvilluesi i projektit, pushoi së mbështeturi atë: publikimi i arnimeve dhe rregullimeve, pranimi i PR-së tonë dhe (jo vetëm tonën). Muajt e fundit (diku nga shkurt-mars 2018) ka rinisur aktiviteti, por para kësaj ka pasur gati 2 vite qetësi të plotë. Përveç kësaj, projekti është duke u zhvilluar
Pretendimi 2. Saktësia e llogaritjeve. Brubeck mbledh gjithsej 65536 vlera për grumbullim. Në rastin tonë, për disa metrikë, gjatë periudhës së grumbullimit (30 sekonda), mund të arrijnë shumë më tepër vlera (1 në kulmin). Si rezultat i këtij kampionimi, vlerat maksimale dhe minimale duken të padobishme. Për shembull, si kjo:
Siç ishte
Si duhet të ishte
Për të njëjtën arsye, shumat përgjithësisht llogariten gabimisht. Shto këtu një defekt me një tejmbushje float 32-bit, e cila në përgjithësi e dërgon serverin në segfault kur merr një metrikë në dukje të pafajshme dhe gjithçka bëhet e mrekullueshme. Meqë ra fjala, defekti nuk është rregulluar.
Dhe, së fundi, Pretendimi X. Në momentin e shkrimit, ne jemi gati t'ua prezantojmë atë të 14 zbatimeve pak a shumë të statsd-së që kemi mundur të gjejmë. Le të imagjinojmë se një infrastrukturë e vetme është rritur aq shumë sa të pranosh 4 milionë MPS nuk mjafton më. Ose edhe nëse nuk është rritur ende, por metrikat janë tashmë aq të rëndësishme për ju, sa edhe uljet e shkurtra 2-3 minuta në grafikët mund të bëhen tashmë kritike dhe të shkaktojnë periudha depresioni të pakapërcyeshëm midis menaxherëve. Meqenëse trajtimi i depresionit është një detyrë e pafalshme, nevojiten zgjidhje teknike.
Së pari, toleranca ndaj gabimeve, në mënyrë që një problem i papritur në server të mos shkaktojë një apokalips psikiatrik zombie në zyrë. Së dyti, shkallëzimi për të qenë në gjendje të pranojë më shumë se 4 milionë MPS, pa u gërmuar thellë në grumbullin e rrjetit Linux dhe pa u rritur me qetësi "në gjerësi" në madhësinë e kërkuar.
Meqenëse kishim hapësirë për shkallëzim, vendosëm të fillonim me tolerancën e gabimeve. "RRETH! Toleranca ndaj gabimeve! Është e thjeshtë, ne mund ta bëjmë atë," menduam dhe lançuam 2 serverë, duke ngritur një kopje të brubeck në secilin. Për ta bërë këtë, na u desh të kopjonim trafikun me metrikë në të dy serverët dhe madje të shkruanim për këtë
Nëse mendoni pak për problemin dhe në të njëjtën kohë gërmoni borën me një lopatë, atëherë mund të vijë në mendje ideja e mëposhtme e qartë: keni nevojë për një statsd që mund të funksionojë në modalitetin e shpërndarë. Kjo do të thotë, ai që zbaton sinkronizimin midis nyjeve në kohë dhe metrikë. “Sigurisht, një zgjidhje e tillë ndoshta ekziston tashmë”, thamë dhe shkuam në Google…. Dhe ata nuk gjetën asgjë. Pasi kaloni dokumentacionin për statsd të ndryshme (
Dhe pastaj u kujtuam për "lodrën" statsd - bioyino, e cila u shkrua në hackathon Just for Fun (emri i projektit u krijua nga skenari para fillimit të hackathon) dhe kuptuam se ne kishim nevojë urgjente për statsd-në tonë. Per cfare?
- sepse ka shumë pak klone statsd në botë,
- sepse është e mundur të sigurohet toleranca e dëshiruar ose afër tolerancës dhe shkallëzimit të defektit (përfshirë sinkronizimin e metrikave të grumbulluara midis serverëve dhe zgjidhjen e problemit të dërgimit të konflikteve),
- sepse është e mundur të llogariten metrikat më saktë se sa bën Brubeck,
- sepse ju mund të mblidhni statistika më të detajuara vetë, të cilat brubeck praktikisht nuk na i dha,
- sepse pata mundësinë të programoja aplikacionin tim të laboratorit të shkallës së shpërndarë me hiperperformancë, i cili nuk do të përsërisë plotësisht arkitekturën e një hiper tjetër të ngjashëm... mirë, kjo është ajo.
mbi çfarë të shkruani? Sigurisht, në Rust. Pse?
- sepse kishte tashmë një zgjidhje prototip,
- sepse autori i artikullit tashmë e njihte Rust në atë kohë dhe ishte i etur të shkruante diçka në të për prodhim me mundësinë për ta vendosur atë në burim të hapur,
- sepse gjuhët me GC nuk janë të përshtatshme për ne për shkak të natyrës së trafikut të marrë (pothuajse në kohë reale) dhe pauzat e GC janë praktikisht të papranueshme,
- sepse keni nevojë për performancë maksimale të krahasueshme me C
- sepse Rust na siguron njëkohshmëri të patrembur dhe nëse do të fillonim ta shkruanim në C/C++, do të kishim grumbulluar edhe më shumë dobësi, tejmbushje buferi, kushte gare dhe fjalë të tjera të frikshme sesa brubeck.
Kishte edhe një argument kundër Rustit. Kompania nuk kishte përvojë në krijimin e projekteve në Rust, dhe tani ne gjithashtu nuk planifikojmë ta përdorim atë në projektin kryesor. Prandaj, kishte frikë serioze se asgjë nuk do të funksiononte, por vendosëm të shfrytëzonim një shans dhe u përpoqëm.
Koha kaloi...
Më në fund, pas disa përpjekjeve të dështuara, versioni i parë i punës ishte gati. Cfare ndodhi? Kjo është ajo që ndodhi.
Çdo nyje merr grupin e vet të metrikave dhe i grumbullon ato, dhe nuk grumbullon metrikë për ato lloje ku grupi i tyre i plotë kërkohet për grumbullimin përfundimtar. Nyjet janë të lidhura me njëra-tjetrën nga një lloj protokolli i bllokimit të shpërndarë, i cili ju lejon të zgjidhni midis tyre të vetmin (këtu kemi qarë) që është i denjë për të dërguar metrikë tek i Madhi. Ky problem aktualisht po zgjidhet nga
Paketat UDP me metrikë janë të pabalancuara midis nyjeve në pajisjet e rrjetit përmes një Round Robin të thjeshtë. Sigurisht, pajisja e rrjetit nuk analizon përmbajtjen e paketave dhe për këtë arsye mund të tërheqë shumë më tepër se 4 milion pako në sekondë, për të mos përmendur metrikat për të cilat nuk di fare. Nëse marrim parasysh që metrikat nuk vijnë një nga një në çdo paketë, atëherë nuk parashikojmë ndonjë problem performancës në këtë vend. Nëse një server rrëzohet, pajisja e rrjetit shpejt (brenda 1-2 sekondave) e zbulon këtë fakt dhe heq serverin e dëmtuar nga rrotullimi. Si rezultat i kësaj, nyjet pasive (d.m.th., jo-lider) mund të ndizen dhe fiken praktikisht pa vërejtur tërheqje në grafikët. Maksimumi që humbasim është pjesë e matjeve që hynë në sekondën e fundit. Një humbje/fikje/ndërrim i papritur i një drejtuesi do të krijojë ende një anomali të vogël (intervali prej 30 sekondash është ende jashtë sinkronizimit), por nëse ka komunikim midis nyjeve, këto probleme mund të minimizohen, për shembull, duke dërguar paketa sinkronizimi .
Pak për strukturën e brendshme. Aplikimi është, natyrisht, me shumë fije, por arkitektura e filetimit është e ndryshme nga ajo e përdorur në brubeck. Fijet në brubeck janë të njëjta - secila prej tyre është përgjegjëse si për mbledhjen e informacionit ashtu edhe për grumbullimin. Në bioyino, punëtorët ndahen në dy grupe: ata që janë përgjegjës për rrjetin dhe ata që janë përgjegjës për grumbullimin. Kjo ndarje ju lejon të menaxhoni në mënyrë më fleksibël aplikacionin në varësi të llojit të matjeve: ku kërkohet grumbullim intensiv, mund të shtoni grumbullues, ku ka shumë trafik në rrjet, mund të shtoni numrin e flukseve të rrjetit. Për momentin, në serverët tanë ne punojmë në 8 rrjete dhe 4 flukse grumbullimi.
Pjesa e numërimit (përgjegjëse për grumbullimin) është mjaft e mërzitshme. Buferët e mbushur nga flukset e rrjetit shpërndahen midis flukseve të numërimit, ku më pas analizohen dhe grumbullohen. Me kërkesë, metrikat jepen për dërgim në nyje të tjera. E gjithë kjo, duke përfshirë dërgimin e të dhënave midis nyjeve dhe punën me Konsullin, kryhet në mënyrë asinkrone, duke ekzekutuar në kornizë
Shumë më tepër probleme gjatë zhvillimit u shkaktuan nga pjesa e rrjetit përgjegjëse për marrjen e metrikës. Qëllimi kryesor i ndarjes së flukseve të rrjetit në entitete të veçanta ishte dëshira për të reduktuar kohën që kalon një rrjedhë. jo për të lexuar të dhënat nga priza. Opsionet që përdorin UDP asinkron dhe recvmsg të rregullt u zhdukën shpejt: i pari konsumon shumë CPU në hapësirën e përdoruesit për përpunimin e ngjarjeve, i dyti kërkon shumë ndërrime konteksti. Prandaj tani përdoret
Shënim
Në cilësimet e paracaktuara, madhësia e tamponit është caktuar të jetë mjaft e madhe. Nëse papritmas vendosni të provoni vetë serverin, mund të hasni në faktin që pas dërgimit të një numri të vogël metrikash, ato nuk do të mbërrijnë në Graphite, duke mbetur në buferin e rrjedhës së rrjetit. Për të punuar me një numër të vogël metrikë, duhet të vendosni madhësinë e bufsize dhe task-queue-size në vlera më të vogla në konfigurim.
Më në fund, disa tabela për adhuruesit e grafikëve.
Statistikat për numrin e matjeve hyrëse për çdo server: më shumë se 2 milion MPS.
Çaktivizimi i një prej nyjeve dhe rishpërndarja e metrikës hyrëse.
Statistikat mbi matjet në dalje: vetëm një nyje dërgon gjithmonë - shefi i bastisjes.
Statistikat e funksionimit të secilës nyje, duke marrë parasysh gabimet në module të ndryshme të sistemit.
Detajet e metrikës hyrëse (emrat metrikë janë të fshehur).
Çfarë po planifikojmë të bëjmë me gjithë këtë në vijim? Natyrisht, shkruaj kod, dreq...! Projekti fillimisht ishte planifikuar të ishte me burim të hapur dhe do të mbetet i tillë gjatë gjithë jetës së tij. Planet tona të menjëhershme përfshijnë kalimin në versionin tonë të Raft, ndryshimin e protokollit të homologëve në një më të lëvizshëm, prezantimin e statistikave të brendshme shtesë, llojeve të reja të matjeve, korrigjimet e gabimeve dhe përmirësime të tjera.
Sigurisht, të gjithë janë të mirëpritur të ndihmojnë në zhvillimin e projektit: të krijojmë PR, Çështje, nëse është e mundur do të përgjigjemi, do të përmirësojmë, etj.
Me këtë u tha, kjo është e gjitha njerëz, blini elefantët tanë!
Burimi: www.habr.com