Yandex.Cloud жүйесіндегі желілік жүктемені теңестіру құралының архитектурасы

Yandex.Cloud жүйесіндегі желілік жүктемені теңестіру құралының архитектурасы
Сәлеметсіз бе, мен Сергей Еланцевпін, мен дамытамын желі жүктемесін теңестіруші Yandex.Cloud ішінде. Бұрын мен Яндекс порталы үшін L7 балансизаторын әзірлеуге жетекшілік еттім - әріптестер мен не істесем де, ол теңгерімші болып шығады деп әзілдейді. Мен Habr оқырмандарына бұлттық платформадағы жүктемені қалай басқаруға болатынын, осы мақсатқа жетудің тамаша құралы ретінде не көретінімізді және осы құралды құруға қалай қарай жүріп жатқанымызды айтып беремін.

Алдымен, кейбір терминдерді енгізейік:

  • VIP (Virtual IP) - баланстық IP мекенжайы
  • Сервер, сервер, данасы – қолданбаны іске қосатын виртуалды машина
  • RIP (Real IP) – сервердің IP мекенжайы
  • Healthcheck - сервердің дайындығын тексеру
  • Availability Zone, AZ – деректер орталығындағы оқшауланған инфрақұрылым
  • Аймақ – әртүрлі АЗ-ның бірлестігі

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

Жүктеме теңестіруші жиі ол жұмыс істейтін OSI үлгісінің протокол деңгейі бойынша жіктеледі. Cloud Balancer төртінші L4 деңгейіне сәйкес келетін TCP деңгейінде жұмыс істейді.

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

Деректер жазықтығы

Трафик шекаралық маршрутизаторлар деп аталатын қымбат құрылғыларда аяқталады. Ақауларға төзімділікті арттыру үшін бірнеше осындай құрылғылар бір деректер орталығында бір уақытта жұмыс істейді. Әрі қарай, трафик клиенттерге арналған BGP арқылы барлық AZ-ға кез келген тарату IP мекенжайларын жариялайтын балансизаторларға түседі. 

Yandex.Cloud жүйесіндегі желілік жүктемені теңестіру құралының архитектурасы

Трафик ECMP арқылы беріледі - бұл бағыттау стратегиясы, оған сәйкес мақсатқа бірнеше бірдей жақсы маршруттар болуы мүмкін (біздің жағдайда мақсат тағайындалған IP мекенжайы болады) және пакеттерді олардың кез келгені бойынша жіберуге болады. Біз сондай-ақ келесі схемаға сәйкес бірнеше қолжетімді аймақтардағы жұмысты қолдаймыз: біз әр аймақта мекенжайды жарнамалаймыз, трафик ең жақынға барады және оның шегінен шықпайды. Кейінірек постта біз трафикпен не болатынын толығырақ қарастырамыз.

Конфигурациялау жазықтығы

 
Конфигурациялау жазықтығының негізгі құрамдас бөлігі API болып табылады, ол арқылы балансизаторлармен негізгі операциялар орындалады: даналардың құрамын жасау, жою, өзгерту, денсаулықты тексеру нәтижелерін алу және т.б.. Бұл бір жағынан REST API, ал басқа, біз бұлтта жиі gRPC жақтауын қолданамыз, сондықтан REST-ті gRPC-ге «аударамыз», содан кейін тек gRPC-ті пайдаланамыз. Кез келген сұрау Yandex.Cloud жұмысшыларының ортақ пулында орындалатын асинхронды идемпотентті тапсырмалар қатарын жасауға әкеледі. Тапсырмалар кез келген уақытта тоқтатылып, қайта іске қосылатындай етіп жазылған. Бұл масштабтауды, қайталануды және операцияларды тіркеуді қамтамасыз етеді.

Yandex.Cloud жүйесіндегі желілік жүктемені теңестіру құралының архитектурасы

Нәтижесінде API тапсырмасы Go бағдарламасында жазылған баланстауыш қызметінің контроллеріне сұрау жасайды. Ол балансизаторларды қосып, жоя алады, серверлер мен параметрлердің құрамын өзгерте алады. 

Yandex.Cloud жүйесіндегі желілік жүктемені теңестіру құралының архитектурасы

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

Баланс контроллеріне оралайық. Оның міндеті - балансизатор туралы ақпаратты сақтау және денсаулықты тексеру контроллеріне виртуалды машинаның дайындығын тексеру тапсырмасын жіберу.

Денсаулықты тексеру контроллері

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

Yandex.Cloud жүйесіндегі желілік жүктемені теңестіру құралының архитектурасы

Денсаулықты тексеру туралы көбірек сөйлесейік. Оларды бірнеше сыныпқа бөлуге болады. Аудиттердің әртүрлі табыс критерийлері бар. TCP тексерулері белгіленген уақыт ішінде қосылымды сәтті орнатуы керек. HTTP тексерулері сәтті қосылымды және 200 күй коды бар жауапты талап етеді.

