Salom, men Sergey Elantsevman, men rivojlanaman
Birinchidan, ba'zi atamalarni kiritamiz:
- VIP (Virtual IP) - muvozanatlashtiruvchi IP-manzil
- Server, backend, instance - ilova bilan ishlaydigan virtual mashina
- RIP (Real IP) - server IP manzili
- Healthcheck - server tayyorligini tekshirish
- Availability Zone, AZ - ma'lumotlar markazidagi izolyatsiyalangan infratuzilma
- Mintaqa - turli AZlar ittifoqi
Yuk balanslagichlari uchta asosiy vazifani hal qiladi: ular muvozanatni o'zi bajaradi, xizmatning nosozliklarga chidamliligini yaxshilaydi va uning masshtabini soddalashtiradi. Avtomatik trafikni boshqarish orqali nosozliklarga chidamlilik ta'minlanadi: balanslashtiruvchi dastur holatini kuzatib boradi va tiriklik tekshiruvidan o'tmagan holatlarni balanslashdan istisno qiladi. Masshtablash yukni misollar bo'yicha teng taqsimlash, shuningdek, tez orada misollar ro'yxatini yangilash orqali ta'minlanadi. Agar muvozanat etarli darajada bir xil bo'lmasa, ba'zi misollar sig'im chegarasidan oshib ketadigan yukni oladi va xizmat kamroq ishonchli bo'ladi.
Yuk balanslagichi ko'pincha u ishlaydigan OSI modelidagi protokol qatlami bilan tasniflanadi. Cloud Balancer to'rtinchi qatlam L4 ga mos keladigan TCP darajasida ishlaydi.
Keling, Cloud Balancer arxitekturasining umumiy ko'rinishiga o'tamiz. Biz tafsilotlar darajasini bosqichma-bosqich oshiramiz. Balanslashtiruvchi komponentlarni uchta sinfga ajratamiz. Konfiguratsiya tekisligi klassi foydalanuvchi o'zaro ta'siri uchun javobgardir va tizimning maqsadli holatini saqlaydi. Boshqaruv tekisligi tizimning joriy holatini saqlaydi va ma'lumotlar tekisligi sinfidagi tizimlarni boshqaradi, ular mijozlardan sizning misollaringizga trafikni etkazib berish uchun bevosita javobgardir.
Ma'lumotlar tekisligi
Trafik chegara marshrutizatorlari deb ataladigan qimmat qurilmalarda tugaydi. Xatolarga chidamliligini oshirish uchun bir nechta bunday qurilmalar bir vaqtning o'zida bitta ma'lumot markazida ishlaydi. Keyinchalik, trafik mijozlar uchun BGP orqali barcha AZ-larga istalgan translatsiya IP manzillarini e'lon qiladigan balanschilarga boradi.
Trafik ECMP orqali uzatiladi - bu marshrutlash strategiyasi bo'lib, unga ko'ra nishonga bir nechta teng yaxshi marshrutlar bo'lishi mumkin (bizning holatlarimizda maqsad IP-manzil bo'ladi) va paketlar ularning har biri bo'ylab yuborilishi mumkin. Shuningdek, biz quyidagi sxema bo'yicha bir nechta mavjud zonalarda ishlashni qo'llab-quvvatlaymiz: biz har bir zonada manzilni e'lon qilamiz, trafik eng yaqiniga boradi va uning chegarasidan tashqariga chiqmaydi. Keyinchalik postda biz trafik bilan nima sodir bo'lishini batafsil ko'rib chiqamiz.
Konfiguratsiya tekisligi
Konfiguratsiya tekisligining asosiy komponenti API bo'lib, u orqali balanslashtiruvchilar bilan asosiy operatsiyalar bajariladi: misollar yaratish, o'chirish, tarkibini o'zgartirish, sog'liqni tekshirish natijalarini olish va hokazo. Bir tomondan, bu REST API va Boshqasi, biz bulutda tez-tez gRPC ramkasidan foydalanamiz, shuning uchun biz RESTni gRPC ga “tarjima qilamiz” va keyin faqat gRPC dan foydalanamiz. Har qanday so'rov Yandex.Cloud ishchilarining umumiy hovuzida bajariladigan bir qator asinxron idempotent vazifalarni yaratishga olib keladi. Vazifalar shunday yozilganki, ular istalgan vaqtda to'xtatib qo'yilishi va keyin qayta ishga tushirilishi mumkin. Bu miqyoslilikni, takrorlanuvchanlikni va operatsiyalarni qayd qilishni ta'minlaydi.
Natijada, API topshirig'i Go-da yozilgan balanslash xizmati boshqaruvchisiga so'rov yuboradi. U balanslashtirgichlarni qo'shishi va olib tashlashi, orqa tomonlar va sozlamalar tarkibini o'zgartirishi mumkin.
Xizmat o'z holatini Yandex ma'lumotlar bazasida saqlaydi, siz tez orada foydalanishingiz mumkin bo'lgan taqsimlangan boshqariladigan ma'lumotlar bazasi. Yandex.Cloud-da, biz allaqachon bo'lgani kabi
Keling, muvozanat boshqaruvchisiga qaytaylik. Uning vazifasi balanslashtiruvchi haqidagi ma'lumotni saqlash va virtual mashinaning tayyorligini tekshirish uchun sog'liqni tekshirish nazoratchisiga topshiriq yuborishdir.
Sog'liqni tekshirish nazoratchisi
U tekshirish qoidalarini o'zgartirish bo'yicha so'rovlarni qabul qiladi, ularni YDBda saqlaydi, sog'liqni tekshirish tugunlari o'rtasida vazifalarni taqsimlaydi va natijalarni jamlaydi, so'ngra ma'lumotlar bazasiga saqlanadi va yuk balansi boshqaruvchisiga yuboriladi. U, o'z navbatida, ma'lumotlar tekisligidagi klaster tarkibini o'zgartirish to'g'risidagi so'rovni yuk balansi-tuguniga yuboradi, men buni quyida muhokama qilaman.
Keling, tibbiy ko'riklar haqida ko'proq gaplashaylik. Ularni bir necha sinflarga bo'lish mumkin. Auditlarda turli muvaffaqiyat mezonlari mavjud. TCP tekshiruvlari belgilangan vaqt ichida ulanishni muvaffaqiyatli o'rnatishi kerak. HTTP tekshiruvlari muvaffaqiyatli ulanishni va 200 holat kodi bilan javobni talab qiladi.
Shuningdek, tekshiruvlar harakat sinfida farqlanadi - ular faol va passivdir. Passiv tekshiruvlar hech qanday maxsus choralar ko'rmasdan, tirbandlik bilan nima sodir bo'layotganini kuzatib boradi. Bu L4 da unchalik yaxshi ishlamaydi, chunki u yuqori darajadagi protokollar mantig'iga bog'liq: L4 da operatsiya qancha davom etgani yoki ulanishning yaxshi yoki yomon yakunlanganligi haqida ma'lumot yo'q. Faol tekshiruvlar balanslashtiruvchidan har bir server misoliga so'rov yuborishni talab qiladi.
Aksariyat yuk balanslagichlari jonlilikni tekshirishni o'zlari amalga oshiradilar. Cloud-da biz miqyosni oshirish uchun tizimning ushbu qismlarini ajratishga qaror qildik. Ushbu yondashuv xizmatga tibbiy tekshiruv so'rovlari sonini saqlab qolgan holda balanschilar sonini ko'paytirishga imkon beradi. Tekshiruvlar alohida sog'liqni tekshirish tugunlari tomonidan amalga oshiriladi, ular bo'ylab tekshirish maqsadlari ajratiladi va takrorlanadi. Siz bitta xostdan tekshirishni amalga oshira olmaysiz, chunki u muvaffaqiyatsiz bo'lishi mumkin. Keyin u tekshirgan holatlarning holatini olmaymiz. Biz kamida uchta sog'liqni tekshirish tugunidan har qanday misolni tekshiramiz. Biz izchil xeshlash algoritmlaridan foydalangan holda tugunlar orasidagi tekshirish maqsadlarini ajratamiz.
Muvozanat va sog'liqni tekshirishni ajratish muammolarga olib kelishi mumkin. Agar sog'liqni tekshirish tuguni balanserni chetlab o'tib (hozirda trafikga xizmat qilmaydi) misolga so'rovlar yuborsa, g'alati vaziyat yuzaga keladi: resurs tirikdek tuyuladi, lekin trafik unga etib bormaydi. Biz bu muammoni shunday hal qilamiz: balanschilar orqali trafikni tekshirishni boshlashimiz kafolatlanadi. Boshqacha qilib aytadigan bo'lsak, mijozlar va tibbiy tekshiruvlardan kelgan trafik bilan paketlarni ko'chirish sxemasi minimal darajada farq qiladi: har ikkala holatda ham paketlar balanschilarga etib boradi, bu esa ularni maqsadli resurslarga etkazib beradi.
Farqi shundaki, mijozlar VIP-ga so'rovlar qiladilar, tibbiy tekshiruvlar esa har bir alohida RIP-ga so'rovlar qiladi. Bu erda qiziqarli muammo tug'iladi: biz foydalanuvchilarga kulrang IP tarmoqlarida resurslarni yaratish imkoniyatini beramiz. Tasavvur qilaylik, ikki xil bulut egalari bor, ular o'z xizmatlarini balanschilar orqasida yashirgan. Ularning har biri 10.0.0.1/24 quyi tarmog'ida bir xil manzillarga ega resurslarga ega. Siz ularni qandaydir tarzda ajrata olishingiz kerak va bu erda siz Yandex.Cloud virtual tarmog'ining tuzilishiga sho'ng'ishingiz kerak. Batafsil ma'lumotni bo'limda topish yaxshiroqdir
Healthcheck tugunlari kvazi-IPv6 manzillari yordamida balanschilar bilan bog'lanadi. Kvazi-manzil IPv6 manzili va uning ichiga o'rnatilgan foydalanuvchi quyi tarmoq identifikatoriga ega bo'lgan IPv4 manzilidir. Trafik muvozanatlashtiruvchiga etib boradi, u undan IPv4 resurs manzilini chiqaradi, IPv6 ni IPv4 bilan almashtiradi va paketni foydalanuvchi tarmog'iga yuboradi.
Teskari trafik xuddi shu tarzda ketadi: muvozanatlashtiruvchi maqsad sog'liqni tekshiruvchilarning kulrang tarmog'i ekanligini ko'radi va IPv4 ni IPv6 ga o'zgartiradi.
VPP - ma'lumotlar tekisligining yuragi
Balanslashtirgich Cisco kompaniyasining tarmoq trafigini ommaviy qayta ishlash uchun asosi bo'lgan Vector Packet Processing (VPP) texnologiyasi yordamida amalga oshiriladi. Bizning holatda, ramka foydalanuvchi-kosmik tarmoq qurilmalarini boshqarish kutubxonasi - Data Plane Development Kit (DPDK) ustida ishlaydi. Bu paketlarni qayta ishlashning yuqori samaradorligini ta'minlaydi: yadroda kamroq uzilishlar sodir bo'ladi va yadro maydoni va foydalanuvchi maydoni o'rtasida kontekstli kalitlar mavjud emas.
VPP yanada oldinga boradi va paketlarni partiyalarga birlashtirib, tizimdan yanada ko'proq unumdorlikni siqib chiqaradi. Ishlash samaradorligi zamonaviy protsessorlarda keshlardan agressiv foydalanishdan kelib chiqadi. Ikkala ma'lumot keshlari ham qo'llaniladi (paketlar "vektorlarda" qayta ishlanadi, ma'lumotlar bir-biriga yaqin) va ko'rsatmalar keshlari: VPPda paketlarni qayta ishlash grafik bo'yicha amalga oshiriladi, ularning tugunlari bir xil vazifani bajaradigan funktsiyalarni o'z ichiga oladi.
Masalan, VPPda IP-paketlarni qayta ishlash quyidagi tartibda sodir bo'ladi: birinchi navbatda paket sarlavhalari tahlil qilish tugunida tahlil qilinadi, so'ngra ular paketlarni marshrutlash jadvallari bo'yicha keyingi yo'naltiruvchi tugunga yuboriladi.
Bir oz qattiqqo'l. VPP mualliflari protsessor keshlaridan foydalanishda murosaga toqat qilmaydilar, shuning uchun paketlar vektorini qayta ishlash uchun odatiy kod qo'lda vektorlashtirishni o'z ichiga oladi: ishlov berish tsikli mavjud bo'lib, unda "navbatda bizda to'rtta paket bor" kabi vaziyat qayta ishlanadi, keyin ikkita uchun bir xil, keyin - bitta uchun. Oldindan yuklash ko'rsatmalari ko'pincha keyingi iteratsiyalarda ularga kirishni tezlashtirish uchun keshlarga ma'lumotlarni yuklash uchun ishlatiladi.
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);
}
Shunday qilib, Healthchecks IPv6 orqali VPP bilan gaplashadi, bu esa ularni IPv4 ga aylantiradi. Buni biz algoritmik NAT deb ataydigan grafikdagi tugun bajaradi. Teskari trafik (va IPv6 dan IPv4 ga o'tkazish) uchun bir xil algoritmik NAT tugun mavjud.
Balanslashtiruvchi mijozlardan to'g'ridan-to'g'ri trafik muvozanatni o'zi bajaradigan grafik tugunlari orqali o'tadi.
Birinchi tugun - yopishqoq seanslar. ning xeshini saqlaydi
5-tuple xesh bizga keyingi izchil xeshlash tugunida kamroq hisoblashni amalga oshirishga yordam beradi, shuningdek, balanslashtiruvchi orqasida resurslar ro'yxatidagi o'zgarishlarni yaxshiroq boshqarishga yordam beradi. Seans bo'lmagan paket balanslashtirgichga kelganda, u izchil xeshlash tuguniga yuboriladi. Bu erda muvozanatlash izchil xeshing yordamida amalga oshiriladi: biz mavjud "jonli" resurslar ro'yxatidan resurs tanlaymiz. Keyinchalik, paketlar NAT tuguniga yuboriladi, u aslida maqsad manzilini almashtiradi va nazorat summalarini qayta hisoblaydi. Ko'rib turganingizdek, biz VPP qoidalariga amal qilamiz - yoqtirishni yoqtirish, protsessor keshlarining samaradorligini oshirish uchun shunga o'xshash hisoblarni guruhlash.
Doimiy xeshlash
Nega biz uni tanladik va bu nima? Birinchidan, oldingi vazifani ko'rib chiqaylik - ro'yxatdan manba tanlash.
Mos kelmaydigan xesh bilan kiruvchi paketning xeshi hisoblab chiqiladi va ushbu xeshni resurslar soniga bo'lishning qolgan qismi bo'yicha ro'yxatdan resurs tanlanadi. Ro'yxat o'zgarishsiz qolsa, bu sxema yaxshi ishlaydi: biz har doim bir xil 5-tupleli paketlarni bir xil misolga yuboramiz. Agar, masalan, ba'zi manbalar sog'liq tekshiruvlariga javob berishni to'xtatgan bo'lsa, unda xeshlarning katta qismi uchun tanlov o'zgaradi. Mijozning TCP ulanishlari buziladi: avval A misoliga yetib kelgan paket ushbu paket uchun seans bilan tanish bo'lmagan B misoliga etib borishi mumkin.
Doimiy xeshlash tasvirlangan muammoni hal qiladi. Ushbu kontseptsiyani tushuntirishning eng oson yo'li bu: sizda resurslarni xesh bo'yicha (masalan, IP: port orqali) tarqatadigan uzuk borligini tasavvur qiling. Resursni tanlash g'ildirakni burchak bilan aylantirishdir, bu paketning xeshi bilan belgilanadi.
Bu resurslar tarkibi o'zgarganda trafikni qayta taqsimlashni minimallashtiradi. Resursni o'chirish faqat resurs joylashgan doimiy xeshlash halqasining qismiga ta'sir qiladi. Resursni qo'shish tarqatishni ham o'zgartiradi, lekin bizda yopishqoq seanslar tuguniga ega bo'lib, u allaqachon o'rnatilgan seanslarni yangi resurslarga o'tkazmaslikka imkon beradi.
Biz balanslashtiruvchi va resurslar o'rtasidagi to'g'ridan-to'g'ri trafik bilan nima sodir bo'lishini ko'rib chiqdik. Endi qaytib keladigan trafikni ko'rib chiqaylik. Bu xuddi shunday sxema bo'yicha trafikni tekshirish - algoritmik NAT orqali, ya'ni mijoz trafigi uchun teskari NAT 44 orqali va sog'liqni tekshirish trafigi uchun NAT 46 orqali. Biz o'z sxemamizga amal qilamiz: biz trafikni sog'lig'ini tekshirish va haqiqiy foydalanuvchi trafigini birlashtiramiz.
Loadbalancer-tugun va yig'ilgan komponentlar
VPPdagi balanschilar va resurslarning tarkibi mahalliy xizmat - loadbalancer-tugun tomonidan xabar qilinadi. U yuk balansi boshqaruvchisidan voqealar oqimiga obuna bo'ladi va joriy VPP holati va kontrollerdan olingan maqsadli holat o'rtasidagi farqni chizishga qodir. Biz yopiq tizimga ega bo'lamiz: API voqealari balanslash boshqaruvchisiga keladi, u resurslarning "jonliligini" tekshirish uchun sog'liqni tekshirish nazoratchisiga topshiriq beradi. Bu, o'z navbatida, sog'liqni tekshirish tuguniga vazifalarni belgilaydi va natijalarni jamlaydi, shundan so'ng u ularni balanslash boshqaruvchisiga qaytaradi. Loadbalancer-tugun kontrollerdan voqealarga obuna bo'ladi va VPP holatini o'zgartiradi. Bunday tizimda har bir xizmat faqat qo'shni xizmatlar haqida nima kerakligini biladi. Ulanishlar soni cheklangan va biz turli segmentlarni mustaqil ravishda boshqarish va o'lchash imkoniyatiga egamiz.
Qanday muammolardan qochdi?
Boshqaruv tekisligidagi barcha xizmatlarimiz Go-da yozilgan va yaxshi masshtablash va ishonchlilik xususiyatlariga ega. Go tarqatilgan tizimlarni yaratish uchun ko'plab ochiq kodli kutubxonalarga ega. Biz GRPC dan faol foydalanamiz, barcha komponentlar xizmatni ochishning ochiq manba dasturini o‘z ichiga oladi - xizmatlarimiz bir-birining ish faoliyatini nazorat qiladi, ularning tarkibini dinamik ravishda o‘zgartirishi mumkin va biz buni GRPC balansi bilan bog‘ladik. Ko'rsatkichlar uchun biz ochiq manba echimidan ham foydalanamiz. Ma'lumotlar tekisligida biz munosib ishlash va katta resurslar zaxirasiga ega bo'ldik: temir tarmoq kartasiga emas, balki VPP ishlashiga tayanishimiz mumkin bo'lgan stendni yig'ish juda qiyin bo'lib chiqdi.
Muammolar va yechimlar
Nima yaxshi ishlamadi? Go'da avtomatik xotira boshqaruvi mavjud, ammo xotira oqishlari hali ham sodir bo'ladi. Ular bilan kurashishning eng oson yo'li - gorutinlarni ishlatish va ularni tugatishni unutmang. Olib ketish: Go dasturlaringizning xotira sarfini kuzating. Ko'pincha yaxshi ko'rsatkich gorutinlar soni hisoblanadi. Ushbu hikoyada ortiqcha narsa bor: Go-da ish vaqti ma'lumotlarini olish oson - xotira sarfi, ishlaydigan gorutinlar soni va boshqa ko'plab parametrlar.
Bundan tashqari, Go funktsional testlar uchun eng yaxshi tanlov bo'lmasligi mumkin. Ular juda batafsil va "hamma narsani CIda bir partiyada ishlatish" standart yondashuvi ular uchun unchalik mos emas. Gap shundaki, funktsional testlar ko'proq resurs talab qiladi va haqiqiy vaqt tugashiga olib keladi. Shu sababli, protsessor birlik sinovlari bilan band bo'lganligi sababli testlar muvaffaqiyatsiz bo'lishi mumkin. Xulosa: Iloji bo'lsa, "og'ir" testlarni birlik sinovlaridan alohida bajaring.
Mikroservis hodisasi arxitekturasi monolitdan ko'ra murakkabroq: o'nlab turli xil mashinalarda jurnallarni yig'ish unchalik qulay emas. Xulosa: agar siz mikroservislar qilsangiz, darhol kuzatuv haqida o'ylang.
Bizning rejalarimiz
Biz ichki muvozanatlashtirgichni, IPv6 balanslagichini ishga tushiramiz, Kubernetes skriptlarini qo‘llab-quvvatlaymiz, xizmatlarimizni bo‘laklashda davom etamiz (hozirda faqat Healthcheck-tugun va Healthcheck-ctrl ajratilgan), yangi sog‘liqni tekshirishlarni qo‘shamiz, shuningdek, cheklarning aqlli yig‘ilishini amalga oshiramiz. Biz xizmatlarimizni yanada mustaqil qilish imkoniyatini ko'rib chiqmoqdamiz - ular bir-biri bilan to'g'ridan-to'g'ri emas, balki xabarlar navbati yordamida aloqa qilishlari uchun. Yaqinda Bulutda SQS-mos keladigan xizmat paydo bo'ldi
Yaqinda Yandex Load Balancer-ning ommaviy chiqarilishi bo'lib o'tdi. Tadqiq qiling
Manba: www.habr.com