[Iwwersetzung] Envoy threading Modell

Iwwersetzung vum Artikel: Envoy threading Modell - https://blog.envoyproxy.io/envoy-threading-model-a8d44b922310

Ech hunn dësen Artikel zimmlech interessant fonnt, a well Envoy am meeschten als Deel vum "istio" oder einfach als "Ingress Controller" vu kubernetes benotzt gëtt, hunn déi meescht Leit net déiselwecht direkt Interaktioun mat deem wéi zum Beispill mat typesche Nginx oder Haproxy Installatiounen. Wann awer eppes brécht, wier et gutt ze verstoen wéi et vu bannen funktionnéiert. Ech hu probéiert esou vill wéi méiglech vum Text op Russesch ze iwwersetzen, och speziell Wierder; fir déi, déi et schmerzhaft fannen dat ze kucken, hunn ech d'Originaler an Klammern gelooss. Wëllkomm zu Kaz.

Niddereg technesch Dokumentatioun fir den Envoy Codebase ass de Moment zimlech sparsam. Fir dëst ze léisen, plangen ech eng Serie vu Blogposten iwwer déi verschidde Subsystemer vum Envoy ze maachen. Well dëst den éischten Artikel ass, sot mir w.e.g. wat Dir mengt a wat Dir an zukünfteg Artikelen interesséiert kéint.

Eng vun den heefegsten technesche Froen, déi ech iwwer Envoy kréien, ass eng niddereg-Niveau Beschreiwung vum Threading Modell ze froen deen et benotzt. An dësem Post wäert ech beschreiwen wéi Envoy Verbindungen op Threads mapéiert, souwéi de Thread Local Storage System deen et intern benotzt fir Code méi parallel an héich performant ze maachen.

Threading Iwwersiicht

[Iwwersetzung] Envoy threading Modell

Envoy benotzt dräi verschidden Aarte vu Streamen:

  • Main: Dëse Fuedem kontrolléiert Prozessstart an Ofschloss, all Veraarbechtung vun der XDS (xDiscovery Service) API, inklusiv DNS, Gesondheetsprüfung, allgemeng Cluster a Runtime Management, Statistiken zrécksetzen, Administratioun an allgemeng Prozessmanagement - Linux Signaler. Hot Restart, etc. geschitt an dësem thread ass asynchron an "net blockéierend". Am Allgemengen, koordinéiert den Haaptgrond all kritesch Funktionalitéit Prozesser datt net eng grouss Quantitéit vun CPU brauchen ze lafen. Dëst erlaabt de meeschte Kontrollcode ze schreiwen wéi wann et eenzel thread wier.
  • Aarbechter: Par défaut erstellt Envoy en Aarbechter thread fir all Hardware thread am System, dëst kann mat der Optioun kontrolléiert ginn --concurrency. All Aarbechter thread leeft eng "net blockéierend" Event Loop, déi verantwortlech ass fir all Nolauschterer ze lauschteren; beim Schreiwen (29. Juli 2017) gëtt et kee Schied vum Nolauschterer, nei Verbindungen akzeptéiert, e Filterstack instantiéiert fir d'Verbindung, a Veraarbechtung vun all Input / Output (IO) Operatiounen während der Liewensdauer vun der Verbindung. Erëm, dëst erlaabt de meeschte Verbindungshandhabungscode geschriwwe ze ginn wéi wann et eenzel thread wier.
  • Datei Spuller: All Datei deen den Envoy schreift, haaptsächlech Zougangsprotokoller, huet de Moment en onofhängege Blockéierungs thread. Dëst ass wéinst der Tatsaach datt Schreiwen op Dateien, déi vum Dateiesystem cache sinn, och wann Dir benotzt O_NONBLOCK kann heiansdo blockéiert ginn (suck). Wann d'Aarbechter thread op eng Datei schreiwen mussen, ginn d'Donnéeën tatsächlech an e Puffer an der Erënnerung geplënnert, wou se schlussendlech duerch de Fuedem gespullt ginn Fichier Spull. Dëst ass ee Gebitt vum Code wou technesch all Aarbechter thread deeselwechte Spär blockéiere kënnen wärend Dir probéiert e Gedächtnisbuffer ze fëllen.