Сондай-ақ, тексерулер әрекет класы бойынша ерекшеленеді - олар белсенді және пассивті. Пассивті тексерулер ешқандай арнайы әрекет жасамай-ақ трафикпен не болып жатқанын бақылайды. Бұл L4-те жақсы жұмыс істемейді, себебі ол жоғары деңгейлі хаттамалардың логикасына байланысты: L4-те операция қанша уақытқа созылғаны немесе қосылымның аяқталуы жақсы немесе нашар болғаны туралы ақпарат жоқ. Белсенді тексерулер теңгерушіден әрбір сервер данасына сұрау жіберуді талап етеді.

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

Yandex.Cloud жүйесіндегі желілік жүктемені теңестіру құралының архитектурасы

Теңгерім мен денсаулықты тексеруді бөлу проблемаларға әкелуі мүмкін. Егер денсаулықты тексеру түйіні балансизаторды айналып өтіп (қазіргі уақытта трафикке қызмет көрсетпейтін) данаға сұраулар жасаса, оғаш жағдай туындайды: ресурс тірі сияқты, бірақ трафик оған жетпейді. Біз бұл мәселені осылай шешеміз: бізге балансерлер арқылы трафикті тексеруді бастауға кепілдік беріледі. Басқаша айтқанда, клиенттерден және денсаулық тексерулерінен трафикпен пакеттерді жылжыту схемасы аз ерекшеленеді: екі жағдайда да пакеттер оларды мақсатты ресурстарға жеткізетін теңгерімдеушілерге жетеді.

Айырмашылық мынада, клиенттер VIP-ке сұраныс жасайды, ал денсаулық тексерулері әрбір жеке RIP-ке сұраныс жасайды. Мұнда қызықты мәселе туындайды: біз пайдаланушыларға сұр IP желілерінде ресурстарды құру мүмкіндігін береміз. Өз қызметтерін балансирлердің артына жасырған екі түрлі бұлт иелері бар деп елестетіп көрейік. Олардың әрқайсысында 10.0.0.1/24 ішкі желіде бірдей мекенжайлары бар ресурстар бар. Сіз оларды қандай да бір түрде ажырата білуіңіз керек және мұнда Yandex.Cloud виртуалды желісінің құрылымына енуіңіз керек. Толығырақ ақпаратты бөлімінен алған дұрыс about:Cloud оқиғасынан бейне, қазір біз үшін желі көпқабатты және ішкі желі идентификаторымен ерекшеленетін туннельдер бар екендігі маңызды.

Денсаулықты тексеру түйіндері квази-IPv6 деп аталатын мекенжайларды қолданатын теңгергіштермен байланысады. Квазимекен-жай - IPv6 мекенжайы және оның ішінде енгізілген пайдаланушы ішкі желі идентификаторы бар IPv4 мекенжайы. Трафик баланстанушыға жетеді, ол одан IPv4 ресурсының мекенжайын шығарады, IPv6-ны IPv4-ке ауыстырады және пакетті пайдаланушы желісіне жібереді.

Кері трафик дәл осылай жүреді: теңгерімші тағайындалған жердің денсаулық тексерушілерінің сұр желі екенін көреді және IPv4-ті IPv6-ға түрлендіреді.

VPP - деректер жазықтығының жүрегі

Баланстандырушы желілік трафикті пакеттік өңдеуге арналған Cisco компаниясының негізі болып табылатын Vector Packet Processing (VPP) технологиясы арқылы жүзеге асырылады. Біздің жағдайда, құрылым пайдаланушы-ғарыштық желі құрылғыларын басқару кітапханасының жоғарғы жағында жұмыс істейді - Data Plane Development Kit (DPDK). Бұл пакетті өңдеудің жоғары өнімділігін қамтамасыз етеді: ядрода үзілістер әлдеқайда аз болады және ядро ​​кеңістігі мен пайдаланушы кеңістігі арасында контекстік ауыстырғыштар жоқ. 

VPP одан да алға жылжып, пакеттерді пакеттерге біріктіру арқылы жүйеден одан да көп өнімділікті сығады. Өнімділік жетістіктері қазіргі заманғы процессорлардағы кэштерді агрессивті пайдаланудан келеді. Деректер кэштері де пайдаланылады (пакеттер «векторларда» өңделеді, деректер бір-біріне жақын) және нұсқаулар кэштері: VPP-де пакеттерді өңдеу график бойынша жүреді, оның түйіндері бірдей тапсырманы орындайтын функцияларды қамтиды.

Мысалы, VPP-де IP пакеттерін өңдеу келесі ретпен жүреді: алдымен пакет тақырыптары талдау түйінінде талданады, содан кейін олар маршруттау кестелері бойынша пакеттерді әрі қарай жіберетін түйінге жіберіледі.

Кішкене хардкор. VPP авторлары процессорлық кэштерді пайдаланудағы ымыраға жол бермейді, сондықтан пакеттер векторын өңдеуге арналған типтік код қолмен векторлауды қамтиды: өңдеу циклі бар, онда «кезекте төрт пакет бар» сияқты жағдай өңделеді, содан кейін екеуі үшін бірдей, содан кейін - біреу үшін. Алдын ала алу нұсқаулары келесі итерацияларда оларға қол жеткізуді жылдамдату үшін кэштерге деректерді жүктеу үшін жиі пайдаланылады.

n_left_from = frame->n_vectors;
while (n_left_from > 0)
{
    vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
    // ...
    while (n_left_from >= 4 && n_left_to_next >= 2)
    {
        // processing multiple packets at once
        u32 next0 = SAMPLE_NEXT_INTERFACE_OUTPUT;
        u32 next1 = SAMPLE_NEXT_INTERFACE_OUTPUT;
        // ...
        /* Prefetch next iteration. */
        {
            vlib_buffer_t *p2, *p3;

            p2 = vlib_get_buffer (vm, from[2]);
            p3 = vlib_get_buffer (vm, from[3]);

            vlib_prefetch_buffer_header (p2, LOAD);
            vlib_prefetch_buffer_header (p3, LOAD);

            CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, STORE);
            CLIB_PREFETCH (p3->data, CLIB_CACHE_LINE_BYTES, STORE);
        }
        // actually process data
        /* verify speculative enqueues, maybe switch current next frame */
        vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
                to_next, n_left_to_next,
                bi0, bi1, next0, next1);
    }

    while (n_left_from > 0 && n_left_to_next > 0)
    {
        // processing packets by one
    }

    // processed batch
    vlib_put_next_frame (vm, node, next_index, n_left_to_next);
}

Сонымен, Healthchecks IPv6 арқылы VPP-ге сөйлеседі, бұл оларды IPv4-ке айналдырады. Мұны біз алгоритмдік NAT деп атайтын графиктегі түйін жасайды. Кері трафик үшін (және IPv6-дан IPv4-ке түрлендіру) бірдей алгоритмдік NAT түйіні бар.

Yandex.Cloud жүйесіндегі желілік жүктемені теңестіру құралының архитектурасы

Баланстауыш клиенттерінен тікелей трафик теңгерімдеуді өзі орындайтын график түйіндері арқылы өтеді. 

Yandex.Cloud жүйесіндегі желілік жүктемені теңестіру құралының архитектурасы

Бірінші түйін - жабысқақ сеанстар. Ол хэшті сақтайды 5-кортеж белгіленген сессиялар үшін. 5-кортеж ақпарат жіберілетін клиенттің мекенжайы мен портын, трафикті қабылдау үшін қолжетімді ресурстардың мекенжайы мен порттарын, сонымен қатар желілік протоколды қамтиды. 

5-кортеждік хэш келесі дәйекті хэштеу түйінінде аз есептеуді орындауға, сондай-ақ балансизатордың артындағы ресурстар тізімінің өзгерістерін жақсы өңдеуге көмектеседі. Сеансы жоқ пакет балансизаторға келгенде, ол тұрақты хэштеу түйініне жіберіледі. Дәл осы жерде теңдестіру дәйекті хэштеу арқылы жүзеге асады: біз қолжетімді «тірі» ресурстар тізімінен ресурсты таңдаймыз. Әрі қарай пакеттер нақты тағайындалған мекенжайды ауыстыратын және бақылау сомасын қайта есептейтін NAT түйініне жіберіледі. Көріп отырғаныңыздай, біз VPP ережелерін ұстанамыз - ұнату ұнайды, процессор кэштерінің тиімділігін арттыру үшін ұқсас есептеулерді топтастыру.

Тұрақты хэштеу

Неліктен біз оны таңдадық және ол қандай? Алдымен, алдыңғы тапсырманы қарастырайық - тізімнен ресурсты таңдау. 

Yandex.Cloud жүйесіндегі желілік жүктемені теңестіру құралының архитектурасы

Сәйкес келмейтін хэштеу кезінде кіріс пакетінің хэші есептеледі және осы хэшті ресурстар санына бөлудің қалған бөлігі бойынша тізімнен ресурс таңдалады. Тізім өзгеріссіз қалса, бұл схема жақсы жұмыс істейді: біз әрқашан бірдей 5-кортежі бар пакеттерді бір данаға жібереміз. Мысалы, кейбір ресурс денсаулық тексерулеріне жауап беруді тоқтатса, хэштердің маңызды бөлігі үшін таңдау өзгереді. Клиенттің TCP қосылымдары үзіледі: бұрын А данасына жеткен пакет осы пакеттің сеансымен таныс емес В данасына жете бастауы мүмкін.

