[Traduko] Envoy-fadenadmodelo

Traduko de la artikolo: Envoy-fadena modelo - https://blog.envoyproxy.io/envoy-threading-model-a8d44b922310

Mi trovis ĉi tiun artikolon sufiĉe interesa, kaj ĉar Envoy estas plej ofte uzata kiel parto de la "istio" aŭ simple kiel la "enirregilo" de kubernetoj, plej multaj homoj ne havas la saman rektan interagadon kun ĝi kiel, ekzemple, kun tipaj. Instalaĵoj de Nginx aŭ Haproxy. Tamen, se io rompas, estus bone kompreni kiel ĝi funkcias de interne. Mi provis traduki kiel eble plej multe de la teksto en la rusan, inkluzive de specialaj vortoj; por tiuj, kiuj trovas tion dolorige rigardi, mi lasis la originalojn inter krampoj. Bonvenon al kato.

Malaltnivela teknika dokumentaro por la Envoy-kodbazo estas nuntempe sufiĉe malabunda. Por solvi ĉi tion, mi planas fari serion da blogaj afiŝoj pri la diversaj subsistemoj de Envoy. Ĉar ĉi tiu estas la unua artikolo, bonvolu sciigi al mi, kion vi pensas kaj pri kio vi povus interesiĝi en estontaj artikoloj.

Unu el la plej oftaj teknikaj demandoj, kiujn mi ricevas pri Envoy, petas malaltnivelan priskribon de la surfadena modelo, kiun ĝi uzas. En ĉi tiu afiŝo, mi priskribos kiel Envoy mapas konektojn al fadenoj, same kiel la Thread Local Storage-sistemon, kiun ĝi uzas interne por fari kodon pli paralela kaj alt-efika.

Superrigardo pri fadenado

[Traduko] Envoy-fadenadmodelo

Envoy uzas tri malsamajn specojn de riveretoj:

  • Ĉefa: Ĉi tiu fadeno kontrolas procezon ekfunkciigon kaj finon, ĉian prilaboradon de la XDS (xDiscovery Service) API, inkluzive de DNS, sankontrolado, ĝenerala grapolo kaj rultempa administrado, statistiko rekomencigita, administrado kaj ĝenerala proceza administrado - Linukso-signaloj, varma rekomenco, ktp. okazas en ĉi tiu fadeno estas nesinkrona kaj "nebloka". Ĝenerale, la ĉefa fadeno kunordigas ĉiujn kritikajn funkciecprocezojn, kiuj ne postulas grandan kvanton da CPU por funkcii. Ĉi tio permesas al plej multe de la kontrolkodo esti skribita kvazaŭ ĝi estus ununura fadena.
  • Laboristo: Defaŭlte, Envoy kreas laborfadenon por ĉiu aparatara fadeno en la sistemo, ĉi tio povas esti kontrolita per la opcio --concurrency. Ĉiu laborfadeno prizorgas "ne-blokan" okazaĵbuklon, kiu respondecas pri aŭskultado de ĉiu aŭskultanto; dum la skribado (la 29-an de julio 2017) ekzistas neniu sharding de la aŭskultanto, akceptante novajn ligojn, kreante filtrilon por la konekto, kaj prilaborado de ĉiuj enigo/eligo (IO) operacioj dum la vivdaŭro de la ligo. Denove, ĉi tio permesas al la plej granda parto de konekttraktadkodo esti skribita kvazaŭ ĝi estus ununura fadena.
  • Dosiera fluŝilo: Ĉiu dosiero, kiun Envoy skribas, ĉefe alirprotokoloj, nuntempe havas sendependan blokan fadenon. Ĉi tio estas pro la fakto, ke skribado al dosieroj konservitaj de la dosiersistemo eĉ kiam vi uzas O_NONBLOCK povas foje esti blokita (suspiro). Kiam laboristaj fadenoj devas skribi al dosiero, la datumoj estas fakte movitaj al bufro en memoro kie ĝi estas poste fluita tra la fadeno. dosiero flush. Ĉi tio estas unu areo de kodo kie teknike ĉiuj laborfadenoj povas bloki la saman seruron provante plenigi memorbufron.

Pritraktado de konekto

Kiel diskutite mallonge supre, ĉiuj laborfadenoj aŭskultas ĉiujn aŭskultantojn sen ia sharding. Tiel, la kerno estas uzata por gracie sendi akceptitajn ingojn al laborfadenoj. Modernaj kernoj estas ĝenerale tre lertaj pri tio, ili uzas funkciojn kiel enigo/eligo (IO) prioritata akcelo por provi plenigi fadenon per laboro antaŭ ol ili komencas uzi aliajn fadenojn kiuj ankaŭ aŭskultas sur la sama ingo, kaj ankaŭ ne uzanta round robin. ŝlosado (Spinlock) por procesi ĉiun peton.
Post kiam konekto estas akceptita sur laborfadeno, ĝi neniam forlasas tiun fadenon. Ĉiu plia prilaborado de la konekto estas pritraktita tute en la laborfadeno, inkluzive de iu ajn plusendado-konduto.

Ĉi tio havas plurajn gravajn konsekvencojn:

  • Ĉiuj konektgrupoj en Envoy estas asignitaj al laborfadeno. Do, kvankam HTTP/2-konektoj nur faras unu konekton al ĉiu kontraŭflua gastiganto samtempe, se estas kvar laborfadenoj, estos kvar HTTP/2-konektoj per kontraŭflua gastiganto en stabila stato.
  • La kialo, kial Envoy funkcias tiel, estas, ke konservante ĉion sur ununura laborfadeno, preskaŭ ĉiuj kodoj povas esti skribitaj sen blokado kaj kvazaŭ ĝi estus ununura fadeno. Ĉi tiu dezajno faciligas skribi multan kodon kaj skalas nekredeble bone al preskaŭ senlima nombro da laborfadenoj.
  • Tamen, unu el la ĉefaj konsideroj estas, ke el memora naĝejo kaj konektefikeca vidpunkto, estas fakte tre grave agordi la --concurrency. Havi pli da laborfadenoj ol necese malŝparos memoron, kreos pli neaktivajn ligojn kaj reduktos la indicon de konekto-kunigo. Ĉe Lyft, niaj senditaj flankaj ujoj funkcias kun tre malalta samtempeco tiel ke agado proksimume kongruas kun la servoj, ĉe kiuj ili sidas. Ni kuras Envoy kiel randa prokurilo nur ĉe maksimuma samtempeco.

Kion signifas neblokado?

La esprimo "ne-blokado" estis uzata plurfoje ĝis nun kiam oni diskutas kiel funkcias la ĉefa kaj laborfadeno. Ĉiu kodo estas skribita laŭ la supozo, ke nenio iam estas blokita. Tamen tio ne estas tute vera (kio ne estas tute vera?).

Sendito uzas plurajn longajn procezserurojn:

  • Kiel diskutite, dum verkado de alirprotokoloj, ĉiuj laborfadenoj akiras la saman seruron antaŭ ol la en-memora protokolo-bufro estas plenigita. La seruro tenanta tempo devus esti tre malalta, sed estas eble ke la seruro esti kontestata ĉe alta samtempeco kaj alta trafluo.
  • Envoy uzas tre kompleksan sistemon por trakti statistikojn lokajn al la fadeno. Ĉi tio estos la temo de aparta afiŝo. Tamen mi mallonge mencios, ke kadre de prilaborado de fadenaj statistikoj loke, foje necesas akiri seruron ĉe centra "statistika vendejo". Ĉi tiu ŝlosilo neniam devus esti postulata.
  • La ĉefa fadeno periode bezonas kunordigi kun ĉiuj laborfadenoj. Ĉi tio estas farita per "publikigado" de la ĉeffadeno al laborfadenoj, kaj foje de laborfadenoj reen al la ĉeffadeno. Sendado postulas seruro por ke la publikigita mesaĝo povas esti vicigita por posta livero. Ĉi tiuj seruroj neniam devus esti serioze kontestataj, sed ili ankoraŭ povas esti teknike blokitaj.
  • Kiam Envoy skribas protokolon al la sistema erarofluo (norma eraro), ĝi akiras seruro sur la tuta procezo. Ĝenerale, la loka arbodehakado de Envoy estas konsiderata terura el agado, do oni ne multe atentis plibonigon de ĝi.
  • Estas kelkaj aliaj hazardaj seruroj, sed neniu el ili estas agado kritika kaj neniam devus esti defiita.

Fadeno loka stokado

Pro la maniero kiel Envoy apartigas la respondecojn de la ĉeffadeno de la respondecoj de la laborfadeno, ekzistas postulo ke kompleksa pretigo povas esti farita sur la ĉeffadeno kaj tiam disponigita al ĉiu laboristfadeno en tre samtempa maniero. Ĉi tiu sekcio priskribas Envoy Thread Loka Stokado (TLS) je alta nivelo. En la sekva sekcio mi priskribos kiel ĝi estas uzata por administri areton.
[Traduko] Envoy-fadenadmodelo

