MÔnikord tÀhendab rohkem vÀhem. Kui koormuse vÀhendamine toob kaasa viivituse suurenemise

Nagu ka enamiku postituste, tekkis probleem jaotatud teenusega, nimetame seda teenust Elviniks. Seekord ei avastanud ma probleemi ise, vaid teatasid sellest kliendipoolsete kolleegide.

Üks pĂ€ev Ă€rkasin ma rahulolematust kirjast Elvini suurte latentsuste tĂ”ttu, mille me plaanisime peagi kĂ€ivitada. EeskĂ€tt koges klient 99. protsentiili latentsust umbes 50 ms, mis oli meie latentsuspiirist oluliselt kĂ”rgem. See oli ĂŒllatav, kuna olin teenust pĂ”hjalikult testinud, eriti latentsuse osas, kuna see on sagedane kaebuste teema.

Enne, kui andsin Elvini testimiseks, tegin ma palju eksperimente 40 tuhande pĂ€ringu sekundis (QPS) juures, kĂ”ik nĂ€itasid vĂ€hem kui 10 ms latentsust. Olin valmis vĂ€itma, et ei nĂ”ustu nende tulemustega. Kuid jĂ€lle vaadates kirja, pöörasin tĂ€helepanu millelegi uuele: ma ei testinud tingimusi, millest nad rÀÀkisid, nende QPS oli oluliselt madalam kui minu. Ma testisin 40k QPS korral, nad aga ainult 1k. KĂ€ivitasin veel ĂŒhe eksperimendi, seekord madalama QPS-iga, et neid rahuldada.

Kuna ma kirjutan sellest blogis - tĂ”enĂ€oliselt olete juba aru saanud: nende numbrid osutusid Ă”igeks. Kontrollisin oma virtuaalset klienti ikka ja jĂ€lle, saades sama tulemuse: madal pĂ€ringute arv suurendab mitte ainult latentsust, vaid ka pĂ€ringute arvu, mis ĂŒletavad 10 ms. TeisisĂ”nu, kui 40k QPS korral ĂŒletas umbes 50 pĂ€ringut sekundis 50 ms, siis 1k QPS korral oli iga sekundi jooksul 100 pĂ€ringut ĂŒle 50 ms. Paradoks!

MÔnikord tÀhendab rohkem vÀhem. Kui koormuse vÀhendamine toob kaasa viivituse suurenemise

VĂ€hendame kahtlusaluste ringi

Kui seisame silmitsi latentsusprobleemiga jaotatud sĂŒsteemis, kus on palju komponente, tuleb kĂ”igepealt koostada lĂŒhike kahtlusaluste nimekiri. Kaevame Elvini arhitektuuris veidi sĂŒgavamale:

MÔnikord tÀhendab rohkem vÀhem. Kui koormuse vÀhendamine toob kaasa viivituse suurenemise

Hea alguspunkt on loetelu tehtud sisendi-vĂ€ljundi ĂŒleminekest (vĂ”rgukutsed / kettale otsimine jne). Proovime vĂ€lja mĂ”elda, kus on latentsus. Lisaks ilmselgele sisendi-vĂ€ljundi suhtlemisele kliendiga, teeb Elvin veel ĂŒhe sammu: ta pöördub andmesalvestuse poole. Siiski töötab see salvestus Elvini kĂ”rval ĂŒhes klastris, seega peaks selle latentsus olema vĂ€iksem kui kliendiga. Seega on kahtlusaluste nimekiri:

  1. VÔrgukutse kliendilt Elvinile.
  2. VÔrgukutse Elvinilt andmesalvesse.
  3. Otsimine kettal andmesalvestuses.
  4. Andmehoidla vÔrgu kÔne Elvini suunas.
  5. VÔrgu kÔne Elvini suunast kliendi suunas.

Proovime mÔned punktid vÀlja jÀtta.

Andmehoidla ei ole seotud.

Esimese asjana muutsin Elvini ping-ping serveriks, mis ei töötle pĂ€ringuid. PĂ€ringu saades tagastab ta tĂŒhi vastus. Kui viivitus vĂ€heneb, on probleem Elvini vĂ”i andmehoidla rakenduses — midagi ulmelist pole. Esimeses katses saame sellise graafiku:

MÔnikord tÀhendab rohkem vÀhem. Kui koormuse vÀhendamine toob kaasa viivituse suurenemise

