Яндекс.Булуттагы тармак жүк балансынын архитектурасы

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

Биринчиден, кээ бир терминдерди киргизели:

  • VIP (Virtual IP) - баланстоочу IP дареги
  • Сервер, бэкэнд, инстанция - тиркемени иштеткен виртуалдык машина
  • RIP (Real IP) - сервердин IP дареги
  • Healthcheck - сервердин даярдыгын текшерүү
  • Жеткиликтүүлүк аймагы, AZ - маалымат борборунда обочолонгон инфраструктура
  • Регион - ар кандай АЗдардын биримдиги

Жүк баланстоочулар үч негизги милдетти чечет: алар тең салмактуулукту өзү аткарышат, кызматтын катачылыкка чыдамдуулугун жакшыртышат жана анын масштабын жөнөкөйлөштүрүшөт. Мүчүлүштүккө толеранттуулук трафикти автоматтык башкаруу аркылуу камсыз кылынат: баланстоочу тиркеменин абалын көзөмөлдөйт жана жандуу текшерүүдөн өтпөй калган учурларды тең салмактуулуктан чыгарат. Масштабдоо жүктү инстанциялар боюнча бирдей бөлүштүрүү, ошондой эле инстанциялардын тизмесин тез арада жаңылоо аркылуу камсыз кылынат. Эгерде тең салмактуулук бирдей болбосо, кээ бир инстанциялар кубаттуулук чегинен ашкан жүктү алып, кызматтын ишенимдүүлүгү начарлайт.

Жүктөлгөн баланстоочу көбүнчө ал иштеген OSI моделинин протокол катмары менен классификацияланат. Cloud Balancer төртүнчү L4 катмарына туура келген TCP деңгээлинде иштейт.

Келгиле, Cloud балансташтыруучу архитектурасынын серепине өтөлү. Биз деталдардын деңгээлин акырындык менен жогорулатабыз. Биз баланстоочу компоненттерди үч класска бөлөбүз. Конфигурацияланган учак классы колдонуучунун өз ара аракеттенүүсү үчүн жооптуу жана системанын максаттуу абалын сактайт. Башкаруу учагы тутумдун учурдагы абалын сактайт жана кардарлардан трафикти сиздин инстанцияларыңызга жеткирүү үчүн түздөн-түз жооптуу болгон маалымат тепкичинин классындагы системаларды башкарат.

Маалымат учагы

Трафик чек ара роутерлери деп аталган кымбат түзмөктөрдө аяктайт. Мүчүлүштүккө толеранттуулукту жогорулатуу үчүн, бир маалымат борборунда бир эле учурда бир нече мындай түзмөктөр иштейт. Андан кийин, трафик баланстоочуларга барат, алар кардарлар үчүн BGP аркылуу бардык AZларга каалаган IP даректерин жарыялайт. 

Яндекс.Булуттагы тармак жүк балансынын архитектурасы

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

Учак конфигурациялоо

 
Конфигурациялоо тегиздигинин негизги компоненти API болуп саналат, ал аркылуу баланстоочулар менен негизги операциялар аткарылат: инстанцияларды түзүү, жок кылуу, курамын өзгөртүү, ден соолукту текшерүүнүн натыйжаларын алуу ж.б.у.с. Бир жагынан, бул REST API жана башкасы, биз Булутта көбүнчө gRPC алкагын колдонобуз, андыктан RESTти gRPCге “которуп”, андан кийин гана gRPC колдонобуз. Ар кандай суроо-талап Yandex.Cloud жумушчуларынын жалпы бассейнинде аткарылуучу асинхрондук идемпотенттик тапшырмалардын сериясын түзүүгө алып келет. Тапшырмалар каалаган убакта токтотулуп, анан кайра баштала тургандай кылып жазылат. Бул масштабдуулукту, кайталанууну жана операцияларды каттоону камсыз кылат.

Яндекс.Булуттагы тармак жүк балансынын архитектурасы

Натыйжада, API тапшырмасы Go-да жазылган баланстоочу кызмат контроллерине суроо-талап кылат. Ал баланс салгычтарды кошуп жана алып салышы, арткы жана жөндөөлөрдүн курамын өзгөртө алат. 

Яндекс.Булуттагы тармак жүк балансынын архитектурасы

Кызмат өз абалын Яндекс маалымат базасында, бөлүштүрүлгөн башкарылган маалымат базасында сактайт, аны сиз жакында колдоно аласыз. Яндекс.Cloud, биз буга чейин эле айтып, ит тамак-аш концепциясы колдонулат: эгерде биз өзүбүздүн кызматтарыбызды колдонсок, анда биздин кардарлар да аларды колдонууга кубанычта болушат. Яндекс базасы мындай концепцияны ишке ашыруунун мисалы болуп саналат. Биз бардык маалыматтарыбызды YDBде сактайбыз жана маалымат базасын сактоо жана масштабдоо жөнүндө ойлонбошубуз керек: бул көйгөйлөр биз үчүн чечилген, биз маалымат базасын кызмат катары колдонобуз.

