Bioyino - hajautettu, skaalautuva metriikkaaggregaattori

Joten keräät mittareita. Kuten olemme. Keräämme myös mittareita. Tietenkin välttämätön liiketoiminnalle. Tänään puhumme seurantajärjestelmämme ensimmäisestä linkistä - statsd-yhteensopivasta aggregointipalvelimesta bioyino, miksi kirjoitimme sen ja miksi hylkäsimme brubeckin.

Bioyino - hajautettu, skaalautuva metriikkaaggregaattori

Aiemmista artikkeleistamme (1, 2) saat selville, että kunnes jonkin aikaa keräsimme merkkejä käyttämällä Brubeck. Se on kirjoitettu C-kielellä. Koodin näkökulmasta se on yhtä yksinkertainen kuin pistoke (tämä on tärkeää, kun haluat osallistua) ja mikä tärkeintä, se käsittelee 2 miljoonan metriikkaa sekunnissa (MPS) huipussaan ilman ongelmia. Asiakirjoissa tuetaan 4 miljoonaa MPS:ää tähdellä. Tämä tarkoittaa, että saat ilmoitetun luvun, jos määrität verkon oikein Linuxissa. (Emme tiedä kuinka monta MPS:ää voit saada, jos jätät verkon sellaisenaan). Näistä eduista huolimatta meillä oli useita vakavia valituksia brubeckista.

Väite 1. Projektin kehittäjä Github lopetti sen tukemisen: korjausten ja korjausten julkaisemisen, meidän ja (ei vain meidän) PR:n hyväksymisen. Viime kuukausina (joskus helmi-maaliskuussa 2018) aktiviteetti on palautunut, mutta sitä ennen oli lähes 2 vuotta täydellistä rauhaa. Lisäksi hanketta kehitetään Gihubin sisäisiin tarpeisiin, josta voi tulla vakava este uusien ominaisuuksien käyttöönotolle.

Väite 2. Laskelmien tarkkuus. Brubeck kerää yhteensä 65536 arvoa aggregointia varten. Meidän tapauksessamme joidenkin mittareiden osalta koontijakson aikana (30 sekuntia) voi tulla paljon enemmän arvoja (1 527 392 huipulla). Tämän näytteenoton seurauksena maksimi- ja vähimmäisarvot näyttävät hyödyttömiltä. Esimerkiksi näin:

Bioyino - hajautettu, skaalautuva metriikkaaggregaattori
Kuten oli

Bioyino - hajautettu, skaalautuva metriikkaaggregaattori
Miten sen piti olla

Samasta syystä summat lasketaan yleensä väärin. Lisää tähän bugi 32-bittisellä float-ylivuodolla, joka yleensä lähettää palvelimen segfaultiin vastaanotettaessa näennäisesti viattoman mittarin, ja kaikki muuttuu hienoksi. Vikaa ei muuten ole korjattu.

Ja lopuksi, Vaatii X. Tätä kirjoittaessamme olemme valmiita esittelemään sen kaikille 14 enemmän tai vähemmän toimivalle statsd-toteutukselle, jotka löysimme. Kuvitellaanpa, että jokin yksittäinen infrastruktuuri on kasvanut niin paljon, että 4 miljoonan MPS:n hyväksyminen ei enää riitä. Tai vaikka se ei ole vielä kasvanut, mutta mittarit ovat jo sinulle niin tärkeitä, että lyhyetkin 2-3 minuutin putoamat kaavioissa voivat jo tulla kriittisiksi ja aiheuttaa ylitsepääsemättömiä masennuskohtauksia johtajien keskuudessa. Koska masennuksen hoito on kiittämätöntä, tarvitaan teknisiä ratkaisuja.

Ensinnäkin vikasietoisuus, jotta äkillinen ongelma palvelimella ei aiheuta psykiatrista zombi-apokalypsia toimistossa. Toiseksi, skaalaus yli 4 miljoonan MPS:n vastaanottamiseen ilman, että kaivetaan syvälle Linux-verkkopinoon ja kasvatetaan rauhallisesti "leveästi" vaadittuun kokoon.

