Nii et, teie kogute mÔÔdikuid. Nagu meie. Meie kogume samuti mÔÔdikuid. Loomulikult selliseid, mis on Ă€ri jaoks vajalikud. TĂ€na rÀÀgime meie jĂ€lgimissĂŒsteemi esimesest elemendist â statsd-ĂŒhilduvast aggregeerimiserverist. , miks me selle kirjutasime ja miks loobusime brubeckist.

Meie varasematest artiklitest (, ) saab teada, et kuni teatud ajani kogusime mĂ€rke brubecki abil. . See on kirjutatud C-s. Koodivaates â lihtne nagu kork (see on oluline, kui soovite panustada) ja, mis kĂ”ige tĂ€htsam, suudab see meie mahtudega 2 miljonit mÔÔdikut sekundis (MPS) tipptasemel probleemideta hakkama saada. Dokumentatsioon lubab 4 miljonit MPS tĂ€hega. See tĂ€hendab, et nimetatud number saavutatakse, kui seadistate vĂ”rgu Linuxis Ă”igesti. (Kui palju MPS on vĂ”imalik saada, kui vĂ”rku jĂ€tta selliseks nagu on, ei ole meile teada). Hoolimata neist eeliseid oli brubecki suhtes mitmeid tĂ”siseid pretensioone.
Pretensioon 1. Github â projekti arendaja â lĂ”petas selle toetamise: plaastrite ja paranduste avaldamise, meie ja (mitte ainult meie) PR-de vastuvĂ”tmise. Viimastel kuudel (umbes alates veebruari-mĂ€rtsi 2018) on aktiivsus taaselustatud, kuid enne seda oli peaaegu 2 aastat tĂ€ielikku vaikust. Lisaks on projekt arendatud , mis vĂ”ib saada tĂ”siseks takistuseks uute vĂ”imaluste rakendamisel.
Pretensioon 2. Arvutuste tÀpsus. Brubeck kogub aggregeerimiseks vaid 65536 vÀÀrtust. Meie puhul vÔib mÔnede mÔÔdikute puhul aggregeerimise perioodi (30 sek) jooksul tulla palju rohkem vÀÀrtusi (tipptasemel 1 527 392). Sellise proovivÔtmise tulemusena nÀevad maksimumide ja miinimumide vÀÀrtused tÀiesti kasutud. NÀiteks, nii:

Kuidas oli

Nii nagu oleks pidanud olema
Sama pĂ”hjusel arvestatakse summasid ĂŒldiselt valesti. Lisage siia 32-bitisest floatist tulenev ĂŒlevoolu viga, mis saadab serveri segfault'i, kui see saab nĂ€iliselt sĂŒĂŒtuid mÔÔdikuid, ja asi muutub veelgi paremaks. Viga, muide, pole siiani parandatud.
Ja lĂ”puks, Pretensioon X. Artikli kirjutamise hetkeks oleme valmis esitama selle kĂ”igile 14 enam-vĂ€hem töötavale statsd rakendusele, mida oleme suutnud leida. Kujutame ette, et mĂ”ni infrastruktuur on kasvanud piisavalt suureks, et 4 miljoni MPS vastuvĂ”tmine ei ole enam piisav. VĂ”i olgu see veel kasvanud, kuid mÔÔdikud on teie jaoks juba nii olulised, et isegi lĂŒhikesed, 2-3 minuti pikkused katkestused graafikutes vĂ”ivad olla kriitilised ja tekitada halbu tujusi juhtide seas. Kuna depressiooni ravimine on tĂ€namatu töö, vajame tehnilisi lahendusi.
Esiteks, talitlushĂ€irete vastupidavus, et ootamatud serveriprobleemid ei cause`iks kontoris psĂŒhhiaatrilist zombiapokalypsi. Teiseks, skaleeritavus, et saaksime vastu vĂ”tta rohkem kui 4 miljonit MPS, ilma et peaksime sĂŒgavale Linuxi vĂ”rgu kihti kaevama ja rahulikult laienema âlaiusesseâ soovitud suuruseni.
Kuna meil oli skaleeritavuse osas varu, otsustasime alustada talitlushĂ€irete vastupidavusest. "O! TalitlushĂ€irete vastupidavus! See on lihtne, me oskame seda!" â mĂ”tlesime ja kĂ€ivitasime 2 serverit, tĂ”stes igaĂŒhele ĂŒles brubeck koopia. Selleks pidime kopeerima liikluse mÔÔdikutega mĂ”lemasse serverisse ja isegi kirjutama selle jaoks . Me lahendasime talitlushĂ€irete vastupidavuse probleemi, kuid... mitte eriti hĂ€sti. Algul tundus kĂ”ik olevat suurepĂ€rane: iga brubeck kogub oma aggregeerimise versiooni, kirjutab andmed Graphite'i iga 30 sekundi tagant, ĂŒlekirjutades vana intervalli (see toimub Graphite'i pool). Kui ĂŒks server peaks riknema, on meil alati olemas teine server koos oma aggregeeritud andmete koopia. Kuid probleem on selles, et kui server rikneb, tekib graafikutesse "saag". See on tingitud sellest, et brubeck'i 30-sekundi intervallid ei ole sĂŒnkroonitud ja katkestuse hetkel ei ĂŒlekirjutata ĂŒhte neist. Kui teine server kĂ€ivitatakse, toimub sama asi. TĂ€iesti talutav, kuid tahaks parem! Skaleeritavuse probleem pole samuti kuhugi kadunud. KĂ”ik mÔÔdikud jooksevad endiselt ĂŒhele serverile, seega oleme piiratud samade 2-4 miljoni MPS-ga, sĂ”ltuvalt vĂ”rgu jĂ”udlusest.
Kui mĂ”elda probleemile ja samal ajal lĂŒhikese labidaga lund kaevata, vĂ”ib pĂ€he tulla ĂŒks ilmne mĂ”te: meil on vaja statsd, mis suudab töötada jaotatud reĆŸiimis. See tĂ€hendab, et see vĂ”imaldab sĂŒnkroniseerida nodede vahel aega ja mÔÔdikuid. "Loomulikult on selline lahendus juba olemas," ĂŒtlesime ja lĂ€ksime guugeldama... Ja ei leidnud midagi. Uurides erinevate statsd dokumentatsiooni ( 31.12.2017), ei leidnud me tegelikult mitte midagi. Tundub, et ei arendajad ega kasutajad ei ole sellise KOGUSE mÔÔdikutega seni kokku puutunud, muidu oleks nad kindlasti midagi vĂ€lja mĂ”elnud.
Ja siis meenutasime me "mÀnguasja" statsd - bioyino, mille olime kirjutatud hackathonil lihtsalt lÔbu pÀrast (projekti nimi genereeris skript enne hackathoni algust) ja mÔistsime, et meil on hÀdasti vaja oma statsd. Miks?
- sest maailmas on liiga vÀhe statsd kloone,
- sest on vĂ”imalik tagada soovitud vĂ”i soovitavale lĂ€hedane vigade taluvus ja skalaarne kasv (sealhulgas sĂŒnkroniseerida agreetitud mÔÔdikud serverite vahel ja lahendada konfliktid edastamise ajal),
- sest mÔÔdikuid on vÔimalik arvestada tÀpsemalt kui brubeck,
- sest saame ise koguda detailsemat statistikat, mida brubeck meile praktiliselt ei pakkunud,
- sest tekkis vĂ”imalus programmeerida oma hĂŒperperformantne jaotatud skaleeritav rakendus, mis ei jĂ€lgi tĂ€ielikult teise sarnase hĂŒperperform... nuviponeli arhitektuuri.
Millega me kirjutame? Loomulikult Rustiga. Miks?
- sest prototĂŒĂŒp lahendus oli juba olemas,
- sest artikli autor teadis tol ajal juba Rusti ja tahtis sellel kirjutada midagi tootmises koos vÔimalusega avaldada see open-source,
- sest GC-ga keelad ei sobi meile saadud liikluse loomuse tÔttu (peaaegu reaalajas) ja GC-pausid on peaaegu vastuvÔetamatud,
- sest maksimaalne jÔudlus on vajalik, vÔrreldav C-ga
- sest Rust pakub meile fearless concurrency, ja kui me oleksime hakanud seda kirjutama C/C++-ga, oleksime saanud veel rohkem haavatavusi, puhkerikkumisi, race conditions ja muid hirmutavaid sÔnu kui brubeck.
Oli ka argumente ka Rusti vastu. EttevÔttel ei olnud kogemusi projektide loomisel Rustis ning praegu me ka ei plaani seda oma peamises projektis kasutada. SeetÔttu oli tÔsiseid muresid, et midagi ei Ônnestu, kuid otsustasime riskida ja proovida.
Aeg möödus...
LÔpuks, pÀrast mitmeid ebaÔnnestunud katseid, oli esimene töötav versioon valmis. Mis vÀlja tuli? Tuli just selline.

Iga sĂ”lm saab oma mÔÔdikute komplekti ja kogub need enda juurde, kuid ei agrega mÔÔdikuid nende tĂŒĂŒpide jaoks, kus lĂ”ppagregatsiooni jaoks on vajalik nende tĂ€iskomplekt. SĂ”lmed on ĂŒhendatud mingi jaotatud lukustuse protokolliga, mis vĂ”imaldab valida nende seast selle ainsa (siin me nutame), mis on teeninud Ă”iguse edastada mÔÔdikud Suurele. Praegu lahendab seda probleemi , kuid tulevikus ulatuvad autori ambitsioonid Rafti, kus see ainuĂ”igust saanud on loomulikult konsensuse juht. Lisaks konsensusele saadavad sĂ”lmed ĂŒsna sageli (vaikimisi ĂŒks kord sekundis) oma naabritele need eel-agreggeeritud mÔÔdikute osad, mida Ă”nnestus selle sekundi jooksul koguda. Selgub, et skaleeritavus ja tĂ”rketaluvus sĂ€ilivad - iga sĂ”lm hoiab endas endiselt tĂ€iskiht mÔÔdikuid, kuid mÔÔdikud saadetakse nĂŒĂŒd juba agreggeeritult, TCP kaudu ja binaarprotokolli kodeerimisega, seega kulud dubleerimisele on vĂ”rreldes UDP-ga mĂ€rkimisvÀÀrselt vĂ€henenud. Hoolimata ĂŒsna suurest sisenevate mÔÔdikute arvust, vajab kogumine vĂ€ga vĂ€he mĂ€lu ja veel vĂ€hem CPU-d. Meie hĂ€sti tihendatud mÔÔdikute jaoks on see vaid paar kĂŒmmet megabaiti andmeid. TĂ€iendava boonuseks saame andmete liigsete ĂŒle kirjutamiste puudumise Graphites, nagu see oli burbeckiga.
UDP-paketid koos mÔÔdikute vÀÀrtustega jagunevad vĂ”rguseadmestikuna lihtsalt Round Robin'i meetodil. Loomulikult ei analĂŒĂŒsi vĂ”rgu riistvara pakettide sisu ning seega suudab see kĂ€sitleda palju rohkem kui 4M paketti sekundis, rÀÀkimata mÔÔdikutest, millest see ĂŒldse midagi ei tea. Arvestades, et mÔÔdikud saabuvad mitte ĂŒkshaaval igas pakendis, ei prognoosi me siin jĂ”udluse probleeme. Kui server peaks alla minema, tuvastab vĂ”rgu seade kiiresti (1-2 sekundi jooksul) selle olukorra ning eemaldab langemisega serveri rotatsioonist. Tulemuseks on see, et passiivseid (st mitte liidri) node saab sisse ja vĂ€lja lĂŒlitada peaaegu mĂ€rkamatult graafikute langemisi. Maksimum, mida me kaotame, on osa mÔÔdikuid, mis saabusid viimase sekundi jooksul. Ăkiline kadumine/lĂŒlitamine/liidri vahetus joonistab endiselt vĂ€ikese anomaalia (30-sekundiline intervall jÀÀb endiselt desĂŒnkroniseerituks), kuid node'ide vaheline side aitab minimeerida ka need probleemid, nĂ€iteks saatmisega sĂŒnkroonimis paketid.
Natuke meie sisemisest seadistusest. Rakendus on muidugi mitme lĂ”imega, kuid lĂ”imed arhitektuur erineb sellest, mida on kasutatud brubeck'is. LĂ”imed brubeck'is on ĂŒhesugused â igaĂŒhe ĂŒlesanne on samaaegselt koguda teavet ja teha selle agregatsiooni. bioyino's on töö lĂ”imed (workers) jagatud kaheks grupiks: ĂŒhed vastutavad vĂ”rgu eest ja teised vastutavad agregatsiooni eest. Selline jaotus vĂ”imaldab rakendust paindlikumalt juhtida sĂ”ltuvalt mÔÔdikute tĂŒĂŒbist: seal, kus vajatakse intensiivset agregatsiooni, saab suurendada agregaatoreid, seal, kus on palju vĂ”rgu liiklust â suurendada vĂ”rgulĂ”imede arvu. Hetkel töötame meie serverites 8 vĂ”rglĂ”ime ja 4 agregatsioonilĂ”imega.
Agregeerimise (arvestava) osa töö on piisavalt igav. VĂ”rgulĂ”imede poolt tĂ€idetud puhvri jaotamine toimub arvestavatel lĂ”imedel, kus andmed parseli ja agrigeeritakse. Kui palutakse mÔÔdikud, antakse need edasi teistele node'idele. KĂ”ik see, sealhulgas andmete edastamine node'ide vahel ja töö Consul'iga, toimub asĂŒnkroonselt, töötab raamistiku peal. .
Arendusplatside arendamise kĂ€igus esines palju probleeme vĂ”rguosas, mis oli vastutav mÔÔtmiste vastuvĂ”tu eest. Peamine eesmĂ€rk vĂ”rguvoogude eraldamiseks eraldi ĂŒksusteks oli pĂŒĂŒd vĂ€hendada aega, mida voog kulutab ei andmete lugemiseks soketist. AsĂŒnkroonseid UDP ja tavapĂ€rase recvmsg'i variandid langesid kiiresti vĂ€lja: esimene kasutab liiga palju user-space CPU-d sĂŒndmuste töötlemiseks, teine â liiga palju konteksti vahetusi. SeetĂ”ttu kasutatakse praegu suurte puhverdate (ja puhvĂ€rd, hĂ€rra ohvitserid, see pole mingisugune nalja asi!). Tavalise UDP toe sĂ€ilitamine on jÀÀnud koormamata juhtumitele, kus recvmmsg'i ei ole tingimata vaja. MultimeetsereĆŸiimis suudetakse saavutada pĂ”hiline eesmĂ€rk: enamik aega veedab vĂ”rguvoog OS-i jĂ€rjekorra sorteerimisel â loeb andmeid soketist ja paneb need userspace'i puhvri, vaid harva vahetades, et anda tĂ€idetud puhver edasi agregaatoritele. Soketi jĂ€rjekord praktiliselt ei kogune, visatud pakettide arv praktiliselt ei kasva.
MĂ€rkus
Vaikimisi sÀtetega on puhvri suurus seadistatud piisavalt suureks. Kui otsustate serverit ise proovida, vÔite kokku puutuda olukorraga, kus pÀrast vÀikese hulga mÔÔtmiste saatmist need ei jÔua Graphite'i, jÀÀdes vÔrguvoo puhvri. VÀikese hulga mÔÔtmiste töötlemiseks tuleb seadistuses mÀÀrata bufsize ja task-queue-size vÀiksemate vÀÀrtustega.
LĂ”petuseks â veidi graafikuid graafikute armastajatele.
Sisse tulevate mÔÔtmiste statistika igas serveris: ĂŒle 2 miljoni MPS.

Ăhe node vĂ€ljalĂŒlitamine ja sisse tulevate mÔÔtmiste ĂŒmberjaotamine.

VĂ€ljuvate mÔÔtmiste statistika: saadab alati ainult ĂŒks node â raidboss.

Iga node'i töö statistika, arvesse vĂ”ttes sĂŒsteemi erinevate moodulite vigu.

Sisse tulevate mÔÔtmiste detailiseerimine (mÔÔtmiste nimed on varjatud).

Mida me plaanime kĂ”igega edasi teha? Muidugi, kodeerida, blâŠ! Projekt oli algselt plaanitud avatud allikana ja jÀÀb selliseks kogu oma elu jooksul. LĂ€hitulevikus plaanime ĂŒleminekut oma versioonile Raft, peer-protokolli vahetamist ĂŒlekantavamaks, lisama sisemist statistikat, uusi mÔÔtmisetĂŒĂŒpe, parandama vigu ja teisi parandusi.
Loomulikult on kÔik, kes soovivad projekti arendamisele kaasa aidata, teretulnud: looge PR-e, Issues, vastame ja tÀiustame vÔimaluste piires jne.
Nii nagu öeldakse, thatâs all folks, ostke meie elevante!

Allikas: habr.com
