Bioyino – hajutatud, skaleeritav mõõdikute koondaja

Nii et kogute mõõdikuid. Nagu me oleme. Kogume ka mõõdikuid. Äritegevuseks muidugi vajalik. Täna räägime meie seiresüsteemi kõige esimesest lingist - statsd-ga ühilduvast koondamisserverist bioyino, miks me selle kirjutasime ja miks me brubeckist loobusime.

Bioyino – hajutatud, skaleeritav mõõdikute koondaja

Meie eelmistest artiklitest (1, 2) saate teada, et kuni mõnda aega kogusime silte kasutades Brubeck. See on kirjutatud C-keeles. Koodi seisukohast on see sama lihtne kui pistik (see on oluline, kui soovite panustada) ja mis kõige tähtsam, see käsitleb tipptasemel meie mahtusid 2 miljonit meetrit sekundis (MPS). ilma probleemideta. Dokumentatsioonis on 4 miljoni MPS-i toetus märgitud tärniga. See tähendab, et kui konfigureerite võrgu Linuxis õigesti, saate näidatud näitaja. (Me ei tea, kui palju MPS-i saate, kui jätate võrgu selliseks, nagu see on). Vaatamata nendele eelistele oli meil brubecki kohta mitu tõsist kaebust.

Nõue 1. Projekti arendaja Github lõpetas selle toetamise: paikade ja paranduste avaldamise, meie oma ja (mitte ainult meie) PR-i aktsepteerimise. Viimastel kuudel (kuskil veebruar-märts 2018) on tegevus taastunud, kuid enne seda oli peaaegu 2 aastat täielikku rahu. Lisaks arendatakse projekti sisemiste Gihubi vajaduste jaoks, mis võib saada tõsiseks takistuseks uute funktsioonide kasutuselevõtul.

Nõue 2. Arvutuste täpsus. Brubeck kogub liitmiseks kokku 65536 väärtust. Meie puhul võib mõne mõõdiku puhul koondperioodi (30 sekundit) jooksul jõuda palju rohkem väärtusi (tippajal 1 527 392). Selle proovivõtu tulemusena näivad maksimum- ja miinimumväärtused kasutud. Näiteks nii:

Bioyino – hajutatud, skaleeritav mõõdikute koondaja
Nagu see oli

Bioyino – hajutatud, skaleeritav mõõdikute koondaja
Kuidas see oleks pidanud olema

Samal põhjusel arvutatakse summad üldjuhul valesti. Lisa siia 32-bitise float overflow viga, mis pealtnäha süütu mõõdiku saamisel saadab üldjuhul serveri segfaulti ja kõik läheb suurepäraseks. Viga, muide, pole parandatud.

Ja lõpuks, Nõue X. Selle artikli kirjutamise ajal oleme valmis seda tutvustama kõigile 14 enam-vähem töötavale statsd-rakendusele, mis meil õnnestus leida. Kujutagem ette, et mõni üksik infrastruktuur on nii palju kasvanud, et 4 miljoni MPS aktsepteerimisest enam ei piisa. Või isegi siis, kui see pole veel kasvanud, kuid mõõdikud on teile juba nii olulised, et isegi lühikesed, 2-3-minutilised langused edetabelites võivad muutuda kriitiliseks ja põhjustada juhtide seas ületamatuid depressioonihooge. Kuna depressiooni ravi on tänamatu töö, on vaja tehnilisi lahendusi.

Esiteks veataluvus, et äkiline probleem serveris ei tekitaks kontoris psühhiaatrilist zombiapokalüpsist. Teiseks skaleerimine, et oleks võimalik vastu võtta rohkem kui 4 miljonit MPS, ilma Linuxi võrgupinu sügavale süvenemata ja rahulikult “laiuselt” vajaliku suuruseni kasvamata.