Verbindung Ëmgank

Wéi uewe kuerz diskutéiert, lauschteren all Aarbechter thread un all Nolauschterer ouni Schied. Also gëtt de Kernel benotzt fir graziéis akzeptéiert Sockets un Aarbechter thread ze schécken. Modern Kärelen sinn allgemeng ganz gutt an dësem, si benotze Funktiounen wéi Input / Output (IO) Prioritéit Boost fir ze probéieren e Fuedem mat Aarbecht ze fëllen ier se ufänken aner Threads ze benotzen déi och op derselwechter Socket lauschteren, an och net Round Robin benotzen Spär (Spinlock) fir all Ufro ze veraarbecht.
Wann eng Verbindung op engem Aarbechter thread akzeptéiert ass, verléisst se dee Fuedem ni. All weider Veraarbechtung vun der Verbindung gëtt ganz am Aarbechter thread gehandhabt, inklusiv all Forwardverhalen.

Dëst huet e puer wichteg Konsequenzen:

  • All Verbindungspools am Envoy ginn un engem Aarbechter thread zougewisen. Also, obwuel HTTP / 2 Verbindungspools nëmmen eng Verbindung mat all Upstream Host gläichzäiteg maachen, wann et véier Aarbechter thread sinn, ginn et véier HTTP / 2 Verbindungen pro Upstream Host an engem stännegen Zoustand.
  • De Grond firwat den Envoy sou funktionnéiert ass datt andeems Dir alles op engem eenzegen Aarbechter thread hält, ka bal all Code geschriwwe ginn ouni ze blockéieren an wéi wann et eenzel thread wier. Dësen Design mécht et einfach vill Code ze schreiwen a skaléiert onheemlech gutt op eng bal onlimitéiert Zuel vun Aarbechter thread.
  • Wéi och ëmmer, ee vun den Haaptméiglechkeeten ass datt aus engem Memory Pool a Verbindungseffizienz Siicht et tatsächlech ganz wichteg ass d'Konfiguratioun --concurrency. Méi Aarbechter thread ze hunn wéi néideg wäert d'Erënnerung verschwenden, méi Idle Verbindungen erstellen an den Taux vun der Verbindungspooling reduzéieren. Bei Lyft lafen eis Envoy Sidecar Container mat ganz gerénger Konkurrenz sou datt d'Performance ongeféier mat de Servicer entsprécht, op déi se niewendru sëtzen. Mir lafen Envoy als Randproxy nëmme mat maximaler Zoustëmmung.

Wat heescht net blockéieren?

De Begrëff "net blockéieren" gouf e puer Mol bis elo benotzt wann Dir diskutéiert wéi d'Haapt- an d'Aarbechter thread funktionnéieren. All Code ass op der Virgab geschriwwen datt näischt jee blockéiert ass. Dëst ass awer net ganz richteg (wat ass net ganz wouer?).