Тұрақты хэштеу сипатталған мәселені шешеді. Бұл тұжырымдаманы түсіндірудің ең оңай жолы мынада: сізде ресурстарды хэш бойынша тарататын сақина бар деп елестетіңіз (мысалы, IP: порт арқылы). Ресурсты таңдау дөңгелекті бұрышпен бұру болып табылады, ол пакеттің хэшімен анықталады.

Yandex.Cloud жүйесіндегі желілік жүктемені теңестіру құралының архитектурасы

Бұл ресурстардың құрамы өзгерген кезде трафикті қайта бөлуді азайтады. Ресурсты жою тек ресурс орналасқан тұрақты хэштеу сақинасының бөлігіне ғана әсер етеді. Ресурсты қосу таратуды да өзгертеді, бірақ бізде бұрыннан орнатылған сеанстарды жаңа ресурстарға ауыстырмауға мүмкіндік беретін жабысқақ сеанстар түйіні бар.

Біз теңгерімдеуші мен ресурстар арасындағы тікелей трафикпен не болатынын қарастырдық. Енді кері трафикті қарастырайық. Ол алгоритмдік NAT арқылы, яғни клиент трафигі үшін кері NAT 44 арқылы және денсаулықты тексеру трафигі үшін NAT 46 арқылы тексеру трафикімен бірдей үлгіге сүйенеді. Біз өз схемамызды ұстанамыз: біз денсаулықты тексеру трафигі мен нақты пайдаланушы трафигін біріктіреміз.

Loadbalancer-түйін және құрастырылған компоненттер

VPP-дегі теңгергіштер мен ресурстардың құрамы туралы жергілікті қызмет – жүк теңестіруші-түйін хабарлайды. Ол жүктеме теңестіруші-контроллерден оқиғалар ағынына жазылады және ағымдағы VPP күйі мен контроллерден алынған мақсатты күй арасындағы айырмашылықты сыза алады. Біз жабық жүйені аламыз: API оқиғалары баланстық контроллерге келеді, ол ресурстардың «тіршілігін» тексеру үшін денсаулықты тексеру контроллеріне тапсырмалар береді. Бұл, өз кезегінде, денсаулықты тексеру түйініне тапсырмаларды тағайындайды және нәтижелерді біріктіреді, содан кейін ол оларды баланстық контроллерге кері жібереді. Loadbalancer-түйін контроллерден оқиғаларға жазылады және VPP күйін өзгертеді. Мұндай жүйеде әрбір қызмет көрші қызметтер туралы не қажет екенін ғана біледі. Қосылымдар саны шектеулі және бізде әртүрлі сегменттерді дербес басқару және масштабтау мүмкіндігі бар.

Yandex.Cloud жүйесіндегі желілік жүктемені теңестіру құралының архитектурасы

Қандай мәселелерден аулақ болды?

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

Мәселелер мен шешімдер

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

Сондай-ақ, Go функционалдық сынақтар үшін ең жақсы таңдау болмауы мүмкін. Олар өте егжей-тегжейлі және «бәрін CI-де пакетте іске қосу» стандартты тәсілі олар үшін өте қолайлы емес. Функционалдық сынақтар ресурсты қажет етеді және нақты күту уақытын тудырады. Осыған байланысты сынақтар сәтсіз болуы мүмкін, себебі процессор бірлік сынақтарымен бос емес. Қорытынды: Мүмкін болса, «ауыр» сынақтарды бірлік сынақтарынан бөлек орындаңыз. 

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

Біздің жоспарларымыз

Біз ішкі теңгерімді, IPv6 теңгергішін іске қосамыз, Kubernetes сценарийлеріне қолдау қосамыз, қызметтерімізді бөлуді жалғастырамыз (қазіргі уақытта тек healthcheck-node және healthcheck-ctrl бөлісілген), жаңа денсаулық тексерулерін қосамыз, сондай-ақ тексерулердің смарт біріктіруін енгіземіз. Біз қызметтерімізді одан да тәуелсіз ету мүмкіндігін қарастырудамыз - олар бір-бірімен тікелей емес, хабарламалар кезегін пайдалана отырып байланысады. Бұлтта жақында SQS-үйлесімді қызмет пайда болды Яндекс хабарлама кезегі.

Жақында Yandex Load Balancer-тің көпшілікке арналған шығарылымы өтті. Зерттеу құжаттама қызметке, теңгерімдеушілерді өзіңізге ыңғайлы түрде басқарыңыз және жобаларыңыздың ақауларға төзімділігін арттырыңыз!

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

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