Келгиле, баланстоочу контроллерге кайрылып көрөлү. Анын милдети - баланстоочу жөнүндө маалыматты сактоо жана виртуалдык машинанын даярдыгын Healthcheck контроллерине текшерүү тапшырмасын жөнөтүү.

Ден соолукту текшергич

Ал текшерүү эрежелерин өзгөртүү боюнча суроо-талаптарды кабыл алат, аларды YDBде сактайт, ден-соолукту текшерүү түйүндөрүнүн арасында тапшырмаларды бөлүштүрөт жана натыйжаларды топтойт, андан кийин маалымат базасына сакталат жана жүк баланстоочу контроллерге жөнөтүлөт. Ал, өз кезегинде, маалымат тегиздигинде кластердин курамын өзгөртүү боюнча суроо-талапты мен төмөндө талкуулай турган loadbalancer-түйүнгө жөнөтөт.

Яндекс.Булуттагы тармак жүк балансынын архитектурасы

Келгиле, ден соолукту текшерүү жөнүндө көбүрөөк сүйлөшөлү. Аларды бир нече класстарга бөлүүгө болот. Аудиттердин ар кандай ийгилик критерийлери бар. TCP текшерүүлөрү белгиленген убакыттын ичинде ийгиликтүү байланыш түзүшү керек. HTTP текшерүүлөрү ийгиликтүү туташууну жана 200 статус коду менен жоопту талап кылат.

Ошондой эле, текшерүүлөр иш-аракет классы боюнча айырмаланат - алар активдүү жана пассивдүү. Пассивдүү текшерүүлөр эч кандай атайын чара көрбөй эле трафик менен эмне болуп жатканын көзөмөлдөйт. Бул L4те жакшы иштебейт, анткени ал жогорку деңгээлдеги протоколдордун логикасына жараша болот: L4те операция канча убакытка созулганы же туташуу жакшы же жаман аяктагандыгы тууралуу маалымат жок. Активдүү текшерүүлөр баланстоочудан ар бир сервер инстанциясына суроо-талаптарды жөнөтүүнү талап кылат.

Көбүнчө жүк теңдештирүүчүлөрү жашоону текшерет. Булутта биз масштабдуулукту жогорулатуу үчүн системанын бул бөлүктөрүн бөлүүнү чечтик. Бул ыкма тейлөөгө медициналык текшерүү сурамдарынын санын сактоо менен баланстоочулардын санын көбөйтүүгө мүмкүндүк берет. Текшерүүлөр өзүнчө ден-соолукту текшерүү түйүндөрүндө аткарылат, алар аркылуу текшерүү максаттары бөлүштүрүлөт жана репликацияланат. Сиз бир хосттон текшерүү жүргүзө албайсыз, анткени ал ишке ашпай калышы мүмкүн. Анда ал текшерген инстанциялардын абалын албайбыз. Биз эң аз дегенде үч ден-соолукту текшерүү түйүндөрүнүн кайсы биринде текшерүүлөрдү жүргүзөбүз. Биз ырааттуу хэширлөө алгоритмдерин колдонуу менен түйүндөрдүн ортосундагы текшерүүлөрдүн максаттарын бөлөбүз.

Яндекс.Булуттагы тармак жүк балансынын архитектурасы

Баланстуулукту жана ден соолукту текшерүүнү бөлүү көйгөйлөргө алып келиши мүмкүн. Эгерде ден-соолукту текшерүү түйүнү балансизаторду (учурда трафикти тейлебейт) айланып өтүп, инстанцияга суроо-талаптарды берсе, анда кызыктай жагдай пайда болот: ресурс тирүү окшойт, бирок трафик ага жетпейт. Биз бул маселени ушундай жол менен чечебиз: биз баланстоочулар аркылуу трафикти текшерүүнү баштоого кепилдик беребиз. Башкача айтканда, кардарлардан жана медициналык текшерүүдөн келген трафик менен пакеттерди жылдыруу схемасы бир аз айырмаланат: эки учурда тең пакеттер баланстоочуларга жетет, ал аларды максаттуу ресурстарга жеткирет.

