[Itzulpena] Envoy hari eredua

Artikuluaren itzulpena: Envoy hari eredua - https://blog.envoyproxy.io/envoy-threading-model-a8d44b922310

Artikulu hau nahiko interesgarria iruditu zait, eta Envoy kubernetes-en "istio"-ren zati gisa edo, besterik gabe, "sarrera-kontrolatzaile" gisa erabiltzen denez, jende gehienak ez du harekin, adibidez, ohikoekin duen interakzio zuzen bera. Nginx edo Haproxy instalazioak. Hala ere, zerbait apurtzen bada, ondo legoke barrutik nola funtzionatzen duen ulertzea. Testuaren zatirik handiena errusierara itzultzen saiatu naiz, hitz bereziak barne; hau ikustea mingarria iruditzen zaienei, jatorrizkoak parentesi artean utzi ditut. Ongi etorri katura.

Envoy kode-baserako maila baxuko dokumentazio teknikoa nahiko urria da. Hori konpontzeko, Envoy-en azpisistema ezberdinei buruzko blog-argitalpen sorta bat egiteko asmoa dut. Hau lehen artikulua denez, mesedez, esan iezadazu zer iruditzen zaizun eta zertan interesatuko zaizun hurrengo artikuluetan.

Envoy-i buruz jasotzen dudan galdera tekniko ohikoenetako bat erabiltzen duen hari-ereduaren maila baxuko deskribapena eskatzea da. Argitalpen honetan, Envoy-ek harietarako konexioak nola mapatzen dituen deskribatuko dut, baita barnean erabiltzen duen Thread Local Storage sistema kodea paraleloagoa eta errendimendu handikoagoa izan dadin.

Threading ikuspegi orokorra

[Itzulpena] Envoy hari eredua

Envoy-ek hiru korronte mota erabiltzen ditu:

  • Nagusia: Hari honek prozesuak abiaraztea eta amaitzea kontrolatzen ditu, XDS (xDiscovery Zerbitzua) APIaren prozesamendu guztia, DNS barne, osasun-egiaztapena, kluster orokorra eta exekuzio-denboraren kudeaketa, estatistikak berrezartzea, administrazioa eta prozesuen kudeaketa orokorra - Linux seinaleak. Berrabiarazi beroa, etab. hari honetan gertatzen da asinkronoa eta "ez-blokeagarria". Oro har, hari nagusiak exekutatzeko CPU kopuru handirik behar ez duten funtzionaltasun prozesu kritiko guztiak koordinatzen ditu. Horri esker, kontrol-kode gehiena hari bakarrekoa izango balitz bezala idatzi daiteke.
  • Langilea: Lehenespenez, Envoy-ek langile-hari bat sortzen du sistemako hardware-hari bakoitzeko, hau aukeraren bidez kontrola daiteke --concurrency. Langile-hari bakoitzak "blokeatzen ez duen" gertaera-begizta bat exekutatzen du, entzule bakoitza entzuteaz arduratzen dena; idazteko unean (29ko uztailaren 2017an) ez dago entzulearen zatiketarik, konexio berriak onartuz, iragazki pila bat instantziatuz. konexioa eta sarrera/irteera (IO) eragiketa guztiak prozesatzen ditu konexioaren bizitzan zehar. Berriz ere, honek konexioa kudeatzeko kode gehiena hari bakarrekoa izango balitz bezala idazteko aukera ematen du.
  • Fitxategien garbigailua: Envoy-ek idazten duen fitxategi bakoitzak, batez ere sarbide-erregistroak, blokeatzeko hari independente bat dauka. Erabiltzean ere fitxategi-sistemak cachean gordetako fitxategietan idazten duelako da hori O_NONBLOCK batzuetan blokeatu egin daiteke (hasperena). Langileen hariek fitxategi batean idatzi behar dutenean, datuak benetan memoriako buffer batera mugitzen dira, non azkenean hariaren bidez garbitzen diren. fitxategia garbitu. Hau kode-eremu bat da, non teknikoki langile-hari guztiek blokeo bera blokeatu dezaketen memoria-buffer bat betetzen saiatzen diren bitartean.

Konexioen kudeaketa

Goian laburki esan bezala, langileen hari guztiek entzule guztiak entzuten dituzte inolako zatiketarik gabe. Horrela, nukleoa langileen harietara onartutako socketak dotoretasunez bidaltzeko erabiltzen da. Nukleo modernoak, oro har, oso onak dira horretan, sarrera/irteera (IO) lehentasuna areagotzea bezalako ezaugarriak erabiltzen dituzte hari bat lanarekin betetzen saiatzeko, socket berean entzuten ari diren beste hari batzuk erabiltzen hasi aurretik, eta, gainera, round robin erabiltzen ez dutenak. blokeatzea (Spinlock) eskaera bakoitza prozesatzeko.
Behin konexio bat langile-hari batean onartzen denean, ez da inoiz hari hori uzten. Konexioaren prozesamendu gehiago langilearen harian kudeatzen da guztiz, birbidaltze-jokabide oro barne.

