[Þýðing] Þræðingarlíkan sendifulltrúa

Þýðing á greininni: Sendiboðsþráður líkan - https://blog.envoyproxy.io/envoy-threading-model-a8d44b922310

Mér fannst þessi grein nokkuð áhugaverð og þar sem Envoy er oftast notaður sem hluti af „istio“ eða einfaldlega sem „inngangsstýrimaður“ kubernetes, hafa flestir ekki sömu bein samskipti við hana og til dæmis með dæmigerðum Nginx eða Haproxy uppsetningar. Hins vegar, ef eitthvað bilar, væri gott að skilja hvernig það virkar innan frá. Ég reyndi að þýða sem mest af textanum yfir á rússnesku, þar á meðal sérstök orð, fyrir þá sem finnst sárt að horfa á þetta skildi ég frumritin eftir innan sviga. Velkomin í köttinn.

Tækniskjöl á lágu stigi fyrir Envoy kóðagrunninn eru frekar dreifður eins og er. Til að ráða bót á þessu ætla ég að gera röð af bloggfærslum um hin ýmsu undirkerfi Envoy. Þar sem þetta er fyrsta greinin, vinsamlegast láttu mig vita hvað þér finnst og hvað þú gætir haft áhuga á í framtíðargreinum.

Ein algengasta tæknispurningin sem ég fæ um Envoy er að biðja um lága lýsingu á þræðilíkaninu sem það notar. Í þessari færslu mun ég lýsa því hvernig Envoy kortleggur tengingar við þræði, sem og Thread Local Storage kerfið sem það notar innbyrðis til að gera kóða samhliða og afkastameiri.

Þráðaryfirlit

[Þýðing] Þræðingarlíkan sendifulltrúa

Envoy notar þrjár mismunandi tegundir af straumum:

  • Aðal: Þessi þráður stjórnar ræsingu og lokun ferla, allri vinnslu XDS (xDiscovery Service) API, þar á meðal DNS, heilsufarsskoðun, almennri klasa- og keyrslustjórnun, endurstillingu tölfræði, stjórnun og almennri ferlistjórnun - Linux merki. heit endurræsing o.s.frv. Allt sem gerist í þessum þræði er ósamstilltur og "non-blocking". Almennt séð samræmir aðalþráðurinn öll mikilvæg virkniferli sem þurfa ekki mikið magn af örgjörva til að keyra. Þetta gerir kleift að skrifa flesta stjórnkóða eins og hann væri einn þráður.
  • Starfsmaður: Sjálfgefið er að Envoy býr til starfsþráð fyrir hvern vélbúnaðarþráð í kerfinu, þessu er hægt að stjórna með því að nota valkostinn --concurrency. Hver starfsþráður keyrir „non-blocking“ atburðarlykkju, sem ber ábyrgð á því að hlusta á hvern hlustanda; þegar þetta er skrifað (29. júlí 2017) er ekki verið að klippa hlustandann, samþykkja nýjar tengingar, stofna síustafla fyrir tengingunni og vinnsla allra inntaks/úttaksaðgerða (IO) á meðan tengingin stendur yfir. Aftur, þetta gerir kleift að skrifa flestan tengingarkóða eins og hann væri einn þráður.
  • Skráarskolun: Hver skrá sem Envoy skrifar, aðallega aðgangsskrár, hefur sem stendur sjálfstæðan lokunarþráð. Þetta er vegna þess að skrifa í skrár sem eru í skyndiminni af skráarkerfinu, jafnvel þegar þú notar O_NONBLOCK getur stundum stíflast (andvarp). Þegar vinnuþræðir þurfa að skrifa í skrá eru gögnin í raun flutt í biðminni í minni þar sem þau eru að lokum skoluð í gegnum þráðinn skrá skola. Þetta er eitt svæði kóða þar sem tæknilega séð geta allir starfsmannaþræðir lokað á sama lás á meðan reynt er að fylla á minnisbiðminni.

Meðhöndlun tenginga

Eins og fjallað er stuttlega um hér að ofan, hlusta allir starfsþræðir á alla hlustendur án þess að klippa sig. Þannig er kjarninn notaður til að senda viðteknar innstungur á þokkafullan hátt til starfsmannaþráða. Nútímakjarnar eru almennt mjög góðir í þessu, þeir nota eiginleika eins og input/output (IO) forgangsaukning til að reyna að fylla þráð af vinnu áður en þeir byrja að nota aðra þræði sem eru líka að hlusta á sömu fals, og heldur ekki að nota round robin læsing (Spinlock) til að vinna úr hverri beiðni.
Þegar tenging hefur verið samþykkt á starfsþráði fer hún aldrei úr þeim þræði. Öll frekari úrvinnsla á tengingunni er að öllu leyti meðhöndluð í starfsþræðinum, þar með talið hvers kyns framsendingarhegðun.