Айырмачылыгы, кардарлардын VIPке кайрылуусунда, ал эми ден соолук текшерүүлөрү ар бир жеке RIPке суроо-талаптарды жөнөтүүдө. Бул жерде кызыктуу маселе келип чыгат: биз колдонуучуларыбызга боз IP тармактарында ресурстарды түзүү мүмкүнчүлүгүн беребиз. Келгиле, эки башка булут ээлери бар деп элестетип көрөлү, алар өз кызматтарын балансизаторлордун артына жашырышкан. Алардын ар биринин 10.0.0.1/24 субнетинде ресурстары бар, ошол эле даректер менен. Сиз аларды кандайдыр бир жол менен ажырата билишиңиз керек жана бул жерде сиз Yandex.Cloud виртуалдык тармагынын түзүмүнө киришиңиз керек. Кененирээк маалымат алуу үчүн жакшыраак about:cloud окуясынан видео, тармак көп катмарлуу жана субнеттин идентификатору менен айырмалануучу туннелдер бар экени азыр биз үчүн маанилүү.

Healthcheck түйүндөрү квази-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 түйүнү бар.

Яндекс.Булуттагы тармак жүк балансынын архитектурасы

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

Яндекс.Булуттагы тармак жүк балансынын архитектурасы

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

5-кортеждик хэш бизге кийинки ырааттуу хэширлөө түйүнүндө азыраак эсептөөлөрдү аткарууга жардам берет, ошондой эле балансташтыргычтын артындагы ресурстардын тизмесин өзгөртүүнү жакшыртат. Сеансы жок пакет баланстоочуга келгенде, ал ырааттуу хэширлөө түйүнүнө жөнөтүлөт. Бул жерде тең салмактуулук ырааттуу хэшинг аркылуу ишке ашат: биз жеткиликтүү "тирүү" ресурстардын тизмесинен ресурсту тандайбыз. Андан кийин пакеттер NAT түйүнүнө жөнөтүлөт, ал иш жүзүндө көздөгөн даректи алмаштырат жана текшерүү суммасын кайра эсептейт. Көрүнүп тургандай, биз VPP эрежелерин карманабыз - жактыруу, процессордун кэштеринин натыйжалуулугун жогорулатуу үчүн окшош эсептөөлөрдү топтоо.

Ырааттуу хэшинг

Эмне үчүн биз аны тандап алдык жана ал эмне? Биринчиден, мурунку тапшырманы карап көрөлү - тизмеден ресурсту тандоо. 

Яндекс.Булуттагы тармак жүк балансынын архитектурасы

Ыңгайсыз хэширлөө менен, келген пакеттин хэши эсептелет жана бул хэшти ресурстардын санына бөлгөндүктөн, тизмеден ресурс тандалат. Тизме өзгөрүүсүз калганда, бул схема жакшы иштейт: биз ар дайым бир эле инстанцияга бир эле 5 король менен пакеттерди жөнөтөбүз. Эгер, мисалы, кандайдыр бир ресурс медициналык текшерүүлөргө жооп бербей калса, анда хэштердин олуттуу бөлүгү үчүн тандоо өзгөрөт. Кардардын TCP байланыштары үзүлөт: мурда жеткен А инстанциясына жеткен пакет бул пакеттин сеансы менен тааныш эмес В инстанциясына жете башташы мүмкүн.

Ырааттуу хэширлөө сүрөттөлгөн маселени чечет. Бул концепцияны түшүндүрүүнүн эң оңой жолу бул: сизде ресурстарды хэш боюнча бөлүштүрүүчү шакек бар деп элестетиңиз (мисалы, IP: порт боюнча). Ресурсту тандоо дөңгөлөктү бир бурчка буруп жатат, ал пакеттин хэштери менен аныкталат.

Яндекс.Булуттагы тармак жүк балансынын архитектурасы

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

Биз баланстоочу менен ресурстардын ортосундагы түз трафик эмне болорун карап чыктык. Эми кайтып келүүчү трафикти карап көрөлү. Ал трафикти текшерүү сыяктуу эле схема боюнча жүрөт - алгоритмдик NAT аркылуу, башкача айтканда, кардарлардын трафиги үчүн тескери NAT 44 аркылуу жана саламаттыкты текшерүү трафики үчүн NAT 46 аркылуу. Биз өзүбүздүн схемабызды карманабыз: биз ден-соолукту текшерген трафикти жана чыныгы колдонуучу трафигин бириктиребиз.

Loadbalancer-түйүн жана чогулган компоненттер