Kuna meil oli ruumi skaleerimiseks, otsustasime alustada veataluvusega. "ABI! Veataluvus! See on lihtne, me saame hakkama,” mõtlesime ja käivitasime kaks serverit, tõstes mõlemasse brubecki koopia. Selleks pidime liikluse koos mõõdikutega mõlemasse serverisse kopeerima ja selle jaoks isegi kirjutama väike utiliit. Lahendasime sellega tõrketaluvuse probleemi, aga... mitte väga hästi. Alguses tundus kõik suurepärane: iga brubeck kogub kokku oma versiooni, kirjutab andmed Graphite'i iga 30 sekundi järel, kirjutades vana intervalli üle (seda tehakse grafiidi poolel). Kui üks server ootamatult ebaõnnestub, on meil alati teine, millel on koondandmete koopia. Kuid siin on probleem: kui server ebaõnnestub, ilmub graafikutele "saag". Selle põhjuseks on asjaolu, et brubecki 30-sekundilised intervallid ei ole sünkroonitud ja krahhi hetkel üks neist üle ei kirjutata. Kui teine ​​server käivitub, juhtub sama. Üsna talutav, aga tahaks paremat! Ka skaleeritavuse probleem pole kuhugi kadunud. Kõik mõõdikud “lendavad” ikka ühte serverisse ja seetõttu piirdume sama 2-4 miljoni MPS-ga, olenevalt võrgutasemest.

Kui probleemile veidi järele mõelda ja samal ajal labidaga lund üles kaevata, siis võib pähe tulla järgmine ilmselge mõte: vaja on statsd-d, mis saaks töötada hajutatud režiimis. See tähendab, et sünkroonimine toimub aja ja mõõdikute vahel sõlmede vahel. "Muidugi on selline lahendus ilmselt juba olemas," ütlesime ja läksime Google'i…. Ja nad ei leidnud midagi. Pärast erinevate statistiliste andmete dokumentatsiooni läbimist (https://github.com/etsy/statsd/wiki#server-implementations seisuga 11.12.2017. detsember XNUMX), ei leidnud me absoluutselt midagi. Ilmselt ei ole nende lahenduste arendajad ega kasutajad veel NII paljude mõõdikutega kokku puutunud, muidu tuleks kindlasti midagi välja.

Ja siis meenus “mänguasja” statsd - bioyino, mis sai kirjutatud just for fun hackathonil (projekti nime genereeris stsenaarium enne häkatoni algust) ja saime aru, et meil on hädasti vaja oma statsd. Milleks?

  • sest maailmas on liiga vähe statsd kloone,
  • kuna on võimalik pakkuda soovitud või sellele lähedast tõrketaluvust ja skaleeritavust (sh serverite koondmõõdikute sünkroonimine ja saatmiskonfliktide lahendamine),
  • sest mõõdikuid on võimalik arvutada täpsemalt kui Brubeck,
  • sest saate ise koguda üksikasjalikumat statistikat, mida brubeck meile praktiliselt ei esitanud,
  • sest mul oli võimalus programmeerida oma hüperjõudlusega hajutatud skaala laborirakendust, mis ei korda täielikult teise sarnase hyperfori arhitektuuri... noh, see on kõik.

Millele kirjutada? Muidugi, Roostes. Miks?

  • kuna prototüüplahendus oli juba olemas,
  • sest artikli autor teadis juba sel ajal Rustit ja tahtis sellesse midagi tootmiseks kirjutada koos võimalusega see avatud lähtekoodiga versiooni panna,
  • kuna GC-ga keeled ei sobi meile vastuvõetud liikluse olemuse tõttu (peaaegu reaalajas) ja GC-pausid on praktiliselt vastuvõetamatud,
  • sest vajate C-ga võrreldavat maksimaalset jõudlust
  • sest Rust pakub meile kartmatut samaaegsust ja kui me hakkaksime seda C/C++-s kirjutama, oleksime leidnud veelgi rohkem haavatavusi, puhvri ületäitumist, võistlustingimusi ja muid hirmutavaid sõnu kui brubeck.

