Ashtu si në , u shfaq një problem me shërbimin e shpërndarë, le ta quajmë këtë shërbim Elvin. Këtë herë nuk e zbulova vetë problemin, më thanë djemtë nga ana e klientit.
Një herë u zgjova nga një letër të pakënaqur për vonesa të mëdha me Elvinin, të cilin ne planifikonim ta lansojmë së shpejti. Në veçanti, klienti u përball me një vonesë 99 për qind rreth 50 ms, shumë më e lartë se buxheti ynë i vonesave. Ishte e habitshme, pasi unë e kam testuar me kujdes shërbimin, veçanërisht për vonesat, pasi kjo është një çështje ankesash të shpeshta.
Përpara se t'i dorëzoja Elvinin për testim, unë kam bërë shumë eksperimente me 40,000 kërkesa në sekundë (QPS), të gjitha treguan vonesë më të vogël se 10 ms. Ishte gati të deklaroja se nuk isha dakord me rezultatet e tyre. Por duke e parë sërish letrën, vura re diçka të re: unë me siguri nuk e kam testuar kushtet që ata përmendën, QPS e tyre ishte shumë më e ulët se e imja. Unë kam testuar me 40k QPS, ndërsa ata vetëm me 1k. Pata një eksperiment tjetër, këtë herë me një QPS më të ulët, vetëm për t'i kënaqur ata.
Pasi po e shkruaj kĂ«tĂ« nĂ« blog â ndoshta e keni kuptuar tashmĂ«: numrat e tyre dolĂ«n tĂ« ishin tĂ« saktĂ«. UnĂ« e kontrollova klientin tim virtual pĂ«rsĂ«ri e 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Ă« mbi 10 ms. Me fjalĂ« tĂ« tjera, nĂ« 40k QPS, rreth 50 kĂ«rkesa nĂ« sekundĂ« kalonin 50 ms, ndĂ«rsa nĂ« 1k QPS, çdo sekondĂ« kishte 100 kĂ«rkesa mĂ« shumĂ« se 50 ms. Paradoxi!

Ngushtoni kërkimin
Duke u përballur me problemin e vonesës në një sistem të shpërndarë me shumë komponente, gjëja e parë që duhet bërë është të krijoni një listë të shkurtër të të dyshuarve. Le të shqyrtojmë më thellë arkitekturën e Elvin:

Një pikë e mirë fillimi është lista e kalimeve të kryera të hyrjeve-daljeve (thirrjet rrjetore/kërkimi në disk etj.). Le të përpiqemi të kuptojmë, ku qëndron vonesa. Përveç hyrjes-daljes evidente me klientin, Elvini bën një hap shtesë: ai i drejtohet magazinës së të dhënave. Megjithatë, kjo magazinë funksionon në të njëjtin grup me Elvin, kështu që atje vonesa duhet të jetë më e vogël se me klientin. Prandaj, lista e të dyshuarve:
- Thirrja rrjetore nga klienti te Elvini.
- Thirrja rrjetore nga Elvini te magazina e të dhënave.
- Kërkimi në disk në magazinën e të dhënave.
- Thirrje rrjeti nga depoja e të dhënave te Elvini.
- Thirrje rrjeti nga Elvini te klienti.
Le të përpiqemi të fshijmë disa pika.
Depoja e të dhënave nuk ka lidhje.
SĂ« pari, unĂ« e transformova Elvinin nĂ« njĂ« server ping-ping, i cili nuk pĂ«rpunon kĂ«rkesat. Pas marrjes sĂ« njĂ« kĂ«rkese, ai ktheu njĂ« pĂ«rgjigje bosh. NĂ«se vonesa zvogĂ«lohet, atĂ«herĂ« problemi ndodhet nĂ« realizimin e Elvinin ose tĂ« depoes sĂ« tĂ« dhĂ«nave â asgjĂ« qĂ« sâka ndodhur mĂ« parĂ«. NĂ« eksperimentin e parĂ«, ne marrim njĂ« grafik tĂ« tillĂ«:

