Soos in
Ek het eendag wakker geword van 'n ontevrede e-pos weens lang vertragings met Alvin, wat ons beplan het om in die nabye toekoms bekend te stel. Die kliënt het spesifiek 99ste persentiel latency in die omgewing van 50 ms ervaar, ver bo ons latensiebegroting. Dit was verbasend aangesien ek die diens breedvoerig getoets het, veral oor latensie, wat 'n algemene klagte is.
Voordat ek Alvin in die toets geplaas het, het ek baie eksperimente uitgevoer met 40k navrae per sekonde (QPS), wat almal latency van minder as 10ms toon. Ek was gereed om te verklaar dat ek nie met hul resultate saamstem nie. Maar terwyl ek weer na die brief kyk, het ek iets nuuts opgemerk: ek het nie presies die toestande wat hulle genoem het, getoets nie, hul QPS was baie laer as myne. Ek het getoets teen 40k QPS, maar hulle het net by 1k. Ek het nog 'n eksperiment uitgevoer, hierdie keer met 'n laer QPS, net om hulle te paai.
Aangesien ek hieroor blog, het jy seker al agtergekom dat hulle nommers reg was. Ek het my virtuele kliënt oor en oor getoets, met dieselfde resultaat: 'n lae aantal versoeke verhoog nie net die latensie nie, maar verhoog die aantal versoeke met 'n latensie van meer as 10 ms. Met ander woorde, as by 40k QPS ongeveer 50 versoeke per sekonde 50 ms oorskry het, dan was daar by 1k QPS 100 versoeke bo 50 ms elke sekonde. Paradoks!
Vernou die soektog
Wanneer 'n vertragingsprobleem in 'n verspreide stelsel met baie komponente gekonfronteer word, is die eerste stap om 'n kort lys van verdagtes te skep. Kom ons delf 'n bietjie dieper in Alvin se argitektuur:
'n Goeie beginpunt is 'n lys van voltooide I/O-oorgange (netwerkoproepe/skyfopsoeke, ens.). Kom ons probeer uitvind waar die vertraging is. Benewens die ooglopende I/O met die kliënt, neem Alvin 'n ekstra stap: hy kry toegang tot die datastoor. Hierdie berging werk egter in dieselfde groep as Alvin, so die latensie daar moet minder wees as by die kliënt. Dus, die lys van verdagtes:
- Netwerkoproep van kliënt na Alvin.
- Netwerkoproep van Alvin na die datastoor.
- Soek op skyf in die datastoor.
- Netwerkoproep van die datapakhuis na Alvin.
- Netwerkoproep van Alvin na 'n kliënt.
Kom ons probeer om 'n paar punte deur te trek.
Databerging het niks daarmee te doen nie
Die eerste ding wat ek gedoen het, was om Alvin om te skakel na 'n ping-ping-bediener wat nie versoeke verwerk nie. Wanneer dit 'n versoek ontvang, gee dit 'n leë antwoord. As die latensie afneem, is 'n fout in die implementering van Alvin of datapakhuis niks ongehoord nie. In die eerste eksperiment kry ons die volgende grafiek:
Soos u kan sien, is daar geen verbetering wanneer u die ping-ping-bediener gebruik nie. Dit beteken dat die datapakhuis nie latensie verhoog nie, en die lys verdagtes word in die helfte gesny:
- Netwerkoproep van kliënt na Alvin.
- Netwerkoproep van Alvin na 'n kliënt.
Puik! Die lys krimp vinnig. Ek het gedink ek het amper die rede uitgepluis.
gRPC
Dit is nou die tyd om jou aan 'n nuwe speler bekend te stel: gRPC
goed geoptimaliseer en wyd gebruik, dit was die eerste keer dat ek dit op 'n stelsel van hierdie grootte gebruik het en ek het verwag dat my implementering suboptimaal sou wees - om die minste te sê.
Beskikbaarheid gRPC
in die stapel het aanleiding gegee tot 'n nuwe vraag: miskien is dit my implementering of myself gRPC
veroorsaak vertragingsprobleem? Voeg 'n nuwe verdagte by die lys:
- Die kliënt bel die biblioteek
gRPC
- Biblioteek
gRPC
maak 'n netwerkoproep na die biblioteek op die kliëntgRPC
op bediener - Biblioteek
gRPC
kontakte Alvin (geen bewerking in die geval van tafeltennisbediener nie)
Om jou 'n idee te gee van hoe die kode lyk, my kliënt/Alvin-implementering verskil nie veel van die kliënt-bediener nie
Let wel: Bogenoemde lys is 'n bietjie vereenvoudig omdat
gRPC
maak dit moontlik om jou eie (sjabloon?) inrygmodel te gebruik, waarin die uitvoeringstapel vervleg isgRPC
en gebruikersimplementering. Ter wille van eenvoud hou ons by hierdie model.
Profilering sal alles regmaak
Nadat ek die datawinkels deurgehaal het, het ek gedink ek is amper klaar: “Nou is dit maklik! Kom ons pas die profiel toe en vind uit waar die vertraging voorkom.” ek
Ek het vier profiele geneem: met hoë QPS (lae latency) en met 'n tafeltennisbediener met lae QPS (hoë latency), beide aan die kliëntkant en aan die bedienerkant. En net vir ingeval, ek het ook 'n voorbeeldverwerkerprofiel geneem. Wanneer ek profiele vergelyk, soek ek gewoonlik 'n anomalie oproepstapel. Byvoorbeeld, aan die slegte kant met hoë latensie is daar baie meer konteksskakelaars (10 keer of meer). Maar in my geval was die aantal konteksskakelaars amper dieselfde. Tot my afgryse was daar niks betekenisvols daar nie.
Bykomende ontfouting
Ek was desperaat. Ek het nie geweet watter ander gereedskap ek kon gebruik nie, en my volgende plan was in wese om die eksperimente met verskillende variasies te herhaal eerder as om die probleem duidelik te diagnoseer.
Wat as
Van die begin af was ek bekommerd oor die spesifieke 50ms latency. Dit is 'n baie groot tyd. Ek het besluit dat ek stukke uit die kode sal sny totdat ek presies kon uitvind watter deel hierdie fout veroorsaak. Toe kom 'n eksperiment wat gewerk het.
Soos gewoonlik, lyk dit agterna of alles voor die hand liggend was. Ek het die kliënt op dieselfde masjien as Alvin geplaas - en 'n versoek gestuur aan localhost
. En die toename in latensie is weg!
Iets was fout met die netwerk.
Leer netwerkingenieursvaardighede
Ek moet erken: my kennis van netwerktegnologieë is verskriklik, veral as in ag geneem word dat ek elke dag daarmee werk. Maar die netwerk was die hoofverdagte, en ek moes leer hoe om dit te ontfout.
Gelukkig is die internet lief vir diegene wat wil leer. Die kombinasie van ping en tracert het gelyk na 'n goeie begin om netwerkvervoerprobleme te ontfout.
Eerstens het ek begin
Toe probeer ek
Dit was dus nie my kode, die gRPC-implementering of die netwerk wat die vertraging veroorsaak het nie. Ek het begin bekommerd raak dat ek dit nooit sou verstaan nie.
Nou met watter OS is ons
gRPC
wyd gebruik op Linux, maar eksoties op Windows. Ek het besluit om 'n eksperiment te probeer, wat gewerk het: ek het 'n virtuele Linux-masjien geskep, Alvin vir Linux saamgestel en dit ontplooi.
En hier is wat gebeur het: die Linux-pingpong-bediener het nie dieselfde vertragings as 'n soortgelyke Windows-gasheer gehad nie, hoewel die databron nie anders was nie. Dit blyk dat die probleem in die gRPC-implementering vir Windows is.
Nagle se algoritme
Al hierdie tyd het ek gedink ek mis 'n vlag gRPC
. Nou verstaan ek wat dit regtig is gRPC
Windows-vlag ontbreek. Ek het 'n interne RPC-biblioteek gevind waarvan ek seker was dat dit goed sou werk vir alle vlae wat gestel is
byna Klaar: Ek het die bygevoegde vlae een op 'n slag begin verwyder totdat die regressie teruggekeer het sodat ek die oorsaak kon identifiseer. Dit was berug
gRPC
hierdie vlag is in die Linux-implementering vir TCP-sockets gestel, maar nie in Windows nie. Ek is hierdie
Gevolgtrekking
Die hoër latensie by lae QPS is veroorsaak deur OS-optimalisering. In retrospek het profilering nie latensie opgespoor nie, want dit is in kernmodus gedoen eerder as in
Wat die localhost-eksperiment betref, het dit waarskynlik nie aan die werklike netwerkkode geraak nie en Nagle se algoritme het nie gehardloop nie, so die vertragingsprobleme het verdwyn toe die kliënt Alvin deur localhost bereik het.
Die volgende keer as jy 'n toename in latensie sien namate die aantal versoeke per sekonde afneem, behoort Nagle se algoritme op jou lys van verdagtes te wees!
Bron: will.com