Þetta hefur nokkrar mikilvægar afleiðingar:

  • Öllum tengihópum í Envoy er úthlutað á starfsþráð. Þannig að þó að HTTP/2 tengingarhópar komi aðeins með eina tengingu við hvern andstreymishýsil í einu, ef það eru fjórir starfsþræðir, verða fjórar HTTP/2 tengingar á hvern andstreymishýsil í stöðugu ástandi.
  • Ástæðan fyrir því að Envoy virkar á þennan hátt er sú að með því að hafa allt á einum vinnuþræði er hægt að skrifa næstum allan kóða án þess að loka og eins og hann sé einn þráður. Þessi hönnun gerir það auðvelt að skrifa mikinn kóða og skalast ótrúlega vel í næstum ótakmarkaðan fjölda starfsmannaþráða.
  • Hins vegar er eitt helsta atriðið að frá sjónarhóli minnisafns og skilvirkni tenginga er í raun mjög mikilvægt að stilla --concurrency. Að hafa fleiri starfsþráða en nauðsynlegt er mun sóa minni, búa til fleiri aðgerðalausar tengingar og draga úr hraða tengingar. Hjá Lyft keyra hliðarvagnsgámarnir fyrir sendifulltrúa okkar með mjög lítilli samhliða þannig að frammistaðan samsvarar nokkurn veginn þeirri þjónustu sem þeir sitja við hliðina á. Við keyrum Envoy sem brún umboð aðeins við hámarks samhliða.

Hvað þýðir ekki að loka?

Hugtakið "non-blocking" hefur verið notað nokkrum sinnum hingað til þegar rætt er um hvernig aðal- og starfsþráður virka. Allur kóði er skrifaður á þeirri forsendu að aldrei sé neitt lokað. Hins vegar er þetta ekki alveg satt (hvað er ekki alveg satt?).

Envoy notar nokkra langa ferlilæsa:

  • Eins og fjallað er um, þegar aðgangsskrár eru skrifaðar, fá allir vinnuþræðir sama lás áður en biðminni í minnisskránni er fyllt. Lokahaldstíminn ætti að vera mjög lítill, en það er mögulegt fyrir lásinn að keppa við mikla samhliða og mikla afköst.
  • Envoy notar mjög flókið kerfi til að meðhöndla tölfræði sem er staðbundin við þráðinn. Þetta verður efni í sérstakri færslu. Hins vegar nefni ég í stuttu máli að sem hluti af vinnslu þráðatölfræði á staðnum er stundum nauðsynlegt að eignast lás á miðlægri "tölfræðiverslun". Þessa læsingu ætti aldrei að vera krafist.
  • Aðalþráðurinn þarf reglulega að samræmast öllum starfsþráðum. Þetta er gert með því að "birta" frá aðalþræði yfir á vinnuþræði og stundum frá starfsþræði aftur á aðalþráð. Sending krefst læsingar svo hægt sé að setja birt skilaboð í biðröð fyrir afhendingu síðar. Þessum læsingum ætti aldrei að mótmæla alvarlega, en samt er tæknilega hægt að loka þeim.
  • Þegar Envoy skrifar annál í kerfisvillustrauminn (venjuleg villa) fær hann læsingu á allt ferlið. Almennt séð er staðbundin skógarhögg Envoy talin hræðileg frá frammistöðusjónarmiði, svo það hefur ekki verið lögð mikil áhersla á að bæta hana.
  • Það eru nokkrir aðrir handahófskenndir læsingar, en enginn þeirra er mikilvægur fyrir frammistöðu og ætti aldrei að mótmæla.

Þráður staðbundin geymsla

Vegna þess hvernig Envoy aðskilur skyldur meginþráðsins frá ábyrgð starfsþráðarins, er krafa um að hægt sé að framkvæma flókna vinnslu á aðalþráðnum og síðan veitt hverjum starfsþráði á mjög samhliða hátt. Þessi hluti lýsir envoy Thread Local Storage (TLS) á háu stigi. Í næsta kafla mun ég lýsa því hvernig það er notað til að stjórna klasa.
[Þýðing] Þræðingarlíkan sendifulltrúa