Kiel jam priskribite, la ĉefa fadeno pritraktas preskaŭ ĉiujn administrajn kaj kontrolebenajn funkciojn en la Envoy-procezo. La kontrolaviadilo estas iom troŝarĝita ĉi tie, sed kiam vi rigardas ĝin ene de la Envoy-procezo mem kaj komparas ĝin kun la plusendado, kiun faras la laborfadenoj, ĝi havas sencon. La ĝenerala regulo estas, ke la ĉeffadena procezo faras iom da laboro, kaj tiam ĝi devas ĝisdatigi ĉiun laborfadenon laŭ la rezulto de tiu laboro. en ĉi tiu kazo, la laborfadeno ne bezonas akiri seruron sur ĉiu aliro.

La sistemo TLS (Thread loka stokado) de Envoy funkcias jene:

  • Kodo funkcianta sur la ĉefa fadeno povas asigni TLS-fendon por la tuta procezo. Kvankam tio estas abstraktita, en praktiko ĝi estas indekso en vektoron, disponigante O(1) aliron.
  • La ĉefa fadeno povas instali arbitrajn datumojn en sia fendo. Kiam tio estas farita, la datumoj estas publikigitaj al ĉiu laborista fadeno kiel normala evento-buklokazaĵo.
  • Laborfadenoj povas legi de sia TLS-fendo kaj retrovi ajnajn faden-lokajn datumojn haveblajn tie.

Kvankam ĝi estas tre simpla kaj nekredeble potenca paradigmo, ĝi estas tre simila al la koncepto de RCU (Legi-Kopii-Ĝisdatigi) blokado. Esence, laborfadenoj neniam vidas ajnajn datumŝanĝojn en la TLS-fendoj dum laboro funkcias. Ŝanĝo okazas nur dum la ripoza periodo inter laboraj eventoj.

Sendito uzas tion laŭ du malsamaj manieroj:

  • Stokante malsamajn datumojn sur ĉiu laborfadeno, la datumoj povas esti aliritaj sen ajna blokado.
  • Konservante komunan montrilon al tutmondaj datumoj en nurlegebla reĝimo sur ĉiu laborfadeno. Tiel, ĉiu laborfadeno havas datuman referenckalkulon kiu ne povas esti malpliigita dum la laboro funkcias. Nur kiam ĉiuj laboristoj trankviliĝos kaj alŝutos novajn komunajn datumojn, la malnovaj datumoj estos detruitaj. Ĉi tio estas identa al RCU.

Fadenado de ĝisdatigo de areto

En ĉi tiu sekcio, mi priskribos kiel TLS (Fadena loka stokado) estas uzata por administri areton. Aretadministrado inkluzivas xDS-API kaj/aŭ DNS-pretigon, same kiel sankontroladon.
[Traduko] Envoy-fadenadmodelo

Aretflua administrado inkluzivas la sekvajn komponentojn kaj paŝojn:

  1. La Cluster Manager estas komponento ene de Envoy, kiu administras ĉiujn konatajn aretojn kontraŭflue, la Cluster Discovery Service (CDS) API, la Secret Discovery Service (SDS) kaj Endpoint Discovery Service (EDS) APIojn, DNS, kaj aktivajn eksterajn kontrolojn. Ĝi respondecas pri kreado de "eventuale konsekvenca" vido de ĉiu kontraŭflua areto, kiu inkludas malkovritajn gastigantojn same kiel sanstatuson.
  2. La sankontrolilo faras aktivan sankontrolon kaj raportas sanstatusŝanĝojn al la clustermanaĝero.
  3. CDS (Cluster Discovery Service) / SDS (Secret Discovery Service) / EDS (Endpoint Discovery Service) / DNS estas faritaj por determini aretmembrecon. La ŝtatŝanĝo estas resendita al la clustermanaĝero.
  4. Ĉiu laborfadeno kontinue efektivigas okazaĵbuklon.
  5. Kiam la clustermanaĝero determinas ke la stato por areto ŝanĝiĝis, ĝi kreas novan nurlegeblan momentfoton de la stato de la areto kaj sendas ĝin al ĉiu laborfadeno.
  6. Dum la sekva trankvila periodo, la laborfadeno ĝisdatigos la momentfoton en la asignita TLS-fendo.
  7. Dum I/O-okazaĵo, kiu supozeble determini la gastiganton por ŝarĝi ekvilibron, la ŝarĝbalancilo petos TLS (Thread-loka stokado) fendo por akiri informojn pri la gastiganto. Ĉi tio ne postulas serurojn. Notu ankaŭ, ke TLS ankaŭ povas deĉenigi ĝisdatigajn eventojn por ke ŝarĝbalanciloj kaj aliaj komponantoj povu rekalkuli kaŝmemorojn, datumstrukturojn, ktp. Ĉi tio estas preter la amplekso de ĉi tiu afiŝo, sed estas uzata en diversaj lokoj en la kodo.