Envoy benotzt verschidde laange Prozessschloss:

  • Wéi diskutéiert, wann Dir Zougangsprotokoller schreift, kréien all Aarbechter thread déiselwecht Sperrung ier den In-Memory Log-Puffer gefëllt ass. D'Spär Holding Zäit soll ganz niddereg ginn, mä et ass méiglech fir d'Spär bei héich concurrency an héich Débit contestéiert ginn.
  • Envoy benotzt e ganz komplexe System fir Statistiken ze handhaben déi lokal zum Fuedem sinn. Dëst wäert d'Thema vun engem separaten Post sinn. Wéi och ëmmer, ech wäert kuerz ernimmen datt am Kader vun der lokaler Veraarbechtung vun threadstatistiken, et heiansdo néideg ass fir e Spär op engem zentrale "Stats Store" ze kréien. Dës Sperrung sollt ni erfuerderlech sinn.
  • Den Haapt thread muss periodesch mat all Aarbechter thread koordinéieren. Dëst gëtt gemaach duerch "Verëffentlechung" vum Haapt thread op d'Aarbechter thread, an heiansdo vun den Aarbechter thread zréck an den Haapt thread. Schécken erfuerdert e Spär fir datt de publizéierte Message ka fir spéider Liwwerung a Schlaang gesat ginn. Dës Schleisen sollen ni eescht contestéiert ginn, mä si kënnen nach technesch blockéiert ginn.
  • Wann den Envoy e Logbuch an de Systemfehlerstroum schreift (Standardfehler), kritt et e Spär op de ganze Prozess. Am Allgemengen gëtt dem Envoy säi lokale Logbuch als schrecklech aus engem Leeschtungssiicht ugesinn, sou datt et net vill Opmierksamkeet gouf fir et ze verbesseren.
  • Et ginn e puer aner zoufälleg spären, mee keent vun hinnen Leeschtung kritesch a soll ni erausgefuerdert ginn.

Thread lokal Lagerung

Wéinst der Aart a Weis wéi den Envoy d'Verantwortung vum Haaptfuedem vun de Verantwortung vum Aarbechter thread trennt, gëtt et eng Fuerderung datt komplex Veraarbechtung um Haaptfuedem ka gemaach ginn an dann un all Aarbechter thread op eng héich gläichzäiteg Manéier geliwwert ginn. Dës Sektioun beschreift Envoy Thread Local Storage (TLS) op engem héijen Niveau. An der nächster Sektioun wäert ech beschreiwen wéi et benotzt gëtt fir e Cluster ze managen.
[Iwwersetzung] Envoy threading Modell

Wéi scho beschriwwen, handhabt den Haapt thread praktesch all Gestioun a Kontroll Fliger Funktionalitéit am Envoy Prozess. De Kontrollfliger ass hei e bëssen iwwerlaascht, awer wann Dir et am Envoy-Prozess selwer kuckt a vergläicht et mat der Forwarding déi d'Aarbechter thread maachen, mécht et Sënn. D'allgemeng Regel ass datt den Haapt thread Prozess e puer Aarbecht mécht, an da muss et all Aarbechter thread no dem Resultat vun där Aarbecht aktualiséieren. an dësem Fall brauch den Aarbechter thread net e Spär op all Zougang ze kréien.

Envoy's TLS (Thread Local Storage) System funktionnéiert wéi follegt:

  • Code deen um Haapt thread leeft kann en TLS Slot fir de ganze Prozess allocéieren. Och wann dëst abstrakt ass, ass et an der Praxis en Index an e Vektor, deen O(1) Zougang ubitt.
  • Den Haaptfuedem kann arbiträr Daten a säi Slot installéieren. Wann dëst gemaach ass, ginn d'Donnéeën un all Aarbechter thread als normal Event Loop Event publizéiert.
  • Aarbechter thread kënnen aus hirem TLS Slot liesen an all thread-lokal Donnéeën déi do verfügbar sinn.

Och wann et e ganz einfachen an onheemlech mächtege Paradigma ass, ass et ganz ähnlech mam Konzept vun der RCU (Read-Copy-Update) Blocking. Wesentlech gesinn d'Aarbechter thread ni Daten Ännerungen an den TLS Slots wärend d'Aarbecht leeft. Ännerung geschitt nëmmen während der Rescht Period tëscht Aarbecht Evenementer.

