Кейде көп нәрсе аз. Жүктемені азайту кідірістің артуына әкеледі

Сонымен қатар көптеген хабарламалар, таратылған қызметте ақау бар, бұл қызметті Alvin деп атаймыз. Бұл жолы мен мәселені өзім таппадым, маған клиенттің жігіттері хабарлады.

Бір күні мен Элвинмен ұзақ кешігуге байланысты наразы электрондық поштаны естідім, біз оны жақын арада іске қосуды жоспарлап отырмыз. Атап айтқанда, клиент 99 мс аймағындағы 50-шы пайыздық кідірісті бастан кешірді, бұл біздің кідіріс бюджетінен әлдеқайда жоғары. Бұл таңқаларлық болды, өйткені мен қызметті кеңінен сынадым, әсіресе жалпы шағым болып табылатын кідіріс кезінде.

Мен Элвинді тестілеуге жібермес бұрын, мен секундына 40 мың сұрау (QPS) бар көптеген эксперименттер жүргіздім, олардың барлығы 10 мс-ден аз кідірісті көрсетті. Мен олардың нәтижелерімен келіспейтінімді мәлімдеуге дайын болдым. Бірақ хатқа тағы бір рет қарап отырып, мен жаңа нәрсені байқадым: мен олар айтқан шарттарды дәл тексерген жоқпын, олардың QPS деңгейі менікіден әлдеқайда төмен. Мен 40k QPS-те сынадым, бірақ олар тек 1к-де. Мен оларды тыныштандыру үшін бұл жолы төмен QPS-пен тағы бір эксперимент жүргіздім.

Мен бұл туралы блог жазып жатқандықтан, сіз олардың санының дұрыс екенін түсінген шығарсыз. Мен виртуалды клиентімді қайта-қайта сынап көрдім, нәтиже бірдей болды: сұраулардың аз саны кідіріс уақытын арттырып қана қоймай, 10 мс асатын кідіріспен сұраулар санын көбейтеді. Басқаша айтқанда, егер 40k QPS кезінде секундына шамамен 50 сұрау 50 мс-тен асса, 1k QPS-те секунд сайын 100 мс-тен жоғары 50 сұрау болды. Парадокс!

Кейде көп нәрсе аз. Жүктемені азайту кідірістің артуына әкеледі

Іздеуді қысқарту

Көптеген құрамдас бөліктері бар үлестірілген жүйеде кідіріс мәселесіне тап болған кезде, бірінші қадам күдіктілердің қысқаша тізімін жасау болып табылады. Элвиннің архитектурасына тереңірек үңілейік:

Кейде көп нәрсе аз. Жүктемені азайту кідірістің артуына әкеледі

Жақсы бастау нүктесі - аяқталған енгізу/шығару ауысуларының тізімі (желілік қоңыраулар/диск іздеулері және т.б.). Кешігу қай жерде екенін анықтауға тырысайық. Клиентпен айқын енгізу/шығарудан басқа, Элвин қосымша қадам жасайды: ол деректер қоймасына кіреді. Дегенмен, бұл сақтау орны Элвин сияқты кластерде жұмыс істейді, сондықтан кідіріс клиентпен салыстырғанда аз болуы керек. Сонымен, күдіктілердің тізімі:

  1. Клиенттен Элвинге желілік қоңырау.
  2. Элвиннен деректер қоймасына желілік қоңырау.
  3. Деректер қоймасында дискіден іздеңіз.
  4. Деректер қоймасынан Элвинге желілік қоңырау.
  5. Элвиннен клиентке желілік қоңырау.

Кейбір нүктелерді сызып тастауға тырысайық.

Деректерді сақтаудың оған ешқандай қатысы жоқ

Мен жасаған бірінші нәрсе - Элвинді сұрауларды өңдемейтін пинг-пинг серверіне түрлендіру болды. Сұрауды алған кезде ол бос жауапты қайтарады. Егер кідіріс азайса, Alvin немесе деректер қоймасын іске асырудағы қате естімеген нәрсе емес. Бірінші тәжірибеде келесі графикті аламыз:

Кейде көп нәрсе аз. Жүктемені азайту кідірістің артуына әкеледі

Көріп отырғаныңыздай, пинг-пинг серверін пайдалану кезінде ешқандай жақсартулар жоқ. Бұл деректер қоймасы кідірістерді арттырмайды және күдіктілер тізімі екі есе қысқарды дегенді білдіреді:

  1. Клиенттен Элвинге желілік қоңырау.
  2. Элвиннен клиентке желілік қоңырау.

Тамаша! Тізім тез қысқарады. Мен себебін дерлік анықтадым деп ойладым.

gRPC

Енді сізді жаңа ойыншымен таныстыратын кез келді: gRPC. Бұл процесс барысындағы байланысқа арналған Google ұсынған ашық бастапқы кітапхана RPC. Дегенмен gRPC жақсы оңтайландырылған және кеңінен қолданылған, бұл менің оны осындай өлшемдегі жүйеде бірінші рет пайдалануым болды және менің іске асыруым оңтайлы емес деп күттім - кем дегенде.

болуы gRPC стекте жаңа сұрақ туындады: мүмкін бұл менің іске асыруым немесе өзім gRPC кідіріс мәселесін тудырады ма? Тізімге жаңа күдікті қосу:

  1. Клиент кітапханаға қоңырау шалады gRPC
  2. Кітапхана gRPC клиенттегі кітапханаға желілік қоңырауды жасайды gRPC серверде
  3. Кітапхана gRPC контактілер Элвин (пинг-понг серверінде жұмыс істемейді)

Сізге кодтың қалай көрінетіні туралы түсінік беру үшін, менің клиентім/Элвинді іске асыру клиент-серверден айтарлықтай ерекшеленбейді. асинхронды мысалдар.

Ескертпе: Жоғарыдағы тізім біршама жеңілдетілген, себебі gRPC орындалу стегі бір-бірімен тоғысқан жеке (үлгі?) ағынды үлгіні пайдалануға мүмкіндік береді. gRPC және пайдаланушыны жүзеге асыру. Қарапайымдылық үшін біз осы үлгіні ұстанамыз.

Профильдеу бәрін түзетеді

Деректер қоймаларын сызып тастағаннан кейін, мен дайын болдым деп ойладым: «Енді оңай! Профильді қолданып, кешігудің қай жерде болатынын білейік. I дәл профильдеудің үлкен жанкүйері, өйткені процессорлар өте жылдам және көбінесе кедергі болмайды. Көптеген кешігулер процессор басқа бірдеңе жасау үшін өңдеуді тоқтату керек болғанда орын алады. Дәл CPU профилін жасау дәл осылай жасайды: ол бәрін дәл жазады контекстік ауыстырғыштар және кешігулердің қай жерде болатынын түсіндіреді.

Мен төрт профильді алдым: жоғары QPS (төмен кідіріс) және төмен QPS (жоғары кідіріс) бар пинг-понг серверімен, клиент жағында да, сервер жағында да. Сондай-ақ, мен процессор профилінің үлгісін алдым. Профильдерді салыстыру кезінде мен әдетте аномальды қоңыраулар стегін іздеймін. Мысалы, жоғары кідірістің нашар жағында көптеген контекстік қосқыштар бар (10 есе немесе одан да көп). Бірақ менің жағдайда контекстік қосқыштардың саны дерлік бірдей болды. Менің қорқыныштысы, онда маңызды ештеңе болмады.

Қосымша жөндеу

Мен шарасыз болдым. Мен басқа қандай құралдарды қолдана алатынымды білмедім және менің келесі жоспарым мәселені нақты диагностикалаудың орнына әртүрлі вариациялармен эксперименттерді қайталау болды.

Болса не

Ең басынан бастап мені 50 мс кідіріс туралы алаңдатты. Бұл өте үлкен уақыт. Мен осы қатені тудырған бөліктің нақты қай бөлігін анықтағанша кодты кесіп тастаймын деп шештім. Содан кейін тәжірибе пайда болды.

Кәдімгідей, артқа қарасақ, бәрі анық болған сияқты. Мен клиентті Элвин сияқты құрылғыға орналастырдым және оған сұрау жібердім localhost. Ал кідірістің артуы жоғалды!

Кейде көп нәрсе аз. Жүктемені азайту кідірістің артуына әкеледі

Желіде бірдеңе дұрыс болмады.

Желілік инженер дағдыларын үйрену

Мойындауым керек: желілік технологиялар туралы білімім қорқынышты, әсіресе олармен күнделікті жұмыс істейтінімді ескерсек. Бірақ желі басты күдікті болды, мен оны жөндеуді үйренуім керек болды.

Бақытымызға орай, Интернет білім алғысы келетіндерді жақсы көреді. Ping және tracert тіркесімі желілік тасымалдау мәселелерін түзету үшін жеткілікті жақсы бастама сияқты көрінді.

Біріншіден, мен іске қостым PsPing Элвиннің TCP портына. Мен әдепкі параметрлерді қолдандым - ерекше ештеңе жоқ. Мыңнан астам пингтердің ешқайсысы қыздыруға арналған біріншіден басқасы 10 мс аспады. Бұл 50-процентильде байқалған кідірістің 99 мс артуына қайшы келеді: онда әрбір 100 сұрау үшін біз 50 мс кешігумен бір сұрауды көруіміз керек еді.

Сосын мен тырыстым тракерт: Элвин мен клиент арасындағы жол бойындағы түйіндердің бірінде ақаулық болуы мүмкін. Бірақ ізбасар да құр алақан оралды.

Сондықтан кешігуді тудырған менің кодым, gRPC енгізуі немесе желі емес. Мен мұны ешқашан түсінбеймін деп уайымдай бастадым.

Енді біз қандай операциялық жүйені қолданамыз

gRPC Linux жүйесінде кеңінен қолданылады, бірақ Windows жүйесінде экзотикалық. Мен эксперимент жасап көруді шештім, ол жұмыс істеді: мен Linux виртуалды машинасын жасадым, Linux үшін Alvin құрастырдым және оны орналастырдым.

Кейде көп нәрсе аз. Жүктемені азайту кідірістің артуына әкеледі

Міне, болды: Linux пинг-понг серверінде деректер көзі басқаша болмаса да, ұқсас Windows хостымен бірдей кешігулер болмады. Мәселе Windows жүйесіне арналған gRPC іске асыруда екені белгілі болды.

Нагль алгоритмі

Осы уақыт бойы мен бір туды жоғалтып алдым деп ойладым gRPC. Енді мен оның шын мәнінде не екенін түсіндім gRPC Windows жалаушасы жоқ. Мен барлық жалаушалар жиынтығы үшін жақсы жұмыс істейтініне сенімді болатын ішкі RPC кітапханасын таптым Winsock. Содан кейін мен осы жалаулардың барлығын gRPC-ке қосып, Alvin-ді Windows жүйесінде, Windows пинг-понг серверінде патчталған Windows жүйесіне орналастырдым!

Кейде көп нәрсе аз. Жүктемені азайту кідірістің артуына әкеледі

Дерлік Дайын: себебін анықтау үшін регрессия қайтарылғанша қосылған жалаушаларды бір-бірден алып тастай бастадым. Бұл атақты болды TCP_NODELAY, Нагль алгоритмінің қосқышы.

Нагль алгоритмі пакет өлшемі белгілі бір байт санынан асқанша хабарламаларды жіберуді кешіктіру арқылы желі арқылы жіберілетін пакеттер санын азайтуға тырысады. Бұл қарапайым пайдаланушы үшін жақсы болуы мүмкін, бірақ бұл нақты уақыттағы серверлер үшін жойқын, өйткені ОЖ кейбір хабарламаларды кешіктіріп, төмен QPS-те кешігуді тудырады. У gRPC бұл жалау TCP ұяшықтары үшін Linux іске асыруында орнатылды, бірақ Windows жүйесінде емес. Мен мынамын түзетілді.

қорытынды

Төмен QPS кезінде жоғары кідіріс операциялық жүйені оңтайландыруға байланысты болды. Ретроспективада профильдеу кешіктіруді анықтаған жоқ, себебі ол ядро ​​режимінде емес, ядро ​​​​режимінде орындалды пайдаланушы режимі. Мен Nagle алгоритмін ETW түсіру арқылы байқауға болатынын білмеймін, бірақ бұл қызықты болар еді.

Localhost тәжірибесіне келетін болсақ, ол нақты желілік кодқа қол тигізбеуі мүмкін және Nagle алгоритмі жұмыс істемеді, сондықтан клиент localhost арқылы Элвинге жеткенде кідіріс мәселелері жойылды.

Келесі жолы секундына сұраулар саны азайған сайын кідірістің артқанын көргенде, Нагле алгоритмі күдіктілер тізімінде болуы керек!

Ақпарат көзі: www.habr.com

пікір қалдыру