Stejně jako v
Jednoho dne mě probudil nespokojený email kvůli dlouhým prodlevám s Alvinem, který jsme plánovali spustit v blízké budoucnosti. Konkrétně klient zaznamenal latenci 99. percentilu v oblasti 50 ms, což je výrazně nad naším rozpočtem na latenci. To bylo překvapivé, protože jsem službu rozsáhle testoval, zejména na latenci, což je běžná stížnost.
Než jsem dal Alvina do testování, provedl jsem spoustu experimentů se 40 10 dotazy za sekundu (QPS), přičemž všechny vykazovaly latenci menší než 40 ms. Byl jsem připraven prohlásit, že s jejich výsledky nesouhlasím. Ale při dalším pohledu na dopis jsem si všiml něčeho nového: podmínky, které zmiňovali, jsem přesně netestoval, jejich QPS byla mnohem nižší než moje. Testoval jsem na 1k QPS, ale oni jen na XNUMXk. Provedl jsem další experiment, tentokrát s nižším QPS, jen abych je uklidnil.
Vzhledem k tomu, že o tom píšu blog, pravděpodobně jste již přišli na to, že jejich čísla byla správná. Svého virtuálního klienta jsem testoval znovu a znovu, se stejným výsledkem: nízký počet požadavků nejen zvyšuje latenci, ale zvyšuje počet požadavků s latencí více než 10 ms. Jinými slovy, pokud při 40k QPS asi 50 požadavků za sekundu přesáhlo 50 ms, pak při 1k QPS bylo každou sekundu 100 požadavků nad 50 ms. Paradox!
Zúžení vyhledávání
Když čelíte problému s latencí v distribuovaném systému s mnoha komponentami, prvním krokem je vytvořit krátký seznam podezřelých. Pojďme se ponořit trochu hlouběji do Alvinovy architektury:
Dobrým výchozím bodem je seznam dokončených I/O přechodů (síťová volání/vyhledávání disku atd.). Zkusme zjistit, kde je zpoždění. Kromě samozřejmého I/O s klientem podnikne Alvin další krok: přistoupí k datovému úložišti. Toto úložiště však funguje ve stejném clusteru jako Alvin, takže latence by tam měla být menší než u klienta. Takže seznam podezřelých:
- Síťový hovor od klienta k Alvinovi.
- Síťové volání od Alvina do úložiště dat.
- Vyhledejte na disku v úložišti dat.
- Síťové volání z datového skladu do Alvina.
- Síťový hovor od Alvina ke klientovi.
Zkusme si odškrtnout některé body.
Ukládání dat s tím nemá nic společného
První věc, kterou jsem udělal, bylo převést Alvina na ping-ping server, který nezpracovává požadavky. Když obdrží požadavek, vrátí prázdnou odpověď. Pokud se latence sníží, pak chyba v implementaci Alvin nebo datového skladu není nic neslýchaného. V prvním experimentu dostaneme následující graf:
Jak vidíte, při používání ping-ping serveru nedochází k žádnému zlepšení. To znamená, že datový sklad nezvyšuje latenci a seznam podezřelých se zkrátí na polovinu:
- Síťový hovor od klienta k Alvinovi.
- Síťový hovor od Alvina ke klientovi.
Skvělý! Seznam se rychle zmenšuje. Myslel jsem, že jsem skoro přišel na důvod.
gRPC
Nyní je čas představit vám nového hráče: gRPC
dobře optimalizovaný a široce používaný, bylo to poprvé, co jsem jej použil na systému této velikosti, a očekával jsem, že moje implementace bude přinejmenším suboptimální.
dostupnost gRPC
v zásobníku vyvolala novou otázku: možná je to moje implementace nebo já gRPC
způsobuje problém s latencí? Přidání nového podezřelého na seznam:
- Klient zavolá do knihovny
gRPC
- knihovna
gRPC
provede síťové volání do knihovny na klientovigRPC
na serveru - knihovna
gRPC
kontaktuje Alvina (žádná operace v případě ping-pong serveru)
Abyste měli představu o tom, jak kód vypadá, moje implementace klient/Alvin se příliš neliší od implementace klient-server
Poznámka: Výše uvedený seznam je trochu zjednodušený, protože
gRPC
umožňuje použít vlastní (šablonový?) model vláken, ve kterém je propleten zásobník prováděnígRPC
a uživatelská implementace. Pro jednoduchost se budeme držet tohoto modelu.
Profilování vše napraví
Po přeškrtnutí datových úložišť jsem si myslel, že jsem téměř hotový: „Teď je to snadné! Aplikujme profil a zjistíme, kde dochází ke zpoždění.“ já
Vzal jsem čtyři profily: s vysokým QPS (nízká latence) a s ping-pongovým serverem s nízkou QPS (vysoká latence), a to jak na straně klienta, tak na straně serveru. A pro každý případ jsem vzal i ukázkový profil procesoru. Při porovnávání profilů obvykle hledám anomální zásobník hovorů. Například na špatné straně s vysokou latencí existuje mnohem více kontextových přepínačů (10krát nebo více). Ale v mém případě byl počet kontextových přepínačů téměř stejný. K mému zděšení tam nebylo nic významného.
Další ladění
Byl jsem zoufalý. Nevěděl jsem, jaké další nástroje bych mohl použít, a mým dalším plánem bylo v podstatě opakovat experimenty s různými variantami, spíše než jasně diagnostikovat problém.
Co když
Od samého začátku jsem měl obavy z konkrétní 50ms latence. Tohle je hodně velká doba. Rozhodl jsem se, že z kódu vyřežu kousky, dokud přesně nezjistím, která část tuto chybu způsobuje. Pak přišel experiment, který fungoval.
Jako obvykle, při zpětném pohledu se zdá, že vše bylo zřejmé. Umístil jsem klienta na stejný stroj jako Alvin - a poslal jsem mu požadavek localhost
. A nárůst latence je pryč!
Něco bylo špatně se sítí.
Naučte se dovednosti síťového inženýra
Musím přiznat: moje znalosti síťových technologií jsou hrozné, zvláště když s nimi pracuji každý den. Ale síť byla hlavním podezřelým a potřeboval jsem se naučit, jak ji odladit.
Naštěstí internet miluje ty, kteří se chtějí učit. Kombinace pingu a tracert se zdála jako dostatečně dobrý začátek k ladění problémů s přenosem v síti.
Nejprve jsem spustil
Pak jsem to zkusil
Takže to nebyl můj kód, implementace gRPC nebo síť, která způsobila zpoždění. Začínal jsem se bát, že tohle nikdy nepochopím.
A teď na jakém OS jsme
gRPC
široce používaný na Linuxu, ale exotický na Windows. Rozhodl jsem se vyzkoušet experiment, který fungoval: vytvořil jsem virtuální stroj Linux, zkompiloval Alvin pro Linux a nasadil jej.
A stalo se toto: Linuxový ping-pongový server neměl stejné zpoždění jako podobný hostitel Windows, ačkoli zdroj dat se nelišil. Ukazuje se, že problém je v implementaci gRPC pro Windows.
Nagleho algoritmus
Celou tu dobu jsem si myslel, že mi chybí vlajka gRPC
. Teď už chápu, co to vlastně je gRPC
Chybí vlajka Windows. Našel jsem interní knihovnu RPC, o které jsem si byl jistý, že bude dobře fungovat pro všechny nastavené příznaky
Téměř Hotovo: Začal jsem odstraňovat přidané příznaky jeden po druhém, dokud se regrese nevrátila, abych mohl určit příčinu. Bylo to neslavné
gRPC
tento příznak byl nastaven v implementaci Linuxu pro TCP sockety, ale ne ve Windows. já jsem tohle
Závěr
Vyšší latence při nízké QPS byla způsobena optimalizací OS. Při zpětném pohledu profilování nezjistilo latenci, protože bylo provedeno v režimu jádra, nikoli v režimu
Pokud jde o experiment localhost, pravděpodobně se nedotkl skutečného síťového kódu a algoritmus Nagle neběžel, takže problémy s latencí zmizely, když klient dosáhl Alvina přes localhost.
Až příště uvidíte nárůst latence, protože počet požadavků za sekundu klesá, měl by být Nagleův algoritmus na vašem seznamu podezřelých!
Zdroj: www.habr.com