Envoy benotzt dëst op zwou verschidde Weeër:

  • Andeems Dir verschidden Donnéeën op all Aarbechter thread späichert, kënnen d'Donnéeën ouni Blockéierung zougänglech sinn.
  • Andeems Dir e gemeinsame Pointer op global Daten am Read-only Modus op all Aarbechter thread behält. Also huet all Aarbechter thread en Datereferenzzuel, deen net dekrementéiert ka ginn während d'Aarbecht leeft. Eréischt wann all Aarbechter berouegen an nei gedeelt Daten eropluede ginn déi al Donnéeën zerstéiert. Dëst ass identesch mat RCU.

Cluster Update Threading

An dëser Sektioun wäert ech beschreiwen wéi TLS (Thread Local Storage) benotzt gëtt fir e Cluster ze managen. Clustermanagement enthält xDS API an / oder DNS Veraarbechtung, souwéi Gesondheetsprüfung.
[Iwwersetzung] Envoy threading Modell

Cluster Flow Management enthält déi folgend Komponenten a Schrëtt:

  1. De Cluster Manager ass e Bestanddeel am Envoy deen all bekannte Cluster Upstreams geréiert, de Cluster Discovery Service (CDS) API, de Secret Discovery Service (SDS) an Endpoint Discovery Service (EDS) APIs, DNS, an aktiv extern Kontrollen. Et ass verantwortlech fir eng "schlussendlech konsequent" Vue vun all Upstream-Cluster ze kreéieren, deen entdeckte Hosten souwéi de Gesondheetszoustand enthält.
  2. De Gesondheetschecker mécht en aktive Gesondheetscheck a bericht Gesondheetsstatus Ännerungen un de Cluster Manager.
  3. CDS (Cluster Discovery Service) / SDS (Secret Discovery Service) / EDS (Endpoint Discovery Service) / DNS gi gemaach fir Cluster Memberschaft ze bestëmmen. D'Staatsännerung gëtt un de Clustermanager zréckginn.
  4. All Aarbechter thread féiert kontinuéierlech eng Event Loop aus.
  5. Wann de Stärekoup Manager bestëmmt datt de Staat fir e Stärekoup geännert huet, erstellt en neie Lies-nëmmen Snapshot vum Staat vum Stärekoup a schéckt se un all Aarbechter thread.
  6. Wärend der nächster roueger Period wäert den Aarbechter thread de Snapshot am zougewisenen TLS Slot aktualiséieren.
  7. Wärend engem I/O Event dat soll den Host bestëmmen fir d'Balance ze lueden, freet de Lastbalancer en TLS (Thread Local Storage) Slot fir Informatioun iwwer de Host ze kréien. Dëst erfuerdert keng Spären. Notéiert och datt TLS och Update-Evenementer ausléise kann, sou datt Lastbalancer an aner Komponenten Cache, Datenstrukturen, etc. Dëst ass iwwer den Ëmfang vun dësem Post, awer gëtt op verschiddene Plazen am Code benotzt.

Mat der uewe genannter Prozedur kann den Envoy all Ufro ouni Blockéierung veraarbechten (ausser wéi virdru beschriwwen). Nieft der Komplexitéit vum TLS Code selwer, brauch de gréissten Deel vum Code net ze verstoen wéi Multithreading funktionnéiert a ka Single-threaded geschriwwe ginn. Dëst mécht de gréissten Deel vum Code méi einfach ze schreiwen zousätzlech zu enger super Leeschtung.

Aner Ënnersystemer déi TLS benotzen

TLS (Thread Local Storage) an RCU (Read Copy Update) gi wäit an Envoy benotzt.

Beispiller fir ze benotzen:

  • Mechanismus fir d'Funktionalitéit während der Ausféierung z'änneren: Déi aktuell Lëscht vun aktivéierte Funktionalitéit gëtt am Haaptthread berechent. All Aarbechter thread gëtt dann e Read-only Snapshot mat RCU Semantik kritt.
  • Route Dëscher ersetzen: Fir Streckentabellen, déi vum RDS (Route Discovery Service) zur Verfügung gestallt gëtt, ginn d'Routetabellen op der Haaptrei erstallt. De Read-only Snapshot gëtt duerno un all Aarbechter thread mat RCU (Read Copy Update) Semantik geliwwert. Dëst mécht änneren Streck Dëscher atomically effikass.
  • HTTP Header Cache: Wéi et sech erausstellt, ass d'Berechnung vum HTTP Header fir all Ufro (während ~25K+ RPS pro Kär leeft) zimlech deier. Envoy berechent zentral den Header ongeféier all hallef Sekonn a liwwert et un all Aarbechter iwwer TLS an RCU.