Uzante la ĉi-supran proceduron, Envoy povas procesi ĉiun peton sen ajna blokado (krom kiel priskribite antaŭe). Krom la komplekseco de la TLS-kodo mem, plejparto de la kodo ne bezonas kompreni kiel plurfadenado funkcias kaj povas esti skribita unu-fadena. Ĉi tio faras la plej grandan parton de la kodo pli facile skribi krom supera rendimento.

Aliaj subsistemoj kiuj uzas TLS

TLS (Fadena loka stokado) kaj RCU (Read Copy Update) estas vaste uzataj en Envoy.

Ekzemploj de uzado:

  • Mekanismo por ŝanĝi funkciecon dum ekzekuto: La nuna listo de ebligitaj funkcioj estas kalkulita en la ĉefa fadeno. Ĉiu laborfadeno tiam ricevas nurlegeblan momentfoton uzante RCU-semantikon.
  • Anstataŭigi itinerajn tabelojn: Por itinertabeloj disponigitaj de RDS (Route Discovery Service), la itinertabeloj estas kreitaj sur la ĉeffadeno. La nurlegebla momentfoto estos poste provizita al ĉiu laborfadeno uzante semantikon de RCU (Read Copy Update). Ĉi tio igas ŝanĝantajn itinertabelojn atome efika.
  • Kaŝmemoro de HTTP-katoloj: Kiel rezultas, kalkuli la HTTP-kapon por ĉiu peto (dum ĝi funkcias ~25K+ RPS per kerno) estas sufiĉe multekosta. Envoy centre komputas la kaplinion proksimume ĉiun duonsekudon kaj provizas ĝin al ĉiu laboristo per TLS kaj RCU.

Estas aliaj kazoj, sed la antaŭaj ekzemploj devus doni bonan komprenon pri kio TLS estas uzata.

Konataj agado-faloj

Dum Envoy funkcias sufiĉe bone entute, ekzistas kelkaj rimarkindaj areoj kiuj postulas atenton kiam ĝi estas uzata kun tre alta samtempeco kaj trairo:

  • Kiel priskribite en ĉi tiu artikolo, nuntempe ĉiuj laborfadenoj akiras seruron skribante al la alirregistra memorbufro. Ĉe alta samtempeco kaj alta trafluo, vi devos grupigi la alirprogramojn por ĉiu laborista fadeno koste de neorda livero kiam vi verkas al la fina dosiero. Alternative, vi povas krei apartan alirprotokolo por ĉiu laborfadeno.
  • Kvankam la statistikoj estas tre optimumigitaj, ĉe tre alta samtempeco kaj trafluo verŝajne estos atomdisputo pri individuaj statistikoj. La solvo al ĉi tiu problemo estas nombriloj per laborista fadeno kun perioda restarigo de centraj sumigiloj. Ĉi tio estos diskutita en posta afiŝo.
  • La nuna arkitekturo ne funkcios bone se Envoy estas deplojita en scenaro kie estas tre malmultaj ligoj kiuj postulas signifajn pretigajn rimedojn. Ne estas garantio, ke ligoj estos egale distribuitaj inter laborfadenoj. Ĉi tio povas esti solvita per efektivigado de laborkonektbalancado, kiu permesos la interŝanĝon de ligoj inter laboristaj fadenoj.

Konkludo

La surfadena modelo de Envoy estas dizajnita por disponigi facilecon de programado kaj masivan paralelecon koste de eble malŝparema memoro kaj ligoj se ne agordita ĝuste. Ĉi tiu modelo permesas al ĝi funkcii tre bone ĉe tre altaj fadenaj nombroj kaj trafluo.
Kiel mi mallonge menciis en Twitter, la dezajno ankaŭ povas funkcii super plena uzant-reĝima interreta stako kiel DPDK (Data Plane Development Kit), kiu povas rezultigi konvenciajn servilojn pritraktantajn milionojn da petoj sekundo kun plena L7-pretigo. Estos tre interese vidi kio estos konstruita en la venontaj kelkaj jaroj.
Lasta rapida komento: Oni demandis min multfoje, kial ni elektis C++ por Envoy. La kialo restas, ke ĝi ankoraŭ estas la nura vaste uzata industria grado lingvo en kiu la arkitekturo priskribita en ĉi tiu afiŝo povas esti konstruita. C++ certe ne taŭgas por ĉiuj aŭ eĉ multaj projektoj, sed por certaj uzkazoj ĝi ankoraŭ estas la sola ilo por fari la laboron.

Ligiloj al kodo

Ligiloj al dosieroj kun interfacoj kaj titolaj efektivigoj diskutitaj en ĉi tiu afiŝo:

fonto: www.habr.com

Aldoni komenton