Siç e shohim, përdorimi i serverit ping-ping nuk tregon asnjë përmirësim. Kjo do të thotë se depoja e të dhënave nuk e rrit vonesën, dhe lista e dyshuarve zvogëlohet me gjysmë:
- Thirrja rrjetore nga klienti te Elvini.
- Thirrje rrjeti nga Elvini te klienti.
Super! Lista po zvogëlohet shpejt. Mendova se pothuajse e zbardha arsyeja.
gRPC
Tani Ă«shtĂ« koha pĂ«r t'ju njohur me njĂ« lojtar tĂ« ri: . Kjo Ă«shtĂ« njĂ« bibliotekĂ« me kod tĂ« hapur nga Google pĂ«r komunikimin brenda procesit. . MegjithatĂ«, gRPC nuk Ă«shtĂ« mirĂ« optimizuar dhe Ă«shtĂ« pĂ«rdorur gjerĂ«sisht, unĂ« e kam pĂ«rdorur pĂ«r herĂ« tĂ« parĂ« nĂ« njĂ« sistem tĂ« kĂ«tij niveli, dhe prisja qĂ« realizimi im do tĂ« ishte jo optimal â pĂ«r ta thĂ«nĂ« lehtĂ«sisht.
Prania gRPC në stek ka lindur një pyetje të re: ndoshta, kjo është realizimi im ose vetë gRPC po shkakton problemin e vonesës? Po e shtojmë në listën e dyshuarve të reja:
- Klienti thërret bibliotekën
gRPC - Biblioteka
gRPCnë klient ekzekuton thirrjen rrjetit të bibliotekësgRPCnë serverin - Biblioteka
gRPCkthen te Elvini (nuk ka operacione në rastin e serverit ping-pong)
PĂ«r tâu kuptuar se si duket kodi, realizimi im i klientit/Elvinin nuk ndryshon shumĂ« nga .
Shënim: lista e mësipërme është pak e thjeshtuar, pasi
gRPCmerr mundësinë e përdorimit të modelit të qarkullimit të vetë (me template?), ku lidhin e stek të ekzekutimitgRPCdhe implementimi i përdoruesit. Për thjeshtësi, do të qëndrojmë në këtë model.
Profilizimi do ta zgjidhë gjithçka.
Duke fshirĂ« depojat e tĂ« dhĂ«nave, mendova se pothuajse e pĂ«rfundova: âTani Ă«shtĂ« e lehtĂ«! Do ta pĂ«rdorim profilin dhe do tĂ« zbulojmĂ« se ku ndodh vonesa.â UnĂ« sepse CPU-tĂ« janĂ« shumĂ« tĂ« shpejtĂ« dhe shpesh nuk janĂ« ngushtica. 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 Ă«shtĂ« bĂ«rĂ« posaçërisht pĂ«r kĂ«tĂ«: regjistron saktĂ«sisht tĂ« gjitha dhe tregon se ku ndodhin vonesat.
Mora mora kam tre profile: për QPS të lartë (vonesa e vogël) dhe me server ping-pong në QPS të ulët (vonese e madhe), si në anën e klientit ashtu edhe në anën e serverit. Dhe thjesht për të qenë në rast, mora edhe një mostër të profilit të procesorit. Kur krahasoja profilet, zakonisht kërkoja një stak thirrjesh anomale. Për shembull, në anën e keqe me vonesë të lartë ndodhin shumë më tepër ndërrime konteksti (10 ose më shumë herë). Por në rastin tim, numri i ndërrimeve të kontekstit ishte praktikisht i njëjtë. Për habinë time, nuk kishte asgjë thelbësore.
Debugging shtesë
Isha në dëshpërim. Nuk dija çfarë mjete të tjera mund të përdorja, dhe plani im i ardhshëm ishte esencialisht përsëritja e eksperimenteve me variacione të ndryshme, në vend të diagnostikimit të saktë të problemit.
ĂfarĂ«, nĂ«se
Që nga fillimi, më shqetësonte një vonesë e caktuar prej 50 ms. Kjo është shumë kohë. Vendosa të prisja pjesë nga kodi derisa të mund të zbuloja saktësisht se cila pjesë shkaktonte këtë gabim. Pastaj pasoi një eksperiment që funksionoi.
Si zakonisht, pas retrospektivës gjithçka dukej e dukshme. Vendosa klientin në një makinë me Elvinin - dhe dërgova kërkesën në localhost. Dhe rritja e vonesës u zhduk!

Diçka nuk ishte në rregull me rrjetin.
Mësojmë aftësitë e inxhinierit të rrjetit
Duhet të pranoj: njohuritë e mia rreth teknologjisë së rrjetit janë të tmerrshme, sidomos duke marrë parasysh se punoj me to çdo ditë. Por rrjeti ishte i dyshuari kryesor dhe duhej të mësoja se si ta diagnostikoj.
Kateqoriya: Parametr/Spesifikasiya | Etibarlılıq sinfi: Tier III+ (SLA 99.99%) | YerlÉĆmÉ: Sofiya, Bolqarıstan (Ovçe Pole kĂŒĂ§Ési, 122) | SertifikatlaĆdırma: ISO 27001:2013, ISO 9001:2015, PCI DSS 4.0 | Elektrik tÉchizatı: 3 mĂŒstÉqil 10 kV giriĆ + öz yarımstansiyası | Ehtiyat gĂŒc tÉchizatı: 6 dizel-generator (4.8 MVt), UPS N+1 (AC/DC) | Soyutma: N+1 dÉqiqlikli kondisionerlÉr, stellaj baĆına 12 kVt-a qÉdÉr | ĆÉbÉkÉ vÉ ÉlaqÉ: Carrier-neutral, mĂŒstÉqil optik giriĆlÉr, Meet-Me Rooms | YanÄınsöndĂŒrmÉ: VESDA erkÉn aĆkarlama sistemi, FM200 vÉ IG-55 qazı | TÉhlĂŒkÉsizlik: 24/7 mĂŒhafizÉ, biometrik giriĆ nÉzarÉti, CCTV | DÉstÉk: Smart Hands-and-Eyes 24/7/365
Bolqarıstanda serverlÉr Imgi 3 trendy isometric icon electrical panel 9206 10922
Imgi 38 big data analytics abstract concept vector illustration 107173 25643 Imgi 2 premium hosting using man woman users vector boy girl use laptop connected server premium hosting characters connectivity cyberspace technology fla
Pra, arsyeja e vonesës nuk ishte kodi im, as implementimi i gRPC dhe as rrjeti. Kisha filluar të shqetësohesha 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ë ekzotike. Vendosa të bëja një eksperiment që funksionoi: krijova një makinë virtuale Linux, kompilova Elvinin për Linux dhe e vendosa.

Dhe ja çfarë ndodhi: në serverin ping-pong Linux nuk kishte ato vonesa si në nodin përkatës Windows, megjithëse burimi i të dhënave nuk ndryshonte. Doli se problemi ishte në implementimin e gRPC për Windows.
Algoritmi Neigel
Gjatë gjithë kësaj kohe mendoja se më mungonte flagu gRPC. Tani e kuptoj se në të vërtetë mungonte flagu në gRPC Windows. Gjeta një bibliotekë të brendshme RPC, për të cilën isha i sigurt se punonte mirë për të gjithë flagat e instaluara . Më pas, i shtova të gjitha këto flamuj në gRPC dhe e zhvillova Alvinin në Windows, në serverin e rregulluar ping-pong nën Windows!

Gati : fillova të hiqja flamujt e shtuar një nga një, derisa të rikthehej regresioni, kështu që arrita të identifikoj saktësisht shkakun e tij. Ishte ai i njohur , ndërruesi i algoritmit Nagle.
përpiqet të reduktojë numrin e paketimeve të dërguara në rrjet duke vonuar dërgimin e mesazheve derisa madhësia e paketës të kalojë një numër të caktuar bajtësh. Ndërsa kjo mund të jetë e dobishme për përdoruesit e zakonshëm, është shkatërruese për serverat në kohë reale, pasi OS do të vonojë disa mesazhe, duke shkaktuar vonesa në një QPS të ulët. Ky gRPC flamur ishte vendosur në implementimin Linux për soket TCP, por jo për Windows. E kuptova këtë .
Përfundim
Vonesa e madhe në një QPS të ulët ishte shkaktuar nga optimizimi i OS-së. Duke e parë mbrapa, profilizimi nuk zbuloi vonesën, sepse u krye në modin bërthamë dhe jo në . Nuk e di nëse mund të vëzhgohet algoritmi Nagle përmes kapjesh ETW, por kjo do të ishte interesante.
Sa i përket eksperimentit localhost, ndoshta nuk ishte në lidhje me kodin e vërtetë të rrjetit, dhe algoritmi Nagle nuk ishte aktivizuar, prandaj problemet me vonesat u zhdukën kur klienti iu drejtua Alvinit përmes localhost.
Herën tjetër që do të shihni një rritje të vonesave kur të ulni numrin e kërkesave për sekondë, algoritmi Nagle duhet të jetë në listën tuaj të të dyshuarve!
Burimi: habr.com