Koska meillä oli tilaa skaalautumiseen, päätimme aloittaa vikasietoisuudella. "NOIN! Vikasietoisuus! Se on yksinkertaista, me pystymme siihen", ajattelimme ja käynnistimme kaksi palvelinta, jotka nostivat jokaiselle kopion brubeckista. Tätä varten meidän piti kopioida liikennettä mittareilla molemmille palvelimille ja jopa kirjoittaa tätä varten pieni hyöty. Ratkaisimme vikasieto-ongelman tällä, mutta... ei kovin hyvin. Aluksi kaikki vaikutti hienolta: jokainen brubeck kerää oman versionsa aggregaatiosta, kirjoittaa tiedot Grafiiteen kerran 30 sekunnissa ylikirjoittaen vanhan aikavälin (tämä tehdään grafiitin puolella). Jos yksi palvelin yhtäkkiä epäonnistuu, meillä on aina toinen palvelin, jolla on oma kopio aggregoidusta tiedosta. Mutta tässä on ongelma: jos palvelin epäonnistuu, "saha" näkyy kaavioissa. Tämä johtuu siitä, että brubeckin 30 sekunnin intervallit eivät ole synkronoituja, eikä yhtä niistä kirjoiteta päälle törmäyshetkellä. Kun toinen palvelin käynnistyy, tapahtuu sama asia. Ihan siedettävää, mutta haluan parempaa! Myöskään skaalautuvuusongelma ei ole poistunut. Kaikki mittarit "lentävät" edelleen yhdelle palvelimelle, ja siksi olemme rajoitettu samaan 2-4 miljoonaan MPS:ään verkkotasosta riippuen.