Horrek hainbat ondorio garrantzitsu ditu:

  • Envoy-eko konexio-talde guztiak langile-hari bati esleitzen zaizkio. Beraz, HTTP/2 konexio-taldeek aldi berean gorako ostalari bakoitzarekin konexio bakarra egiten badute ere, lau langile-hari badaude, lau HTTP/2 konexio egongo dira gorako ostalari bakoitzeko egoera egonkorrean.
  • Envoy-ek horrela funtzionatzen duen arrazoia hauxe da: dena langile-hari bakarrean mantenduz, ia kode guztia blokeatu gabe idatzi daitekeela eta hari bakarrekoa izango balitz bezala. Diseinu honek kode asko idaztea errazten du eta oso ondo eskalatzen du langile-hari kopuru ia mugagabe batera.
  • Hala ere, ondorio nagusietako bat da memoria-taldearen eta konexioaren eraginkortasunaren ikuspegitik oso garrantzitsua dela konfiguratzea. --concurrency. Behar baino langile-hari gehiago edukitzeak memoria alferrik galduko du, konexio inaktibo gehiago sortuko ditu eta konexio-bilketa-tasa murriztuko du. Lyft-en, gure envoy sidecar-eko edukiontziak oso konkurrentzia baxuarekin ibiltzen dira, errendimendua gutxi gorabehera ondoan dauden zerbitzuekin bat datorren. Envoy ertzeko proxy gisa exekutatzen dugu aldi berean gehienez.

Zer esan nahi du ez blokeatzea?

"Blokeatu gabeko" terminoa hainbat aldiz erabili da orain arte hari nagusiak eta langileak nola funtzionatzen duten aztertzerakoan. Kode guztia inoiz ez dela ezer blokeatuta idatzita dago. Hala ere, hori ez da guztiz egia (zer ez da guztiz egia?).

Envoy-ek prozesu luzeko hainbat blokeo erabiltzen ditu:

  • Esan bezala, sarbide-erregistroak idaztean, langile-hari guztiek blokeo bera eskuratzen dute memoriako erregistro-bufferra bete aurretik. Blokeoaren euste-denborak oso baxua izan behar du, baina baliteke blokeoa aldiberekotasun handian eta errendimendu handian lehiatzea.
  • Envoy-ek sistema oso konplexua erabiltzen du hariaren tokikoak diren estatistikak kudeatzeko. Hau aparteko mezu baten gaia izango da. Hala ere, labur-labur aipatuko dut harien estatistikak lokalean prozesatzeko parte gisa, batzuetan beharrezkoa dela "estatistika-denda" zentral batean blokeoa eskuratzea. Blokeo hori ez da inoiz beharrezkoa izan behar.
  • Hari nagusiak aldiro langileen hari guztiekin koordinatu behar du. Hau hari nagusitik langileen harietara "argitaltzen" egiten da, eta batzuetan langileen harietatik berriro hari nagusira. Bidaltzeko blokeoa behar da, argitaratutako mezua ilaran jarri ahal izateko gero entregatzeko. Blokeo hauek ez dira inoiz serioski eztabaidatu behar, baina oraindik teknikoki blokeatu daitezke.
  • Envoy-ek sistemako errore-korrontean erregistro bat idazten duenean (errore estandarra), prozesu osoan blokeoa lortzen du. Oro har, Envoy-en tokiko erregistroa ikaragarritzat jotzen da errendimenduaren ikuspuntutik, beraz, ez zaio arreta handirik eman hura hobetzeko.
  • Badira beste ausazko blokeo batzuk, baina horietako bat ere ez da errendimendu kritikoa eta ez litzateke inoiz zalantzan jarri behar.

Hari biltegiratze lokala

Envoy-ek hari nagusiaren ardurak eta langilearen hariaren ardurak bereizten dituen moduagatik, hari nagusian prozesamendu konplexua egin eta gero langile hari bakoitzari modu oso aldi berean eman dakiokeen baldintza dago. Atal honek Envoy Thread Local Storage (TLS) maila altuan deskribatzen du. Hurrengo atalean kluster bat kudeatzeko nola erabiltzen den deskribatuko dut.
[Itzulpena] Envoy hari eredua