Kuidas me nÀeme, ei tÀheldata ping-ping serveri kasutamisel mingeid parandusi. See tÀhendab, et andmehoidla ei suurenda viivitust, ja kahtlusaluste nimekiri vÀheneb poole vÔrra:

  1. VÔrgukutse kliendilt Elvinile.
  2. VÔrgu kÔne Elvini suunast kliendi suunas.

Super! Nimekirja vÀheneb kiiresti. Ma arvasin, et olen peaaegu pÔhjuse vÀlja selgitanud.

gRPC

NĂŒĂŒd on Ă”ige aeg tutvustada teile uut mĂ€ngijat: gRPC. See on Google'i avatud lĂ€htekoodiga raamistik sisepoolsete suhtlemiseks. RPC. Kuigi gRPC on hĂ€sti optimeeritud ja laialdaselt kasutatud, kasutasin ma seda esmakordselt sellise mastaabisĂŒsteemi puhul ning ootasin, et minu rakendus oleks, pehmelt öeldes, mitteoptimaalne.

Standardsete moodulite komplekti olemasolu gRPC tegelikult tĂ”i meelde uue kĂŒsimuse: vĂ”ib-olla on probleem viivituses minu rakenduses vĂ”i ise gRPC ? Lisa nimekirja uus kahtlane:

  1. Kliendi poolt kutsutud raamatukogu gRPC
  2. Raamatukogu gRPC kliendis teostab raamatukogu vÔrgu kÔne gRPC serveris
  3. Raamatukogu gRPC viitab Elvinile (ping-pong serveri korral operatsiooni pole)

Et sa mĂ”istaksid, milline on kood, on minu kliendi/Elvini rakendus ĂŒsna sarnane kliendi-serveri async nĂ€idistele..

MĂ€rkus: ĂŒlaltoodud nimekiri on veidi lihtsustatud, sest gRPC annab vĂ”imaluse kasutada oma (malle?) voogudemudelit, milles pĂ”imuvad tĂ€itmissteek gRPC ja kasutaja rakendus. Lihtsuse huvides jÀÀme selle mudeli juurde.

Profiliseerimine parandab kÔik.

Andmehoidlad vĂ€lja jĂ€ttes arvasin, et olen peaaegu valmis: „NĂŒĂŒd on lihtne! Rakendame profiili ja uurime, kus viivitus tekib.“ Ma olen suur tĂ€pse profiilimise toetaja, sest CPU on vĂ€ga kiired ega ole sageli kitsaskohaks. Enamik viivitusi toimub siis, kui protsessor peab töötlemise peatama, et teha midagi muud. TĂ€pne CPU profiilimine ongi selleks, et see salvestab tĂ€pselt kĂ”ik konteksti vahetused ja annab arusaama, kus viivitused tekivad.

Otsisin nelja profiili: kÔrge QPS (madal viivitus) ja ping-pongi server madala QPS-iga (suur viivitus), nii kliendi kui ka serveri poolel. Ja lihtsalt igaks juhuks vÔtsin ka protsessori profiili nÀidise. Profiilide vÔrdlemisel otsin tavaliselt ebanormaalset kutsungihunnikut. NÀiteks halva jÔudlusega, kÔrge viivituse korral toimub konteksti vahetamine palju sagedamini (10 ja rohkem korda). Kuid minu puhul oli konteksti vahetuste arv praktiliselt sama. Mu kohutuseks polnud seal midagi olulist.

Lisa tÔrkeotsing

Olin meeleheitel. Ma ei teadnud, milliseid tööriistu veel kasutada, ja minu jÀrgmine plaan seisnes pÔhimÔtteliselt katsete kordamises erinevate variatsioonidega, mitte probleemide tÀpses diagnoosimises.

Mis siis, kui

Alates esimesest hetkest hĂ€iris mind konkreetselt 50 ms viivitus. See on vĂ€ga suur aeg. Otsustasin kĂ€rpida kooditĂŒkke, kuni suudan tĂ€pselt vĂ€lja selgitada, milline osa selle vea pĂ”hjustab. SeejĂ€rel jĂ€rgnes katse, mis töötas.

Kuid tavaliselt tundub tagantjĂ€rele, et kĂ”ik oli ilmne. Asetasin kliendi ĂŒhele masinale Elvini juurde — ja saatsin pĂ€ringu localhost. Ja viivituse suurenemine kadus!

MÔnikord tÀhendab rohkem vÀhem. Kui koormuse vÀhendamine toob kaasa viivituse suurenemise

Midagi ei olnud otseselt korras vÔrguga.

Omandame vÔrguinseneri oskusi