Jos vähän mietit ongelmaa ja samalla kaivaa lunta lapiolla, niin mieleen saattaa tulla seuraava ilmeinen idea: tarvitset statsd:n, joka voi toimia hajautetussa tilassa. Toisin sanoen sellainen, joka toteuttaa synkronoinnin solmujen välillä ajassa ja mittareissa. "Tietenkin, tällainen ratkaisu on todennäköisesti jo olemassa", sanoimme ja menimme Googleen…. Ja he eivät löytäneet mitään. Käytyäsi läpi eri statsd-dokumentaation (https://github.com/etsy/statsd/wiki#server-implementations 11.12.2017. joulukuuta XNUMX mennessä), emme löytäneet mitään. Ilmeisesti näiden ratkaisujen kehittäjät tai käyttäjät eivät ole vielä törmänneet NIIN moniin mittareihin, muuten he varmasti keksivät jotain.

Ja sitten muistimme "lelu" statsd - bioyino, joka kirjoitettiin Just for Fun -hackathonissa (projektin nimi on luotu käsikirjoituksesta ennen hackathonin alkua) ja tajusimme, että tarvitsemme kiireellisesti oman tilastomme. Minkä vuoksi?

  • koska maailmassa on liian vähän statsd-klooneja,
  • koska on mahdollista tarjota haluttu tai lähellä haluttua vikasietoisuutta ja skaalautuvuutta (mukaan lukien aggregoitujen mittareiden synkronointi palvelimien välillä ja lähetysristiriitojen ratkaiseminen),
  • koska on mahdollista laskea mittareita tarkemmin kuin brubeck,
  • koska voit kerätä itse tarkempia tilastoja, joita brubeck ei käytännössä toimittanut meille,
  • koska minulla oli mahdollisuus ohjelmoida oma hyperperformance-hajautetun mittakaavan laboratoriosovellus, joka ei täysin toista toisen samanlaisen hyperfor-arkkitehtuuria... no, siinä se.

Mihin kirjoittaa? Tietysti Rustissa. Miksi?

  • koska prototyyppiratkaisu oli jo olemassa,
  • koska artikkelin kirjoittaja tunsi Rustin jo tuolloin ja halusi kirjoittaa siihen jotain tuotantoa varten mahdollisuudella laittaa se avoimeen lähdekoodiin,
  • koska kielet, joissa on GC, eivät sovi meille vastaanotetun liikenteen luonteen vuoksi (melkein reaaliaikaisesti) ja GC-taukoja ei käytännössä voida hyväksyä,
  • koska tarvitset maksimaalisen suorituskyvyn, joka on verrattavissa C:hen
  • koska Rust tarjoaa meille pelottoman samanaikaisuuden, ja jos olisimme alkaneet kirjoittaa sitä C/C++:lla, olisimme löytäneet vielä enemmän haavoittuvuuksia, puskureiden ylivuotoja, kilpailuolosuhteita ja muita pelottavia sanoja kuin brubeck.

Oli myös argumentti Rustia vastaan. Yrityksellä ei ollut kokemusta projektien luomisesta Rustissa, emmekä nyt myöskään aio käyttää sitä pääprojektissa. Siksi pelättiin vakavia, että mikään ei onnistu, mutta päätimme ottaa riskin ja yritimme.

Aika kului...

Lopulta, useiden epäonnistuneiden yritysten jälkeen, ensimmäinen toimiva versio oli valmis. Mitä tapahtui? Näin tapahtui.

Bioyino - hajautettu, skaalautuva metriikkaaggregaattori

Jokainen solmu vastaanottaa oman metriikkajoukonsa ja kerää ne, eikä kokoa mittareita sellaisille tyypeille, joissa niiden koko joukko vaaditaan lopulliseen aggregointiin. Solmut on yhdistetty toisiinsa jonkinlaisella hajautetulla lukitusprotokollalla, jonka avulla voit valita niistä ainoan (tässä itkimme), joka on arvoinen lähettämään mittareita Suurelle. Tätä ongelmaa ratkaisee parhaillaan Konsuli, mutta tulevaisuudessa kirjailijan tavoitteet ulottuvat oma toteutus Lautta, jossa arvokkain on tietysti konsensusjohtajasolmu. Konsensuksen lisäksi solmut lähettävät melko usein (oletusarvoisesti kerran sekunnissa) naapureilleen ne osat esikoostetuista mittareista, jotka he onnistuivat keräämään sillä sekunnilla. Osoittautuu, että skaalaus ja vikasietoisuus säilyvät - jokaisessa solmussa on edelleen täysi joukko mittareita, mutta mittarit lähetetään valmiiksi koottuna TCP:n kautta ja koodataan binääriprotokollaksi, joten päällekkäisyyskustannukset pienenevät merkittävästi UDP:hen verrattuna. Huolimatta saapuvien mittareiden melko suuresta määrästä, kerääminen vaatii hyvin vähän muistia ja vielä vähemmän prosessoria. Erittäin pakattavissa oleville merticsillemme tämä on vain muutamia kymmeniä megatavuja dataa. Lisäbonuksena emme saa tarpeettomia tietojen uudelleenkirjoituksia Graphitessa, kuten Burbeckin tapauksessa.

Mittarilliset UDP-paketit ovat epätasapainossa verkkolaitteiden solmujen välillä yksinkertaisen Round Robinin avulla. Tietenkään verkkolaitteisto ei jäsennä pakettien sisältöä ja voi siksi vetää paljon enemmän kuin 4 miljoonaa pakettia sekunnissa, puhumattakaan mittareista, joista se ei tiedä juuri mitään. Jos otamme huomioon, että mittarit eivät tule yksi kerrallaan jokaisessa paketissa, emme näe tässä paikassa suorituskykyongelmia. Jos palvelin kaatuu, verkkolaite havaitsee nopeasti (1-2 sekunnissa) tämän tosiasian ja poistaa kaatuneen palvelimen kierrosta. Tämän seurauksena passiiviset (eli ei-leader-) solmut voidaan kytkeä päälle ja pois käytännössä huomaamatta kaavioiden laskuja. Enimmäismäärä, jonka menetämme, on osa viimeisellä sekunnilla saapuneista mittareista. Johtajan äkillinen menetys/sammutus/vaihto aiheuttaa silti pienen poikkeaman (30 sekunnin aikaväli on edelleen epäsynkronissa), mutta jos solmujen välillä on kommunikaatiota, näitä ongelmia voidaan minimoida esimerkiksi lähettämällä synkronointipaketteja. .

Hieman sisäisestä rakenteesta. Sovellus on tietysti monisäikeinen, mutta ketjutusarkkitehtuuri eroaa brubeckissa käytetystä. Brubeckin säikeet ovat samat - jokainen niistä vastaa sekä tiedon keräämisestä että yhdistämisestä. Bioyinossa työntekijät jaetaan kahteen ryhmään: verkostosta vastaaviin ja aggregoinnista vastaaviin. Tämän jaon avulla voit hallita sovellusta joustavammin mittareiden tyypistä riippuen: missä tarvitaan intensiivistä aggregointia, voit lisätä aggregaattoreita, missä on paljon verkkoliikennettä, voit lisätä verkkovirtojen määrää. Tällä hetkellä palvelimillamme työskentelemme 8 verkko- ja 4 aggregaatiovirrassa.

Laskentaosa (vastaa yhdistämisestä) on melko tylsää. Verkkovirtojen täyttämät puskurit jaetaan laskentavirtojen kesken, jossa ne jäsennetään ja aggregoidaan. Pyynnöstä mittarit annetaan muille solmuille lähettämistä varten. Kaikki tämä, mukaan lukien tiedon lähettäminen solmujen välillä ja työskentely Consulin kanssa, suoritetaan asynkronisesti, ajettaessa kehyksessä Tokio.

Paljon enemmän ongelmia kehityksen aikana aiheutti mittareiden vastaanottamisesta vastaava verkkoosa. Päätavoitteena verkkovirtojen erottamisessa erillisiksi kokonaisuuksiksi oli halu vähentää virtauksen käyttämää aikaa ei lukemaan tietoja socketista. Asynkronista UDP:tä ja tavallista recvmsg:tä käyttävät vaihtoehdot katosivat nopeasti: ensimmäinen kuluttaa liian paljon käyttäjätilaa tapahtumien käsittelyyn, toinen vaatii liian monta kontekstikytkintä. Siksi se on nyt käytössä recvmmsg suurilla puskureilla (ja puskurit, herrat upseerit, eivät ole mitään teille!). Tavallisen UDP:n tuki on varattu kevyille tapauksille, joissa recvmmsg:tä ei tarvita. Moniviestitilassa on mahdollista saavuttaa pääasia: suurimman osan ajasta verkkosäie haravoi käyttöjärjestelmän jonon - lukee tiedot socketista ja siirtää ne käyttäjätilapuskuriin, vain satunnaisesti siirtyen antamaan täytetyn puskurin aggregaattoreita. Jono pistorasiassa ei käytännössä kerry, pudonneiden pakettien määrä ei käytännössä kasva.

Huomata

Oletusasetuksissa puskurin koko on asetettu melko suureksi. Jos päätät yhtäkkiä kokeilla palvelinta itse, saatat kohdata sen tosiasian, että pienen määrän mittareita lähettämisen jälkeen ne eivät pääse grafiittiin vaan jäävät verkkovirtapuskuriin. Jotta voit työskennellä pienen määrän mittareilla, sinun on asetettava bufsize- ja task-queue-size-arvot pienemmiksi konfiguraatiossa.

Lopuksi joitain kaavioita kaavioiden ystäville.

Tilastot kunkin palvelimen saapuvien mittareiden määrästä: yli 2 miljoonaa MPS.

Bioyino - hajautettu, skaalautuva metriikkaaggregaattori

Yhden solmun poistaminen käytöstä ja saapuvien mittareiden jakaminen uudelleen.

Bioyino - hajautettu, skaalautuva metriikkaaggregaattori

Tilastot lähtevistä mittareista: vain yksi solmu lähettää aina - raidpomo.

Bioyino - hajautettu, skaalautuva metriikkaaggregaattori

Tilastot kunkin solmun toiminnasta ottaen huomioon eri järjestelmämoduulien virheet.

Bioyino - hajautettu, skaalautuva metriikkaaggregaattori

Saapuvien mittareiden yksityiskohdat (mittareiden nimet on piilotettu).

Bioyino - hajautettu, skaalautuva metriikkaaggregaattori

Mitä aiomme tehdä tämän kaiken kanssa seuraavaksi? Tietenkin, kirjoita koodi, vittu...! Projekti suunniteltiin alun perin avoimeksi lähdekoodiksi ja tulee olemaan sitä koko sen elinkaaren ajan. Lähisuunnitelmiimme kuuluu vaihtaminen omaan Raft-versioomme, vertaisprotokollan vaihtaminen kannettavaan, sisäisten lisätilastojen, uudentyyppisten mittareiden, virheenkorjausten ja muiden parannusten käyttöönotto.

Tietysti kaikki ovat tervetulleita auttamaan projektin kehittämisessä: luo PR, Issues, mikäli mahdollista vastaamme, parannamme jne.

Näin sanoen, siinä kaikki, ihmiset, ostakaa norsumme!



Lähde: will.com

Lisää kommentti