Dagoeneko deskribatu bezala, hari nagusiak Envoy prozesuan kudeaketa eta kontrol-planoaren funtzionaltasun ia guztiak kudeatzen ditu. Kontrol-hegazkina pixka bat gainkargatuta dago hemen, baina Envoy prozesuaren barruan begiratu eta langile-hariak egiten duten birbidalketarekin alderatzen duzunean, zentzuzkoa da. Arau orokorra da hari-prozesu nagusiak lan batzuk egiten dituela eta, ondoren, langile-hari bakoitza eguneratu behar duela lan horren emaitzaren arabera. kasu honetan, langilearen hariak ez du sarbide bakoitzean blokeorik eskuratu behar.

Envoy-en TLS (Thread local storage) sistemak honela funtzionatzen du:

  • Hari nagusian exekutatzen den kodeak TLS zirrikitua esleitu dezake prozesu osorako. Hau abstrakzioa bada ere, praktikan bektore bateko indize bat da, O(1) sarbidea ematen duena.
  • Hari nagusiak datu arbitrarioak instala ditzake bere zirrikituan. Hori egiten denean, datuak langile-hari bakoitzean argitaratzen dira gertaera-begizta-gertaera normal gisa.
  • Langileen hariek beren TLS zirrikitutik irakur ditzakete eta bertan dauden hari lokaleko edozein datu berreskura ditzakete.

Paradigma oso sinplea eta izugarri indartsua den arren, RCU (Irakurri-Kopia-Eguneratu) blokeoaren kontzeptuaren oso antzekoa da. Funtsean, langileen hariek ez dute inoiz datu aldaketarik ikusten TLS zirrikituetan, lana martxan dagoen bitartean. Aldaketa laneko ekitaldien arteko atsedenaldian bakarrik gertatzen da.

Envoy-ek bi modu desberdinetan erabiltzen du:

  • Langilearen hari bakoitzean datu desberdinak gordeta, datuak blokeatu gabe atzi daitezke.
  • Langileen hari bakoitzean datu globaletarako erakusle partekatua irakurtzeko soilik moduan mantenduz. Horrela, langile-hari bakoitzak datu-erreferentzia-zenbaketa bat du, eta ezin da gutxitu lana martxan dagoen bitartean. Langile guztiak lasaitzen direnean eta partekatutako datu berriak igotzen direnean soilik suntsituko dira datu zaharrak. Hau RCUren berdina da.

Klusterraren eguneratze-haria

Atal honetan, kluster bat kudeatzeko TLS (Thread local storage) nola erabiltzen den deskribatuko dut. Klusterren kudeaketa xDS APIa eta/edo DNS prozesatzea barne hartzen du, baita osasun-egiaztapena ere.
[Itzulpena] Envoy hari eredua

Kluster-fluxuaren kudeaketak osagai eta urrats hauek ditu:

  1. Cluster Manager Envoy-eko osagai bat da, ezagutzen diren kluster upstream guztiak, Cluster Discovery Service (CDS) APIa, Secret Discovery Service (SDS) eta Endpoint Discovery Service (EDS) APIak, DNS eta kanpoko egiaztapen aktiboak. Goragoko kluster bakoitzaren ikuspegi "azkenean koherentea" sortzeaz arduratzen da, aurkitutako ostalariak eta osasun egoera barne hartzen dituena.
  2. Osasun-egiaztapenak osasun-egiaztapen aktibo bat egiten du eta osasun-egoeraren aldaketen berri ematen dio kluster-kudeatzaileari.
  3. CDS (Cluster Discovery Service) / SDS (Secret Discovery Service) / EDS (Endpoint Discovery Service) / DNS egiten dira kluster-kidetasuna zehazteko. Egoera-aldaketa kluster kudeatzaileari itzultzen zaio.
  4. Langile-hari bakoitzak gertaeren begizta bat exekutatzen du etengabe.
  5. Kluster-kudeatzaileak kluster baten egoera aldatu dela zehazten duenean, kluster-aren egoeraren irakurtzeko soilik den argazki berri bat sortzen du eta langile-hari bakoitzari bidaltzen dio.
  6. Hurrengo isilunean, langile-hariak esleitutako TLS zirrikituan argazkia eguneratuko du.
  7. Ostalariaren karga orekatzeko zehaztu behar duen I/O gertaera batean, karga-orekatzaileak TLS (Thread local storage) zirrikitua eskatuko du ostalariari buruzko informazioa lortzeko. Honek ez du blokeorik behar. Kontuan izan, gainera, TLS-k eguneratze-gertaerak abiarazi ditzakeela, karga-orekatzaileek eta beste osagai batzuek cacheak, datu-egiturak, etab. Hau mezu honen esparrutik kanpo dago, baina kodean hainbat lekutan erabiltzen da.