Pean tunnistama: minu teadmised vÔrgu tehnoloogiatest on kohutavad, arvestades, et töötan nendega iga pÀev. Kuid vÔrk oli peamine kahtlusalune ja mul tuli Ôppida, kuidas seda tÔrkeotsinguks kasutada.

Õnneks armastab internet Ă”ppida tahtega inimesi. Ping ja tracert kombinatsioon tundus olevat piisavalt hea algus vĂ”rgu transportimise probleemide tĂ”rkeotsinguks.

Esiteks jooksin PsPing Elvini TCP-porti. Kasutasin vaikeseadeid — midagi erilist. Üle tuhande pingimisi ei ĂŒletanud ĂŒkski 10 ms, vĂ€lja arvatud esimene soojenduseks. See on vastuolus 50 ms viivituse suurenemisega 99. protsendilis: seal peaks iga 100 pĂ€ringu kohta olema umbes ĂŒks pĂ€ring 50 ms viivitusega.

SeejĂ€rel proovisin tracert: ehk probleem on ĂŒhe sĂ”lme juures marsruudi vahel Elvini ja kliendi vahel. Kuid jĂ€lgija tuli ka tĂŒhjade kĂ€tega tagasi.

SeelÀbi ei olnud viivituse pÔhjus minu koodis, gRPC rakenduses ega vÔrgus. Olin juba hakanud muretsema, et ma ei saa seda kunagi aru.

NĂŒĂŒd, millisel opsĂŒsteemil me oleme

gRPC kasutatakse laialdaselt Linuxis, kuid Windowsis on see eksootiline. Otsustasin teha eksperimenti, mis Ônnestus: lÔin Linuxi virtuaalmasina, kompileerisin Elvini Linuxile ja juurutasin selle.

MÔnikord tÀhendab rohkem vÀhem. Kui koormuse vÀhendamine toob kaasa viivituse suurenemise

Ja siin on, mis juhtus: Linuxi ping-pong serveris ei olnud viivitusi nagu sarnasel Windowsi soliidil, kuigi andmeallikas ei olnud erinev. Selgub, et probleem on gRPC rakenduses Windowsile.

Neygle algoritm

Kogu selle aja arvasin, et mul puudub lipp gRPC. NĂŒĂŒd sain aru, et tegelikult see on Windowsi gRPC lipu puudumine. Leidsin sisemise RPC teegi, mille suhtes olin kindel, et see töötab hĂ€sti kĂ”ikide installitud lipudega Winsock. SeejĂ€rel lisasin kĂ”ik need lipud gRPC-sse ja juurutasin Elvini Windowsis, parandatud ping-pong serveris Windowsile!

MÔnikord tÀhendab rohkem vÀhem. Kui koormuse vÀhendamine toob kaasa viivituse suurenemise

Peaaegu valmis: hakkasin eemaldama lisatud lippe ĂŒkshaaval, kuni regressioon naasis, nii et sain tĂ€pselt mÀÀrata selle pĂ”hjuse. See oli kurikuulus TCP_NODELAY, Neygle algoritmi lĂŒliti.

Neygle algoritm ĂŒritab vĂ€hendada vĂ”rgu kaudu saadetavate pakkide arvu, viivitades sĂ”numite saatmist, kuni pakendi suurus ĂŒletab teatud baitide arvu. Kuigi see vĂ”ib keskmisele kasutajale olla meeldiv, on see reaalajas serveritele hĂ€vitav, kuna opsĂŒsteem viivitab teatud sĂ”numitega, pĂ”hjustades madala QPS-i korral viivitusi. Sellel gRPC lipp oli Linuxi TCP sokettide rakenduses paigaldatud, kuid mitte Windowsis. Ma tean, et parandasin.

KokkuvÔte

Suur viivitus madala QPS-i korral pĂ”hjustas opsĂŒsteemi optimeerimine. Tagasi vaadates ei avastanud proffiilimine viivitust, kuna see toimus tuuma reĆŸiimis, mitte kasutajareĆŸiimis. Ma ei tea, kas Neygle algoritmi on vĂ”imalik ETW konsoolidest nĂ€ha, kuid see oleks huvitav.

Mis puudutab localhosti eksperimenti, siis see tÔenÀoliselt ei puudutanud tegelikku vÔrgu koodi ja Neygle algoritm ei kÀivitunud, seega kadusid viivitusega probleemid, kui klient pöördus Elvini poole localhosti kaudu.

JÀrgmine kord, kui nÀete viivituse suurenemist sekundite arvu vÀhenedes, peaks Neygle algoritm olema teie kahtlusaluste nimekirjas!

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster