Као у
Једног дана сам се пробудио са незадовољним мејлом због дугих кашњења са Алвином, који смо планирали да покренемо у блиској будућности. Конкретно, клијент је искусио кашњење од 99. перцентила у региону од 50 мс, што је знатно изнад нашег буџета за кашњење. Ово је било изненађујуће јер сам опсежно тестирао услугу, посебно на кашњењу, што је уобичајена жалба.
Пре него што сам ставио Алвина на тестирање, спровео сам много експеримената са 40 хиљада упита у секунди (КПС), а сви су показали кашњење мање од 10 мс. Био сам спреман да изјавим да се не слажем са њиховим резултатима. Али погледавши још једном писмо, приметио сам нешто ново: нисам баш тестирао услове које су они поменули, њихов КПС је био много нижи од мог. Тестирао сам на 40к КПС, али они само на 1к. Извео сам још један експеримент, овог пута са нижим КПС-ом, само да их умирим.
Пошто пишем о овоме на блогу, вероватно сте већ схватили да су њихови бројеви тачни. Тестирао сам свог виртуелног клијента изнова и изнова са истим резултатом: мали број захтева не само да повећава кашњење, већ и повећава број захтева са кашњењем већим од 10 мс. Другим речима, ако је при 40к КПС било око 50 захтева у секунди изнад 50мс, онда је при 1к КПС било 100 захтева изнад 50мс сваке секунде. Парадокс!
Сужавање претраге
Када се суочите са проблемом кашњења у дистрибуираном систему са много компоненти, први корак је креирање кратке листе осумњичених. Хајде да копамо мало дубље у Алвинову архитектуру:
Добра полазна тачка је листа извршених И/О прелаза (мрежни позиви/претраживања диска, итд.). Хајде да покушамо да схватимо где је кашњење. Поред очигледног И/О са клијентом, Алвин предузима додатни корак: приступа складишту података. Међутим, ово складиште ради у истом кластеру као и Алвин, тако да би кашњење требало да буде мање него код клијента. Дакле, листа осумњичених:
- Мрежни позив од клијента до Алвина.
- Мрежни позив од Алвина ка складишту података.
- Претражите диск у складишту података.
- Мрежни позив из складишта података Алвину.
- Мрежни позив од Алвина клијенту.
Покушајмо да прецртамо неке тачке.
Чување података нема никакве везе са тим
Прво што сам урадио је да претворим Алвина у пинг-пинг сервер који не обрађује захтеве. Када прими захтев, враћа празан одговор. Ако се кашњење смањи, онда грешка у имплементацији Алвина или складишта података није ништа нечувено. У првом експерименту добијамо следећи графикон:
Као што видите, нема побољшања када користите пинг-пинг сервер. То значи да складиште података не повећава кашњење, а листа осумњичених је преполовљена:
- Мрежни позив од клијента до Алвина.
- Мрежни позив од Алвина клијенту.
Велики! Листа се брзо смањује. Мислио сам да сам скоро схватио разлог.
гРПЦ
Сада је време да вас упознамо са новим играчем: gRPC
добро оптимизован и широко коришћен, ово је био мој први пут да га користим на систему ове величине и очекивао сам да моја имплементација буде подоптимална - у најмању руку.
доступност gRPC
у стеку је довео до новог питања: можда је то моја имплементација или ја gRPC
узрокује проблем кашњења? Додавање новог осумњиченог на листу:
- Клијент позива библиотеку
gRPC
- библиотека
gRPC
упућује мрежни позив библиотеци на клијентуgRPC
на серверу - библиотека
gRPC
контактира Алвина (нема операције у случају пинг-понг сервера)
Да бих вам дао представу о томе како изгледа код, моја имплементација клијент/Алвин се не разликује много од клијент-сервер
Напомена: Горња листа је мало поједностављена јер
gRPC
омогућава коришћење сопственог (шаблона?) нитног модела, у којем је стек извршења испреплетенgRPC
и имплементација корисника. Ради једноставности, задржаћемо се овог модела.
Профилисање ће све поправити
Пошто сам прецртао складишта података, мислио сам да сам скоро завршио: „Сада је лако! Хајде да применимо профил и сазнамо где долази до кашњења." И
Узео сам четири профила: са високим КПС-ом (мало кашњење) и са пинг-понг сервером са ниским КПС-ом (висока латенција), и на страни клијента и на страни сервера. И за сваки случај, узео сам и узорак профила процесора. Када упоређујем профиле, обично тражим аномалан стек позива. На пример, са лоше стране са великим кашњењем, постоји много више промена контекста (10 пута или више). Али у мом случају, број промена контекста је био скоро исти. На мој ужас, ту није било ништа значајно.
Додатно отклањање грешака
Био сам у очају. Нисам знао које друге алате могу да користим, а мој следећи план је у суштини био да поновим експерименте са различитим варијацијама уместо да јасно дијагностикујем проблем.
Шта ако
Био сам забринут због специфичног кашњења од 50 мс од почетка. Ово је веома велико време. Одлучио сам да исечем делове кода док не откријем тачно који део изазива ову грешку. Затим је дошао експеримент који је успео.
Као и обично, гледајући уназад, чини се да је све било очигледно. Поставио сам клијента на исту машину као и Алвин - и послао захтев localhost
. И повећање латенције је нестало!
Нешто није у реду са мрежом.
Учење вештина мрежног инжењера
Морам признати: моје познавање мрежних технологија је ужасно, поготово ако се узме у обзир да свакодневно радим са њима. Али мрежа је била главни осумњичени и морао сам да научим како да је отклоним.
Срећом, интернет воли оне који желе да уче. Комбинација пинга и трацерта је изгледала као довољно добар почетак за отклањање грешака у мрежном транспорту.
Прво сам лансирао
Онда сам покушао
Дакле, кашњење није био мој код, имплементација гРПЦ-а или мрежа. Почео сам да бринем да ово никада нећу разумети.
Сада на ком ОС-у смо
gRPC
широко се користи на Линук-у, али егзотично на Виндовс-у. Одлучио сам да испробам експеримент, који је успео: направио сам Линук виртуелну машину, компајлирао Алвина за Линук и применио је.
И ево шта се догодило: Линук пинг-понг сервер није имао иста кашњења као сличан Виндовс хост, иако се извор података није разликовао. Испоставило се да је проблем у имплементацији гРПЦ-а за Виндовс.
Наглеов алгоритам
Све ово време сам мислио да ми недостаје застава gRPC
. Сада разумем шта је то заиста gRPC
Виндовс заставица недостаје. Нашао сам интерну РПЦ библиотеку за коју сам био уверен да ће добро функционисати за све постављене заставице
Скоро Готово: Почео сам да уклањам додане заставице једну по једну док се регресија не врати како бих могао тачно да одредим узрок. Било је неславно
gRPC
ова заставица је постављена у Линук имплементацији за ТЦП утичнице, али не и у Виндовс-у. Ја сам ово
Закључак
Веће кашњење при ниском КПС-у је узроковано оптимизацијом ОС-а. Ретроспективно, профилисање није открило кашњење јер је урађено у режиму кернела, а не у
Што се тиче експеримента са локалним хостом, он вероватно није дотакао стварни мрежни код и Наглеов алгоритам се није покренуо, тако да су проблеми са кашњењем нестали када је клијент дошао до Алвина преко локалног хоста.
Следећи пут када видите повећање латенције како се број захтева у секунди смањује, Наглеов алгоритам би требало да буде на вашој листи осумњичених!
Извор: ввв.хабр.цом