Goiko prozedura erabiliz, Envoy-ek eskaera guztiak prozesatu ditzake inolako blokeorik gabe (lehen azaldutakoa izan ezik). TLS kodearen konplexutasunaz gain, kode gehienak ez du ulertu behar multithreading nola funtzionatzen duen eta hari bakarrean idatz daiteke. Horrek kode gehiena errazagoa egiten du errendimendu handiagoaz gain.

TLS erabiltzen duten beste azpisistema batzuk

TLS (Thread local storage) eta RCU (Read Copy Update) oso erabiliak dira Envoy-en.

Erabilera adibideak:

  • Exekuzioan funtzionaltasuna aldatzeko mekanismoa: Gaitutako funtzionalitateen uneko zerrenda hari nagusian kalkulatzen da. Langile-hari bakoitzari irakurtzeko soilik den argazki bat ematen zaio RCU semantika erabiliz.
  • Ibilbide-taulak ordezkatzea: RDS-k (Route Discovery Service) eskaintzen dituen ibilbide-tauletarako, ibilbide-taulak hari nagusian sortzen dira. Ondoren, irakurtzeko soilik den argazkia langile-hari bakoitzari emango zaio RCU (Read Copy Update) semantika erabiliz. Horrek ibilbide-taulak aldatzea atomikoki eraginkorra bihurtzen du.
  • HTTP goiburuko cachea: Bihurtzen denez, eskaera bakoitzaren HTTP goiburua kalkulatzea (nukleo bakoitzeko ~25K+ RPS exekutatzen den bitartean) nahiko garestia da. Envoy-ek goiburua erdialdetik kalkulatzen du gutxi gorabehera segundo erdiro eta langile bakoitzari ematen dio TLS eta RCU bidez.

Badaude beste kasu batzuk, baina aurreko adibideek TLS zertarako erabiltzen den ondo ulertu beharko lukete.

Errendimendu-zulo ezagunak

Envoy-ek orokorrean nahiko ondo funtzionatzen duen arren, badaude arreta behar duten arlo aipagarri batzuk aldiberekotasun eta errendimendu oso handiarekin erabiltzen denean:

  • Artikulu honetan deskribatzen den bezala, gaur egun langile-hari guztiek blokeoa lortzen dute sarbide-erregistroko memoria-bufferean idaztean. Aldiberetasun handian eta errendimendu handian, lan-hari bakoitzaren sarbide-erregistroak lotu beharko dituzu azken fitxategian idaztean ordenaz kanpoko entregaren kontura. Bestela, sarbide-erregistro bereizia sor dezakezu langile-hari bakoitzeko.
  • Estatistikak oso optimizatuta dauden arren, aldiberekotasun eta errendimendu oso altuetan, ziurrenik, banakako estatistiketan gatazka atomikoa egongo da. Arazo honen konponbidea langile hari bakoitzeko kontagailuak dira, kontagailu zentralen aldizkako berrezartzearekin. Hau hurrengo post batean eztabaidatuko da.
  • Egungo arkitekturak ez du ondo funtzionatuko Envoy prozesatzeko baliabide garrantzitsuak behar dituzten konexio gutxi dauden eszenatoki batean hedatzen bada. Ez dago bermatzen konexioak langileen harien artean uniformeki banatuko direnik. Hau konpon daiteke langileen konexioen oreka ezarriz, eta horrek langileen harien arteko konexioak trukatzea ahalbidetuko du.

Ondorioa

Envoy-en hari-eredua programatzeko erraztasuna eta paralelismo masiboa eskaintzeko diseinatuta dago, behar bezala konfiguratzen ez badira memoria eta konexioak alfer litezkeen kaltetan. Eredu honek oso ondo funtzionatzen du hari-kopuru eta errendimendu oso altuetan.
Twitter-en laburki aipatu dudan bezala, diseinua erabiltzaile-modu osoko sare-pila baten gainean ere exekutatu daiteke, hala nola DPDK (Data Plane Development Kit), eta horrek zerbitzari konbentzionalek segundoko milioika eskaera kudeatzen ditu L7 prozesatu osoarekin. Oso interesgarria izango da hurrengo urteetan zer eraikitzen den ikustea.
Azken iruzkin azkar bat: askotan galdetu didate zergatik aukeratu dugun C++ Envoy-erako. Arrazoiak oraindik ere oso erabilia den industria-mailako hizkuntza bakarra dela argitalpen honetan deskribatutako arkitektura eraiki daiteke. C++, zalantzarik gabe, ez da egokia proiektu guztietarako, ezta proiektu askotarako ere, baina erabilera-kasu jakin batzuetan lana egiteko tresna bakarra da oraindik.

Koderako estekak

Argitalpen honetan eztabaidatutako interfazeak eta goiburuko inplementazioak dituzten fitxategietarako estekak:

Iturria: www.habr.com

Gehitu iruzkin berria