Ndonjëherë më shumë është më pak. Kur reduktimi i ngarkesës çon në rritjen e vonesës

As in në shumicën e postimeve, u shfaq një problem me shërbimin e shpërndarjes, le të quajmë këtë shërbim Elvini. Këtë herë nuk e kam zbuluar vetë problemin, më e lajmëruan djemtë nga ana e klientit.

Një herë u zgjova nga një letër të pakënaqur për shkak të vonesave të mëdha me Elvinin, të cilin e kishim planifikuar ta lançonim së shpejti. Së veçanti, klienti përjetoi një vonesë 99 përqind në rreth 50 ms, shumë më lart se buxheti ynë për vonesat. Ishte befasuese, pasi unë e kisha testuar me kujdes shërbimin, veçanërisht për vonesat, pasi kjo është një temë ankimesh të shpeshta.

Para se ta dërgoja Elvin për testim, kam bërë shumë eksperimente me 40 mijë kërkesa në sekondë (QPS), të gjitha treguan vonesë më të vogël se 10 ms. Ishim të gatshëm të deklaronim se nuk ishim dakord me rezultatet e tyre. Por duke e shqyrtuar sërish letrën, vura re diçka të re: nuk isha testuar nën kushtet që ata përmendën, dhe QPS i tyre ishte shumë më i ulët se i imi. Unë testova me 40k QPS, ndërsa ata vetëm me 1k. Kësaj here, nisa një eksperiment tjetër, me një QPS më të ulët, thjesht për t'i bërë qejfin atyre.

Pasi shkruaj pĂ«r kĂ«tĂ« nĂ« blog — ndoshta keni kuptuar se numrat e tyre ishin tĂ« saktĂ«. E kam verifikuar klientin tim virtual pĂ«rsĂ«ri dhe pĂ«rsĂ«ri, gjithmonĂ« me tĂ« njĂ«jtin rezultat: numri i ulĂ«t i kĂ«rkesave jo vetĂ«m qĂ« rrit vonesĂ«n, por rrit gjithashtu numrin e kĂ«rkesave me vonesĂ« mĂ« shumĂ« se 10 ms. Me fjalĂ« tĂ« tjera, nĂ« 40k QPS, rreth 50 kĂ«rkesa nĂ« sekondĂ« kalonin 50 ms, ndĂ«rsa nĂ« 1k QPS çdo sekondĂ« kishte 100 kĂ«rkesa mĂ« shumĂ« se 50 ms. Paradoxi!

Ndonjëherë më shumë është më pak. Kur reduktimi i ngarkesës çon në rritjen e vonesës

Të ngushtohemi në kërkim

Kur përballesh me një problem vonese në një sistem të shpërndarë me shumë komponentë, hapi i parë është të krijosh një listë të shkurtër të të dyshuarve. Le të thellohemi pak më shumë në arkitekturën e Elvin-it:

Ndonjëherë më shumë është më pak. Kur reduktimi i ngarkesës çon në rritjen e vonesës

Një pikë e mirë fillestare është lista e kalimeve të realizuara të hyrjeve dhe daljeve (thirrjet rrjet/ kërkimi në disk, etj.). Le të përpiqemi të zbulojmë se ku është vonesa. Përveç hyrjeve dhe daljeve të dukshme me klientin, Elvin bën një hap të mëtejshëm: ai i drejtohet depozitës së të dhënave. Megjithatë, kjo depozitë punon në të njëjtin klaster me Elvin-in, prandaj aty vonesa duhet të jetë më e ulët se me klientin. Pra, lista e të dyshuarve:

  1. Thirrja rrjet nga klienti tek Elvin.
  2. Thirrje rrjeti nga Elvini në magazinën e të dhënave.
  3. Kërkimi në diskun e magazinës së të dhënave.
  4. Thirrje rrjeti nga magazina e të dhënave te Elvini.
  5. Thirrje rrjeti nga Elvini te klienti.

Le të provosh të përjashtosh disa pikë.

Magazina e të dhënave nuk ka lidhje.

E para që kam bërë është të konvertoj Elvinin në një server ping-ping, i cili nuk përpunon kërkesat. Pasi merr një kërkesë, kthen një përgjigje bosh. Nëse koha e vonesës zvogëlohet, atëherë problemi është në implementimin e Elvinit ose në magazinën e të dhënave - asgjë e pabesueshme. Në eksperimentin e parë, marrim këtë grafik:

Ndonjëherë më shumë është më pak. Kur reduktimi i ngarkesës çon në rritjen e vonesës

Siç e shohim, duke përdorur serverin ping-ping, nuk ka përmirësime të dukshme. Kjo do të thotë se magazina e të dhënave nuk rrit vonesën, dhe lista e të dyshuarve zvogëlohet në gjysmë:

  1. Thirrja rrjet nga klienti tek Elvin.
  2. Thirrje rrjeti nga Elvini te klienti.

Super! Lista po zvogëlohet shpejt. Mendova se pothuajse e zbulova shkakun.

gRPC

Tani është koha për të ju prezantuar me një lojtar të ri: gRPC. Kjo është një bibliotekë me kod të hapur nga Google për komunikimin brenda procesit. RPC. Ndërsa gRPC është mirë e optimizuar dhe përdoret gjerësisht, është hera e parë që e përdor në një sistem të tillë në këtë shkallë, dhe prisja që implementimi im do të jetë jo optimal - për ta thënë butë.

Prania gRPC në grumbull, krijoi një pyetje të re: ndoshta është implementimi im apo vetë gRPC po shkakton një problem vonese? Shtojmë në listën e të dyshuarve të rinj:

  1. Klienti thërret biblioteken gRPC
  2. Biblioteka gRPC në klient bën një thirrje rrjeti të biblioteks gRPC në server
  3. Biblioteka gRPC i drejtohet Elvinit (në rastin e serverit ping-pong nuk ka operacione)

Për të kuptuar se si duket kodi, implementimi im i klientit/Elvinit nuk ndryshon shumë nga shembujt e klient-serverëve shembuj async.

Vërejtje: lista e mësipërme është pak e thjeshtëzuar, pasi gRPC lejon përdorimin e modelit të vet (me shabllon?) të rrjedhës, ku ndërthuren grumbulli i ekzekutimit gRPC dhe implementimi i përdoruesit. Për thjeshtësi, le të qëndrojmë në këtë model.

Profilizimi do të zgjidhë gjithçka

Duke hequr magazinat e të dhënave, mendoja se isha gati: "Tani është e lehtë! Do të aplikojmë profilin dhe do të shohim ku ndodh vonesa". Unë jam një adhurues i madh i profilizimit të saktë, sepse CPU janë shumë të shpejtë dhe shpesh nuk janë pika të ngushta. Shumica e vonesave ndodhin kur procesori duhet të ndalojë përpunimin për të bërë diçka tjetër. Profilizimi i saktë i CPU-së është bërë pikërisht për këtë: regjistron saktësisht të gjitha ndërrimet kontekstuale dhe tregon se ku ndodhin vonesat.

Mora katër profile: nën QPS të lartë (vonësi e vogël) dhe me një server ping-pong në QPS të ulët (vonësi e madhe), si në anën e klientit ashtu edhe në anën e serverit. Dhe për të qenë i sigurt, gjithashtu mora një mostër të profilit të procesorit. Kur krahasoj profile, zakonisht kërkoj një grumbull të çuditshëm thirrjesh. Për shembull, në anën e keqe me vonësi të lartë ka shumë më tepër ndërrime kontekstuale (10 herë e më shumë). Por në rastin tim, numri i ndërrimeve kontekstuale ishte pothuajse i njëjtë. Për të tmerrin tim, nuk kishte asgjë thelbësore.

Debugim shtesë

Isha në dëshpërim. Nuk dija cilat mjete të tjera mund të përdorja, dhe plani im i ardhshëm përbënte thelbësisht përsëritjen e eksperimenteve me variacione të ndryshme, dhe jo diagnostikimin e qartë të problemit.

ÇfarĂ«, nĂ«se

QĂ« nĂ« fillim, mĂ« shqetĂ«sonte vonesa specifike prej 50 ms. ËshtĂ« njĂ« kohĂ« shumĂ« e gjatĂ«. Vendosa tĂ« prerĂ« pjesĂ« nga kodi derisa tĂ« zbuloja saktĂ«sisht cili pjesĂ« shkaktonte kĂ«tĂ« problem. MĂ« pas, ndodhi njĂ« eksperiment qĂ« funksionoi.

Si zakonisht, me mendje pas ngjarjeve duket se gjithçka ishte e dukshme. Vendosa klientin në një makinë me Elvinin dhe dërgova një kërkesë në localhost. Dhe vonesa u zhduk!

Ndonjëherë më shumë është më pak. Kur reduktimi i ngarkesës çon në rritjen e vonesës

Diçka nuk ishte në rregull me rrjetin.

Duke mësuar aftësitë e inxhinierit të rrjetit

Duhet të pranoj: njohuritë e mia për teknologjitë e rrjetit janë të frikshme, veçanërisht duke qenë se punoj me to çdo ditë. Por rrjeti ishte të dyshuar kryesor, dhe duhej të mësoja si ta diagnostikoj.

Fatmirësisht, interneti i pëlqen atyre që duan të mësojnë. Kombinimi i ping dhe tracert duket se ishte një fillim mjaft i mirë për diagnostikimin e problemeve të transportit në rrjet.

SĂ« pari, e pata PsPing nĂ« portin TCP tĂ« ElvinĂ«s. Kam pĂ«rdorur parametrat e paracaktuar — asgjĂ« e veçantĂ«. Nga mĂ« shumĂ« se njĂ« mijĂ« ping-Ă«, asnjĂ« nuk kaloi 10 ms, pĂ«rveç tĂ« parit pĂ«r pĂ«rgatitje. Kjo Ă«shtĂ« nĂ« kundĂ«rshtim me rritjen e vonesĂ«s prej 50 ms nĂ« percentilin 99: aty pĂ«r çdo 100 kĂ«rkesa ne duhet tĂ« shihnim rreth njĂ« kĂ«rkesĂ« me vonesĂ« 50 ms.

Pastaj provova tracert: ndoshta problemi ndodhet në njërin nga nodet në rrugën midis Elvinës dhe klientit. Por dhe tracer-i u kthye pa duar.

Pra, shkaku i vonesës nuk ishte kodi im, as realizimi i gRPC dhe as rrjeti. Ishte duke filluar të më shqetësonte se kurrë nuk do ta kuptoja këtë.

Tani, në cilën OS jemi

gRPC përdoret gjerësisht në Linux, por për Windows është ekzotik. Vendosa të bëj një eksperiment, që funksionoi: krijova një makinë virtuale Linux, kompilova Elvinën për Linux dhe e shpërndava atë.

Ndonjëherë më shumë është më pak. Kur reduktimi i ngarkesës çon në rritjen e vonesës

Dhe ja çfarë ndodhi: në serverin ping-pong të Linux-it nuk kishte vonesa të tilla si në noden përkatëse të Windows-it, megjithëse burimi i të dhënave nuk ndryshonte. Doli se problemi ishte në realizimin e gRPC për Windows.

Algoritmi i Neuglës

Gjatë gjithë kësaj kohe kam menduar se më mungonte flagu gRPC. Tani e kuptova se në të vërtetë është në gRPC më mungon flamuri Windows. Gjeta një bibliotekë të brendshme RPC, në të cilën isha i sigurt se funksiononte mirë për të gjitha flamujt e instaluar. Winsock. Pastaj shtova të gjithë këta flamuj në gRPC dhe e deploy-ova Elvin-in në Windows, në serverin e rregullt ping-pong nën Windows!

Ndonjëherë më shumë është më pak. Kur reduktimi i ngarkesës çon në rritjen e vonesës

Gati : fillova të hiqja flamujt e shtuar një e nga një, derisa regresioni të kthehej, kështu që arrita të përcaktoja saktësisht shkakun e tij. Ishte TCP_NODELAY, ndërruesi i algoritmit Nagle.

Algoritmi i Neuglës përpiqet të zvogëlojë numrin e paketimeve të dërguara në rrjet, duke vonuar dërgimin e mesazheve deri sa madhësia e paketës të kalojë një sasi të caktuar bajtësh. Megjithëse mund të jetë e këndshme për përdoruesin e zakonshëm, është shkatërruese për serverat në kohë reale, pasi OS do të vonojë disa mesazhe, duke shkaktuar vonesa në QPS të ulët. U gRPC vendos ky flamur në implementimin Linux për socket-at TCP, por jo për Windows. E kam rregulluar.

Përfundimi

Vonesën e madhe në QPS të ulët e shkaktoi optimizimi i OS. Me të kthyer pas, profilizimi nuk e zbuloi vonesën, sepse u krye në modin e bërthamës, e jo në modin e përdoruesit.. Nuk e di, nëse është e mundur të vëzhgosh algoritmin e Neigle përmes kapjes ETW, por do të ishte interesante.

Sa i përket eksperimentit localhost, ai ndoshta nuk preku kodin real të rrjetit, dhe algoritmi i Neigle nuk u aktivizua, kështu që problematika e vonesës u zhduk kur klienti u lidh me Elvinin përmes localhost.

Herën tjetër, kur të shihni një rritje të vonesës ndërsa ulni numrin e kërkesave për sekondë, algoritmi i Neigle duhet të jetë në listën tuaj të dyshimtëve!

Burimi: habr.com

Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster