Soms is mear minder. By it ferminderjen fan lading resultearret yn tanimmende latency

Lykas measte berjochten, der is in probleem mei in ferspraat tsjinst, lit ús neame dizze tsjinst Alvin. Dizze kear haw ik it probleem sels net ûntdutsen, lieten de jonges fan de kliïntekant my witte.

Op in dei waard ik wekker mei in ûntefreden e-post fanwegen lange fertragingen mei Alvin, dy't wy fan plan wiene yn 'e heine takomst te lansearjen. Spesifyk belibbe de kliïnt 99e percentile latency yn 'e regio fan 50 ms, goed boppe ús latencybudzjet. Dit wie ferrassend, om't ik de tsjinst wiidweidich hifke, foaral op latency, wat in mienskiplike klacht is.

Foardat ik Alvin yn testen sette, rûn ik in protte eksperiminten mei 40k queries per sekonde (QPS), allegear toant latency fan minder dan 10ms. Ik wie ree om te ferklearjen dat ik it net iens wie mei har resultaten. Mar doe't ik nochris nei de brief seach, seach ik wat nijs: ik hie de betingsten dy't se neamden net krekt hifke, har QPS wie folle leger as mines. Ik hifke op 40k QPS, mar se allinnich op 1k. Ik rûn in oar eksperimint, dizze kear mei in legere QPS, gewoan om se te ferfelen.

Sûnt ik hjir oer blogge, hawwe jo wierskynlik al útfûn dat har nûmers goed wiene. Ik hifke myn firtuele klant hieltyd wer, mei itselde resultaat: in leech oantal oanfragen fergruttet net allinich de latency, mar fergruttet it oantal oanfragen mei in latency fan mear as 10 ms. Mei oare wurden, as by 40k QPS sa'n 50 oanfragen per sekonde de 50 ms oer wiene, dan wiene d'r by 1k QPS 100 oanfragen boppe 50 ms elke sekonde. Paradoks!

Soms is mear minder. By it ferminderjen fan lading resultearret yn tanimmende latency

It sykjen beheine

Wannear't konfrontearre wurdt mei in latency-probleem yn in ferspraat systeem mei in protte komponinten, is de earste stap om in koarte list fan fertochten te meitsjen. Litte wy in bytsje djipper grave yn Alvin's arsjitektuer:

Soms is mear minder. By it ferminderjen fan lading resultearret yn tanimmende latency

In goed útgongspunt is in list mei foltôge I / O transysjes (netwurk calls / skiif lookups, ensfh). Litte wy besykje út te finen wêr't de fertraging is. Njonken de fanselssprekkende I/O mei de klant, nimt Alvin in ekstra stap: hy komt tagong ta de gegevenswinkel. Dizze opslach wurket lykwols yn itselde kluster as Alvin, sadat de latency dêr minder moat wêze as by de kliïnt. Dus, de list fan fertochten:

  1. Netwurkoprop fan kliïnt nei Alvin.
  2. Netwurkoprop fan Alvin nei de gegevenswinkel.
  3. Sykje op skiif yn 'e gegevenswinkel.
  4. Netwurkoprop fan it datapakhús nei Alvin.
  5. Netwurkoprop fan Alvin nei in kliïnt.

Litte wy besykje guon punten út te lûken.

Data opslach hat neat te krijen mei it

It earste ding dat ik dien wie Alvin te konvertearjen nei in ping-ping-tsjinner dy't gjin fersiken ferwurket. As it in fersyk ûntfangt, jout it in lege antwurd werom. As de latency ôfnimt, dan is in brek yn 'e Alvin- of datawarehouse-ymplemintaasje neat unheard. Yn it earste eksperimint krije wy de folgjende grafyk:

Soms is mear minder. By it ferminderjen fan lading resultearret yn tanimmende latency

Sa't jo sjen kinne, is d'r gjin ferbettering by it brûken fan de ping-ping-tsjinner. Dit betsjut dat it datapakhús de latency net fergruttet, en de list mei fertochten wurdt yn 'e helte ôfsnien:

  1. Netwurkoprop fan kliïnt nei Alvin.
  2. Netwurkoprop fan Alvin nei in kliïnt.

Grut! De list krimp fluch. Ik tocht dat ik de reden hast útfûn hie.

gRPC

No is it tiid om jo foar te stellen oan in nije spiler: gRPC. Dit is in iepen boarne bibleteek fan Google foar kommunikaasje yn it proses CPR... Alhoewol gRPC goed optimalisearre en breed brûkt, dit wie myn earste kear dat ik it brûkte op in systeem fan dizze grutte en ik ferwachte dat myn ymplemintaasje suboptimaal soe wêze - om it minste te sizzen.

beskikberens gRPC yn 'e steapel joech oanlieding ta in nije fraach: miskien is it myn ymplemintaasje of mysels gRPC wêrtroch latency probleem? In nije fertochte tafoegje oan de list:

  1. De klant belle de biblioteek gRPC
  2. Bibleteek gRPC makket in netwurk oprop nei de bibleteek op de klant gRPC op tsjinner
  3. Bibleteek gRPC kontakten Alvin (gjin operaasje yn gefal fan ping-pong-tsjinner)

Om jo in idee te jaan hoe't de koade derút sjocht, is myn ymplemintaasje fan kliïnt / Alvin net folle oars fan 'e kliïnt-tsjinner async foarbylden.

Opmerking: De boppesteande list is in bytsje ferienfâldige omdat gRPC makket it mooglik om jo eigen (sjabloan?) threadingmodel te brûken, wêryn't de útfieringsstapel ferweefd is gRPC en brûker ymplemintaasje. Om 'e ienfâld, sille wy fêsthâlde oan dit model.

Profilearjen sil alles reparearje

Nei't ik de gegevenswinkels trochstutsen hie, tocht ik dat ik hast klear wie: "No is it maklik! Litte wy it profyl tapasse en útfine wêr't de fertraging foarkomt. ik grutte fan fan presys profilearring, om't CPU's tige fluch binne en meastentiids net de knipehals binne. De measte fertragingen komme foar as de prosessor it ferwurkjen moat stopje om wat oars te dwaan. Accurate CPU Profiling docht krekt dat: it registrearret alles krekt kontekst skeakelt en makket dúdlik wêr't fertragingen foarkomme.

Ik naam fjouwer profilen: mei hege QPS (lege latency) en mei in ping-pong-tsjinner mei lege QPS (hege latency), sawol oan 'e kliïntkant as oan' e serverkant. En foar it gefal, ik naam ek in sample prosessor profyl. By it fergelykjen fan profilen sykje ik meastentiids nei in anomale opropstapel. Bygelyks, oan 'e minne kant mei hege latency binne d'r folle mear kontekstskeakels (10 kear of mear). Mar yn myn gefal wie it oantal kontekstskeakels hast itselde. Ta myn skrik wie der neat wichtichs.

Oanfoljende debuggen

Ik wie wanhopich. Ik wist net hokker oare ark ik koe brûke, en myn folgjende plan wie yn essinsje om de eksperiminten te werheljen mei ferskate fariaasjes ynstee fan it probleem dúdlik te diagnostearjen.

Wat as

Fan it begjin ôf wie ik soargen oer de spesifike 50ms latency. Dit is in heul grutte tiid. Ik besleat dat ik brokken út 'e koade soe snije oant ik krekt koe útfine hokker diel dizze flater feroarsake. Doe kaam in eksperimint dat wurke.

As gewoanlik liket it derop dat alles dúdlik wie. Ik pleatste de klant op deselde masine as Alvin - en stjoerde in fersyk oan localhost. En de ferheging fan latency is fuort!

Soms is mear minder. By it ferminderjen fan lading resultearret yn tanimmende latency

Der wie wat mis mei it netwurk.

Learje netwurkingenieursfeardigens

Ik moat tajaan: myn kennis fan netwurktechnologyen is ferskriklik, foaral sjoen it feit dat ik elke dei mei har wurkje. Mar it netwurk wie de haadfertochte, en ik moast leare hoe't ik it debugge koe.

Gelokkich hâldt it ynternet fan dyjingen dy't wolle leare. De kombinaasje fan ping en tracert like in goed genôch begjin foar it debuggen fan netwurkferfierproblemen.

Earst, ik lansearre PsPing nei Alvin syn TCP haven. Ik brûkte de standertynstellingen - neat spesjaal. Fan mear as tûzen pings, gjinien boppe 10 ms, mei útsûndering fan de earste foar opwaarming. Dit is yn striid mei de waarnommen ferheging fan latency fan 50 ms by it 99e percentile: dêr soene wy ​​foar elke 100 oanfragen sa'n ien fersyk mei in latency fan 50 ms moatte sjoen hawwe.

Doe besocht ik tracer: Der kin in probleem wêze op ien fan 'e knopen lâns de rûte tusken Alvin en de kliïnt. Mar de tracer kaam ek mei lege hannen werom.

Dat it wie net myn koade, de gRPC-ymplemintaasje, of it netwurk dat de fertraging feroarsake. Ik begon te soargen dat ik dit noait soe begripe.

No hokker OS binne wy ​​op

gRPC in soad brûkt op Linux, mar eksoatysk op Windows. Ik besleat in eksperimint te besykjen, dat wurke: ik makke in Linux firtuele masine, kompilearre Alvin foar Linux, en ynset it.

Soms is mear minder. By it ferminderjen fan lading resultearret yn tanimmende latency

En hjir is wat barde: de Linux ping-pong-tsjinner hie net deselde fertragingen as in ferlykbere Windows-host, hoewol de gegevensboarne net oars wie. It docht bliken dat it probleem is yn 'e gRPC-ymplemintaasje foar Windows.

Nagle's algoritme

Al dy tiid tocht ik dat ik in flagge miste gRPC. No begryp ik wat it echt is gRPC Windows flagge ûntbrekt. Ik fûn in ynterne RPC bibleteek dat ik wie wis soe wurkje goed foar alle flaggen set Winsock. Doe haw ik al dizze flaggen tafoege oan gRPC en Alvin ynset op Windows, yn in patched Windows ping-pong-tsjinner!

Soms is mear minder. By it ferminderjen fan lading resultearret yn tanimmende latency

Almost Dien: ik begon de tafoege flaggen ien foar ien te ferwiderjen oant de regression weromkaam, sadat ik de oarsaak koe identifisearje. It wie berucht TCP_NODELAY, Nagle syn algoritme switch.

Nagle's algoritme besiket it oantal pakketten te ferleegjen dat oer in netwurk ferstjoerd wurdt troch de oerdracht fan berjochten te fertrage oant de pakketgrutte in bepaald oantal bytes grutter is. Hoewol dit moai wêze kin foar de gemiddelde brûker, is it destruktyf foar real-time tsjinners, om't it OS guon berjochten fertrage sil, wêrtroch't fertragingen op lege QPS feroarsaakje. U gRPC dizze flagge waard ynsteld yn de Linux ymplemintaasje foar TCP sockets, mar net yn Windows. Ik bin dit korrizjearre.

konklúzje

De hegere latency by lege QPS waard feroarsake troch OS-optimalisaasje. Yn retrospektyf ûntdekte profilearring gjin latency, om't it waard dien yn kernelmodus ynstee fan yn brûker modus. Ik wit net oft Nagle syn algoritme kin wurde waarnommen fia ETW captures, mar it soe wêze nijsgjirrich.

Wat it localhost-eksperimint oanbelanget, hat it wierskynlik de eigentlike netwurkkoade net oanrekke en Nagle's algoritme rûn net, sadat de latencyproblemen ferdwûn doe't de klant Alvin berikte fia localhost.

De folgjende kear as jo in ferheging fan latency sjogge as it oantal oanfragen per sekonde ôfnimt, soe Nagle's algoritme op jo list mei fertochten moatte stean!

Boarne: www.habr.com

Add a comment