Oli ka argument Rusti vastu. Ettevõttel puudus Rustis projektide loomise kogemus ja nüüd ei plaani me seda ka põhiprojektis kasutada. Seetõttu oli tõsine kartus, et midagi ei õnnestu, kuid otsustasime riskida ja proovisime.

Aeg läks...

Lõpuks, pärast mitut ebaõnnestunud katset, oli esimene tööversioon valmis. Mis juhtus? Nii juhtus.

Bioyino – hajutatud, skaleeritav mõõdikute koondaja

Iga sõlm saab oma mõõdikute komplekti ja akumuleerib need ning ei koonda mõõdikuid nende tüüpide jaoks, kus lõplikuks koondamiseks on vaja nende täielikku komplekti. Sõlmed on omavahel ühendatud mingi hajutatud lukuprotokolli abil, mis võimaldab valida nende hulgast ainukese (siin me nutsime), mis on väärt Suurele mõõdikuid saatma. Seda probleemi lahendab praegu Konsulaat, kuid tulevikus ulatuvad autori ambitsioonid oma rakendamine Parv, kus kõige väärikam on loomulikult konsensusliidri sõlm. Lisaks konsensusele saadavad sõlmed üsna sageli (vaikimisi üks kord sekundis) oma naabritele neid eelagregeeritud mõõdikute osi, mis neil õnnestus selle sekundi jooksul koguda. Selgub, et skaleerimine ja veataluvus on säilinud – iga sõlm sisaldab endiselt tervet mõõdikute komplekti, kuid mõõdikud saadetakse juba koondatuna, TCP kaudu ja kodeeritakse binaarprotokolli, nii et dubleerimiskulud vähenevad oluliselt võrreldes UDP-ga. Vaatamata üsna suurele sissetulevate mõõdikute arvule nõuab kogumine väga vähe mälu ja veelgi vähem protsessorit. Meie väga tihendatavate mertikute jaoks on see vaid mõnikümmend megabaiti andmemahtu. Täiendava boonusena ei saa me Graphite'is tarbetuid andmete ümberkirjutusi, nagu Burbecki puhul.

Mõõdikutega UDP-paketid on lihtsa Round Robini abil võrguseadmete sõlmede vahel tasakaalustamata. Muidugi ei parsi võrguriistvara pakettide sisu ja suudab seetõttu tõmmata palju rohkem kui 4M paketti sekundis, rääkimata mõõdikutest, mille kohta ta üldse midagi ei tea. Kui võtta arvesse, et mõõdikud ei tule igas paketis ükshaaval, siis ei näe me selles kohas jõudlusprobleeme ette. Kui server jookseb kokku, tuvastab võrguseade selle kiiresti (1-2 sekundi jooksul) ja eemaldab kokkujooksnud serveri pöörlemisest. Selle tulemusena saab passiivseid (st mitteliider) sõlmesid praktiliselt sisse ja välja lülitada ilma, et graafikutel oleks märkamata. Maksimum, mille me kaotame, on osa viimasel sekundil sisse tulnud mõõdikutest. Liidri äkiline kadumine/seiskamine/lülitamine tekitab siiski väikese anomaalia (30-sekundiline intervall on endiselt sünkroonist väljas), kuid kui sõlmede vahel on side, saab neid probleeme vähendada näiteks sünkroonimispakettide väljasaatmisega. .

Natuke sisestruktuurist. Rakendus on loomulikult mitmelõimeline, kuid keermestamise arhitektuur erineb brubeckis kasutatavast. Brubecki lõimed on samad - igaüks neist vastutab nii teabe kogumise kui ka koondamise eest. Bioyino puhul jagunevad töötajad kahte rühma: võrgustiku eest vastutavad ja koondamise eest vastutavad. See jaotus võimaldab rakendust paindlikumalt hallata olenevalt mõõdikute tüübist: kus on vajalik intensiivne koondamine, saab lisada agregaatoreid, kus on palju võrguliiklust, saab lisada võrguvoogude arvu. Hetkel töötame oma serverites 8 võrgu- ja 4 koondamisvoos.