Et ginn aner Fäll, awer déi virdrun Beispiller sollen e gutt Verständnis ubidden fir wat TLS benotzt gëtt.

Bekannt Leeschtung Fallen

Wärend den Envoy insgesamt zimlech gutt leeft, ginn et e puer bemierkenswäert Beräicher déi Opmierksamkeet erfuerderen wann se mat ganz héijer Zoustëmmung an Duerchsatz benotzt gëtt:

  • Wéi an dësem Artikel beschriwwen, kréien de Moment all Aarbechter Threads e Spär beim Schreiwen an den Access Log Memory Buffer. Bei héijer Concurrency an héijen Duerchgang musst Dir d'Zougangsprotokoller fir all Aarbechter thread op Käschte vun der ausseruerdentlecher Liwwerung batchéieren wann Dir op d'Finale Datei schreift. Alternativ kënnt Dir e separaten Zougangsprotokoll fir all Aarbechter thread erstellen.
  • Och wann d'Statistiken héich optimiséiert sinn, bei ganz héijer Concurrency an Duerchsatz wäert et méiglecherweis atomar Sträit op eenzel Statistike sinn. D'Léisung fir dëse Problem ass Zähler pro Aarbechter thread mat periodesche Reset vun zentrale Zähler. Dëst wäert an engem spéideren Post diskutéiert ginn.
  • Déi aktuell Architektur wäert net gutt funktionnéieren wann Envoy an engem Szenario ofgesat gëtt wou et ganz wéineg Verbindunge sinn déi bedeitend Veraarbechtungsressourcen erfuerderen. Et gëtt keng Garantie datt d'Verbindunge gläichméisseg tëscht den Aarbechter thread verdeelt ginn. Dëst kann geléist ginn andeems d'Aarbechterverbindungsbalancéierung ëmgesat gëtt, wat den Austausch vu Verbindungen tëscht Aarbechter thread erlaabt.

Conclusioun

Dem Envoy säi Threading Modell ass entwéckelt fir Liichtegkeet ze programméieren a massive Parallelismus op Käschte vu potenziell verschwenden Erënnerung a Verbindungen ze bidden wann net richteg konfiguréiert sinn. Dëse Modell erlaabt et ganz gutt bei ganz héije Fuedemzuelen an Duerchsatz ze Leeschtunge.
Wéi ech kuerz op Twitter ernimmt hunn, kann den Design och uewen op engem vollen User-Modus Netzwierkstack wéi DPDK (Data Plane Development Kit) lafen, wat zu konventionelle Serveren resultéiere kann, déi Millioune vun Ufroen pro Sekonn mat voller L7 Veraarbechtung behandelen. Et wäert ganz interessant sinn ze gesinn wat an den nächste Jore gebaut gëtt.
Ee leschte séiere Kommentar: Ech hu vill Mol gefrot firwat mir C++ fir Envoy gewielt hunn. De Grond bleift datt et nach ëmmer déi eenzeg wäit benotzt Industriegrad Sprooch ass an där d'Architektur an dësem Post beschriwwe ka gebaut ginn. C ++ ass definitiv net gëeegent fir all oder souguer vill Projeten, awer fir bestëmmte Benotzungsfäll ass et nach ëmmer dat eenzegt Tool fir d'Aarbecht gemaach ze kréien.

Linken op Code

Links op Dateien mat Interfaces an Header Implementatiounen diskutéiert an dësem Post:

Source: will.com

Setzt e Commentaire