Eins og áður hefur verið lýst, sér aðalþráðurinn um nánast alla virkni stjórnunar- og stjórnunarflugvélar í sendiráðsferlinu. Stjórnarflugvélin er svolítið ofhlaðin hér, en þegar þú horfir á það innan sendimannsferilsins sjálfs og ber það saman við áframsendinguna sem starfsmannsþræðir gera, þá er það skynsamlegt. Almenna reglan er sú að aðalþráðarferlið vinnur einhverja vinnu og þá þarf það að uppfæra hvern starfsþráð í samræmi við niðurstöðu þeirrar vinnu. í þessu tilviki þarf vinnuþráðurinn ekki að fá læsingu á hvern aðgang.

TLS (Thread local storage) kerfi Envoy virkar sem hér segir:

  • Kóði sem keyrir á aðalþræðinum getur úthlutað TLS rauf fyrir allt ferlið. Þó að þetta sé óhlutbundið er það í reynd vísitala í vektor, sem veitir O(1) aðgang.
  • Aðalþráðurinn getur sett upp handahófskennd gögn í raufina sinn. Þegar þessu er lokið eru gögnin birt á hvern starfsþráð sem venjulegan atburðarlykkja.
  • Starfsmannaþræðir geta lesið úr TLS raufinni sinni og sótt hvaða þráða-staðbundnu gögn sem eru tiltæk þar.

Þó að það sé mjög einfalt og ótrúlega öflugt hugmyndafræði, er það mjög líkt hugmyndinni um RCU (Read-Copy-Update) blokkun. Í meginatriðum sjá starfsþræðir aldrei neinar gagnabreytingar í TLS raufunum meðan vinnan er í gangi. Breytingar eiga sér stað aðeins á hvíldartíma milli vinnuatburða.

Sendiherra notar þetta á tvo mismunandi vegu:

  • Með því að geyma mismunandi gögn á hverjum starfsþræði er hægt að nálgast gögnin án nokkurrar lokunar.
  • Með því að viðhalda sameiginlegum bendili að alþjóðlegum gögnum í skrifvarinn ham á hverjum starfsþræði. Þannig hefur hver starfsþráður gagnaviðmiðunartölu sem ekki er hægt að lækka á meðan verkið er í gangi. Aðeins þegar allir starfsmenn róast og hlaða upp nýjum sameiginlegum gögnum verður gömlu gögnunum eytt. Þetta er eins og RCU.

Þráður fyrir klasauppfærslu

Í þessum hluta mun ég lýsa því hvernig TLS (Thread local storage) er notað til að stjórna klasa. Klasastjórnun felur í sér xDS API og/eða DNS vinnslu, auk heilsufarsskoðunar.
[Þýðing] Þræðingarlíkan sendifulltrúa

Klasaflæðisstjórnun felur í sér eftirfarandi þætti og skref:

  1. Cluster Manager er hluti innan Envoy sem stjórnar öllum þekktum klasa andstreymi, Cluster Discovery Service (CDS) API, Secret Discovery Service (SDS) og Endpoint Discovery Service (EDS) API, DNS og virku ytri eftirliti. Það er ábyrgt fyrir því að búa til „á endanum samræmda“ sýn á hvern andstreymisþyrping, sem felur í sér uppgötvaða hýsils auk heilsufars.
  2. Heilsufarinn framkvæmir virka heilsufarsskoðun og tilkynnir um breytingar á heilsufari til klasastjórans.
  3. CDS (Cluster Discovery Service) / SDS (Secret Discovery Service) / EDS (Endpoint Discovery Service) / DNS eru framkvæmdar til að ákvarða klasaaðild. Ástandsbreytingunni er skilað til klasastjóra.
  4. Hver starfsþráður framkvæmir stöðugt atburðarlykkju.
  5. Þegar klasastjórinn ákveður að ástand klasa hafi breyst, býr hann til nýja skrifvarða skyndimynd af ástandi klasans og sendir það á hvern starfsþráð.
  6. Á næsta rólega tímabili mun starfsþráðurinn uppfæra skyndimyndina í úthlutaðri TLS rauf.
  7. Meðan á I/O atburði stendur sem á að ákvarða hýsilinn til að hlaða jafnvægi mun hleðslujafnarinn biðja um TLS (Thread local storage) rauf til að fá upplýsingar um hýsilinn. Þetta krefst ekki læsinga. Athugaðu einnig að TLS getur einnig kallað fram uppfærsluatburði þannig að álagsjafnari og aðrir íhlutir geti endurreiknað skyndiminni, gagnauppbyggingu osfrv. Þetta er utan gildissviðs þessarar færslu, en er notað á ýmsum stöðum í kóðanum.