Loendamise (liitmise eest vastutav) osa on üsna igav. Võrguvoogudega täidetud puhvrid jaotatakse loendusvoogude vahel, kus need seejärel sõelutakse ja koondatakse. Soovi korral antakse mõõdikud teistele sõlmedele saatmiseks. Kõik see, sealhulgas andmete saatmine sõlmede vahel ja töö Consuliga, toimub asünkroonselt, töötades raamistikus Tokyo.

Palju rohkem probleeme arenduse käigus tekitas mõõdikute vastuvõtmise eest vastutav võrguosa. Võrguvoogude eraldi üksusteks eraldamise peamine eesmärk oli soov vähendada aega, mille voog kulutab ei pesast andmete lugemiseks. Asünkroonset UDP-d ja tavalist recvmsg-d kasutavad valikud kadusid kiiresti: esimene kulutab sündmuste töötlemiseks liiga palju kasutajaruumi CPU-d, teine ​​nõuab liiga palju kontekstilülitusi. Seetõttu kasutatakse seda nüüd recvmmsg suurte puhvritega (ja puhvrid, härrased ohvitserid, pole teile midagi!). Tavalise UDP tugi on reserveeritud kergeteks juhtudel, kui recvmmsg pole vajalik. Mitme sõnumi režiimis on võimalik saavutada peamine: valdava enamuse ajast rehib võrgulõng OS-i järjekorda - loeb pesast andmeid ja edastab need kasutajaruumi puhvrisse, lülitudes vaid aeg-ajalt täispuhvri andmisele. agregaatorid. Järjekord pistikupesas praktiliselt ei kogune, väljakukkunud pakettide arv praktiliselt ei kasva.

Märkus

Vaikeseadetes on puhvri suurus seatud üsna suureks. Kui otsustate ootamatult serverit ise proovida, võite kokku puutuda tõsiasjaga, et pärast väikese arvu mõõdikute saatmist ei jõua need grafiiti, jäädes võrgu voopuhvrisse. Väikese arvu mõõdikutega töötamiseks peate konfiguratsioonis määrama bufsize ja task-queue-size väiksemad väärtused.

Lõpetuseks mõned edetabelid edetabeliarmastajatele.

Statistika iga serveri sissetulevate mõõdikute arvu kohta: üle 2 miljoni MPS.

Bioyino – hajutatud, skaleeritav mõõdikute koondaja

Ühe sõlme keelamine ja sissetulevate mõõdikute ümberjagamine.

Bioyino – hajutatud, skaleeritav mõõdikute koondaja

Väljaminevate mõõdikute statistika: alati saadab ainult üks sõlm - raid boss.

Bioyino – hajutatud, skaleeritav mõõdikute koondaja

Iga sõlme töö statistika, võttes arvesse erinevate süsteemimoodulite vigu.

Bioyino – hajutatud, skaleeritav mõõdikute koondaja

Sissetulevate mõõdikute üksikasjad (mõõdikute nimed on peidetud).

Bioyino – hajutatud, skaleeritav mõõdikute koondaja

Mida me selle kõigega edasi kavatseme teha? Muidugi kirjuta kood, kurat...! Projekt oli algselt kavandatud avatud lähtekoodiga ja jääb selliseks kogu selle eluea jooksul. Meie lähiplaanide hulka kuulub üleminek Raft oma versioonile, partnerprotokolli muutmine kaasaskantavamaks, täiendava sisemise statistika, uut tüüpi mõõdikute, veaparanduste ja muude täiustuste tutvustamine.

Loomulikult on kõik oodatud aitama projekti arendamisel: looma PR-i, Issues, võimalusel vastame, täiustame jne.

Seda öeldes, see on kõik, inimesed, ostke meie elevandid!



Allikas: www.habr.com

Lisa kommentaar