VPPдеги балансчылардын жана ресурстардын курамын жергиликтүү кызмат - жүктөөчү-түйүн билдирет. Ал жүк теңдештирүүчү-контроллерден окуялардын агымына жазылат жана учурдагы VPP абалы менен контроллерден алынган максаттуу абалдын ортосундагы айырманы түзө алат. Биз жабык системаны алабыз: API окуялары баланстоочу контроллерге келет, ал ресурстардын "жандуулугун" текшерүү үчүн Healthcheck контроллерине тапшырмаларды берет. Бул, өз кезегинде, ден-соолукту текшерүү түйүнүнө тапшырмаларды берет жана натыйжаларды бириктирет, андан кийин аларды баланстоочу контроллерге кайра жөнөтөт. Loadbalancer-түйүн контроллерден келген окуяларга жазылат жана VPP абалын өзгөртөт. Мындай системада ар бир кызмат кошуна кызматтар жөнүндө эмне керек экенин гана билет. Байланыштардын саны чектелген жана бизде ар кандай сегменттерди өз алдынча иштетүү жана масштабдоо мүмкүнчүлүгү бар.

Яндекс.Булуттагы тармак жүк балансынын архитектурасы

Кандай маселелер четте калды?

Башкаруу тегиздигинде биздин бардык кызматтар Go тилинде жазылган жана масштабдуу жана ишенимдүү мүнөздөмөлөргө ээ. Go бөлүштүрүлгөн системаларды куруу үчүн көптөгөн ачык булак китепканалары бар. Биз GRPCти жигердүү колдонобуз, бардык компоненттерде кызматтын ачылышынын ачык булагы бар - биздин кызматтар бири-биринин иштешин көзөмөлдөйт, алардын курамын динамикалык түрдө өзгөртө алат жана биз муну GRPC балансташтыруу менен байланыштырдык. Метрика үчүн биз ачык булактуу чечимди да колдонобуз. Берилиштер тегиздигинде биз татыктуу өндүрүмдүүлүккө жана чоң ресурстук резервге ээ болдук: темир тармак картасына эмес, VPPтин иштешине таяна турган стендди чогултуу абдан кыйын болуп чыкты.

Проблемалар жана чечимдер

Эмне мынчалык жакшы иштеген жок? Go'до эстутумду автоматтык башкаруу бар, бирок эс тутумдун агып кетиши дагы деле болот. Алар менен күрөшүүнүн эң оңой жолу - горутиндерди иштетүү жана аларды токтотууну унутпаңыз. Takeaway: Go программаларыңыздын эстутумунун сарпталышын көрүңүз. Көп учурда жакшы көрсөткүч горутиндердин саны болуп саналат. Бул окуяда плюс бар: Go программасында иштөө убактысынын маалыматтарын алуу оңой - эстутум керектөө, иштеп жаткан горутиндердин саны жана башка көптөгөн параметрлер.

Ошондой эле, Go функционалдык тесттер үчүн эң жакшы тандоо болбой калышы мүмкүн. Алар абдан кеңири жана "баарын CIде бир партияда иштетүү" стандарттуу мамилеси алар үчүн анча ылайыктуу эмес. Функционалдык тесттер ресурсту көбүрөөк талап кылат жана реалдуу убакытты талап кылат. Ушундан улам, CPU бирдик сыноолору менен алек болгондуктан, тесттер ийгиликсиз болушу мүмкүн. Жыйынтык: Мүмкүн болсо, "оор" сыноолорду бирдик сыноолорунан бөлөк аткарыңыз. 

Микросервис окуясынын архитектурасы монолитке караганда татаалыраак: ондогон ар кандай машиналарда журналдарды чогултуу өтө ыңгайлуу эмес. Корутунду: эгерде сиз микросервистерди жасасаңыз, дароо трасса жөнүндө ойлонуңуз.

Биздин пландар

Биз ички балансташтыргычты, IPv6 баланстоочуну ишке киргизебиз, Kubernetes скрипттерине колдоо кошобуз, кызматтарыбызды бөлүүнү улантабыз (учурда Healthcheck-node жана Healthcheck-ctrl гана бөлүштүрүлгөн), жаңы ден-соолук текшерүүлөрүн кошобуз, ошондой эле текшерүүлөрдүн акылдуу топтомун ишке ашырабыз. Биз өз кызматтарыбызды ого бетер көз карандысыз кылуу мүмкүнчүлүгүн карап жатабыз - алар бири-бири менен түз байланышта эмес, билдирүү кезегин колдонуу менен. Жакында булутта SQS-шайкеш кызмат пайда болду Яндекс билдирүү кезеги.

Жакында Yandex Load Balancer коомдук релиз болуп өттү. Изилдөө документтештирүү кызматка, баланстоочуларды сизге ыңгайлуу жол менен башкарыңыз жана долбоорлоруңуздун катачылыкка чыдамдуулугун жогорулатыңыз!

Source: www.habr.com

Комментарий кошуу