Með því að nota ofangreinda aðferð getur Envoy afgreitt allar beiðnir án nokkurrar lokunar (nema eins og áður hefur verið lýst). Fyrir utan flókinn TLS kóðann sjálfan, þá þarf meirihluti kóðans ekki að skilja hvernig fjölþráður virkar og hægt er að skrifa hann einn-þráður. Þetta gerir flestan kóðann auðveldari að skrifa auk yfirburða frammistöðu.

Önnur undirkerfi sem nýta sér TLS

TLS (Thread local storage) og RCU (Read Copy Update) eru mikið notaðar í Envoy.

Dæmi um notkun:

  • Vélbúnaður til að breyta virkni meðan á framkvæmd stendur: Núverandi listi yfir virka virkni er reiknaður út í aðalþræðinum. Hver starfsþráður fær síðan skrifvarinn skyndimynd með því að nota merkingarfræði RCU.
  • Skipt um leiðartöflur: Fyrir leiðartöflur frá RDS (Route Discovery Service), eru leiðartöflurnar búnar til á aðalþræðinum. Skrifvarinn skyndimynd verður í kjölfarið veitt hverjum starfsþráði með því að nota RCU (Read Copy Update) merkingarfræði. Þetta gerir breytingar á leiðartöflum atómfræðilega skilvirkar.
  • HTTP haus skyndiminni: Eins og það kemur í ljós er nokkuð dýrt að reikna HTTP hausinn fyrir hverja beiðni (meðan í gangi ~25K+ RPS á kjarna). Envoy reiknar hausinn miðlægt á um það bil hálfrar sekúndu fresti og lætur hvern starfsmann fá hann í gegnum TLS og RCU.

Það eru önnur tilvik, en fyrri dæmi ættu að gefa góðan skilning á því til hvers TLS er notað.

Þekktar árangursgildrur

Þó að Envoy standi sig nokkuð vel í heildina eru nokkur athyglisverð svæði sem krefjast athygli þegar það er notað með mjög mikilli samhliða og afköst:

  • Eins og lýst er í þessari grein, eins og er, fá allir vinnuþræðir læsingu þegar þeir skrifa í aðgangsskráminni biðminni. Við mikla samhliða og mikla afköst þarftu að safna aðgangsskrám fyrir hvern starfsþráð á kostnað ópöntunar þegar þú skrifar í lokaskrána. Að öðrum kosti geturðu búið til sérstaka aðgangsskrá fyrir hvern starfsþráð.
  • Þrátt fyrir að tölfræðin sé mjög bjartsýn, mun líklega vera atómdeilur um einstaka tölfræði við mjög mikla samhliða og afköst. Lausnin á þessu vandamáli er teljarar á hvern starfsþráð með reglulegri endurstillingu miðlægra teljara. Um þetta verður fjallað í síðari færslu.
  • Núverandi arkitektúr mun ekki virka vel ef Envoy er notað í atburðarás þar sem það eru mjög fáar tengingar sem krefjast umtalsverðs vinnsluauðlinda. Það er engin trygging fyrir því að tengingar dreifist jafnt á milli starfsmannaþráða. Þetta er hægt að leysa með því að innleiða jöfnun starfsmannatenginga, sem gerir kleift að skiptast á tengingum milli starfsmannaþráða.

Niðurstaða

Þræðingarlíkan Envoy er hannað til að auðvelda forritun og gríðarlega samsvörun á kostnað hugsanlega sóunar á minni og tengingum ef ekki er rétt stillt. Þetta líkan gerir því kleift að standa sig mjög vel við mjög háa þráðafjölda og afköst.
Eins og ég minntist stuttlega á á Twitter, getur hönnunin einnig keyrt ofan á fullan netstafla með notandastillingu eins og DPDK (Data Plane Development Kit), sem getur leitt til þess að hefðbundnir netþjónar meðhöndla milljónir beiðna á sekúndu með fullri L7 vinnslu. Það verður mjög áhugavert að sjá hvað verður byggt á næstu árum.
Ein síðasta stutta athugasemd: Ég hef margoft verið spurður hvers vegna við völdum C++ fyrir Envoy. Ástæðan er sú að það er enn eina mikið notaða iðnaðarmálið sem hægt er að byggja upp arkitektúrinn sem lýst er í þessari færslu. C++ er örugglega ekki hentugur fyrir öll eða jafnvel mörg verkefni, en fyrir ákveðin notkunartilvik er það samt eina tólið til að vinna verkið.

Tenglar á kóða

Tenglar á skrár með viðmótum og hausútfærslum sem fjallað er um í þessari færslu:

Heimild: www.habr.com

Bæta við athugasemd