[Tarjima] Envoy threading modeli

Maqolaning tarjimasi: Envoy threading modeli - https://blog.envoyproxy.io/envoy-threading-model-a8d44b922310

Men ushbu maqolani juda qiziq deb topdim va Elchi ko'pincha "istio" ning bir qismi sifatida yoki oddiygina kubernetlarning "kirish boshqaruvchisi" sifatida foydalanilganligi sababli, ko'pchilik u bilan, masalan, odatdagidek bevosita o'zaro ta'sir qilmaydi. Nginx yoki Haproxy o'rnatish. Biroq, agar biror narsa buzilgan bo'lsa, uning ichidan qanday ishlashini tushunish yaxshi bo'ladi. Iloji boricha matnni rus tiliga, jumladan maxsus soβ€˜zlarni tarjima qilishga harakat qildim, buni koβ€˜rish ogβ€˜riqli boβ€˜lganlar uchun asl nusxani qavs ichida qoldirdim. Mushukga xush kelibsiz.

Envoy kod bazasi uchun past darajadagi texnik hujjatlar hozirda juda kam. Buni tuzatish uchun men Elchining turli quyi tizimlari haqida bir qator blog postlarini yozishni rejalashtirmoqdaman. Bu birinchi maqola bo'lgani uchun, iltimos, fikringizni bildiring va kelgusi maqolalarda sizni nima qiziqtirishi mumkin.

Envoy haqida menga eng ko'p beriladigan texnik savollardan biri u foydalanadigan iplar modelining past darajadagi tavsifini so'rashdir. Ushbu postda men Envoy qanday qilib iplarga ulanishlarni xaritalashini, shuningdek, kodni yanada parallel va yuqori unumdor qilish uchun ichki ishlatadigan Thread Local Storage tizimini tasvirlab beraman.

Yivga umumiy nuqtai

[Tarjima] Envoy threading modeli

Elchi uch xil turdagi oqimlardan foydalanadi:

  • Asosiy: Bu oqim jarayonlarni ishga tushirish va tugatish, XDS (xDiscovery Service) API ning barcha qayta ishlanishini, jumladan DNS, salomatlik tekshiruvi, umumiy klaster va ish vaqtini boshqarish, statistikani tiklash, maΚΌmuriyat va jarayonni umumiy boshqarish – Linux signallari. issiq qayta ishga tushirish va hokazolarni boshqaradi. bu mavzuda sodir bo'ladigan hodisalar asinxron va "bloklanmaydi". Umuman olganda, asosiy ish zarrachasi ishlashi uchun katta hajmdagi protsessor talab qilmaydigan barcha muhim funktsional jarayonlarni muvofiqlashtiradi. Bu ko'pchilik boshqaruv kodini xuddi bitta ipli kabi yozishga imkon beradi.
  • Ishchi: Odatiy bo'lib, Envoy tizimdagi har bir apparat oqimi uchun ishchi ipni yaratadi, bu variant yordamida boshqarilishi mumkin. --concurrency. Har bir ishchi ipda har bir tinglovchini tinglash uchun mas'ul bo'lgan "bloklanmaydigan" hodisa tsikli ishlaydi; yozish paytida (29 yil 2017 iyul) tinglovchining parchalanishi, yangi ulanishlarni qabul qilish, filtrlar to'plamini yaratish yo'q. ulanish va ulanish muddati davomida barcha kirish/chiqish (IO) operatsiyalarini qayta ishlash. Shunga qaramay, bu ko'pchilik ulanish kodlarini xuddi bitta tishli kabi yozishga imkon beradi.
  • Faylni tozalash: Envoy yozadigan har bir fayl, asosan, jurnallarga kirish, hozirda mustaqil blokirovka chizig'iga ega. Buning sababi, hatto foydalanilganda ham fayl tizimi tomonidan keshlangan fayllarga yozish O_NONBLOCK ba'zan to'sib qo'yilishi mumkin (ho'rsinib). Ishchi ish zarralari faylga yozishi kerak bo'lganda, ma'lumotlar aslida xotiradagi buferga ko'chiriladi va u oxir-oqibat ip orqali tozalanadi. faylni tozalash. Bu texnik jihatdan barcha ishchi iplar xotira buferini to'ldirishga urinayotganda bir xil qulfni bloklashi mumkin bo'lgan kodning bir sohasidir.

Ulanishni boshqarish

Yuqorida qisqacha muhokama qilinganidek, barcha ishchi mavzular barcha tinglovchilarni hech qanday parchalanishsiz tinglaydi. Shunday qilib, yadro qabul qilingan rozetkalarni ishchi iplarga jozibali tarzda yuborish uchun ishlatiladi. Zamonaviy yadrolar, odatda, bu borada juda yaxshi, ular bir xil rozetkada tinglayotgan boshqa ish zarrachalaridan foydalanishni boshlashdan oldin ipni ish bilan to'ldirishga harakat qilish uchun kiritish/chiqish (IO) ustuvorligini oshirish kabi xususiyatlardan foydalanadilar, shuningdek, round robin ishlatmaydilar. har bir so'rovni qayta ishlash uchun qulflash (Spinlock).
Ishchi ipda ulanish qabul qilingandan so'ng, u hech qachon bu ipni tark etmaydi. Ulanishning barcha keyingi ishlovlari to'liq ishchi ish zarrachasida, shu jumladan har qanday yo'naltirish harakatida amalga oshiriladi.

Bu bir nechta muhim oqibatlarga olib keladi:

  • Envoy-dagi barcha ulanish hovuzlari ishchi ipga tayinlangan. Shunday qilib, HTTP/2 ulanish hovuzlari bir vaqtning o'zida har bir yuqori oqim xostiga faqat bitta ulanishni amalga oshirsa ham, agar to'rtta ishchi tarmoq mavjud bo'lsa, barqaror holatda har bir yuqori oqim hostiga to'rtta HTTP/2 ulanishi bo'ladi.
  • Elchining bu tarzda ishlashining sababi shundaki, hamma narsani bitta ishchi ipda saqlash orqali deyarli barcha kodlarni blokirovka qilmasdan va xuddi bitta ipli kabi yozish mumkin. Ushbu dizayn juda ko'p kod yozishni osonlashtiradi va deyarli cheksiz miqdordagi ishchi iplar uchun ajoyib darajada yaxshi o'lchaydi.
  • Biroq, asosiy fikrlardan biri shundaki, xotira havzasi va ulanish samaradorligi nuqtai nazaridan, sozlamalarni sozlash juda muhim. --concurrency. Zarur bo'lgandan ko'ra ko'proq ishchi iplarga ega bo'lish xotirani yo'qotadi, ko'proq bo'sh ulanishlarni yaratadi va ulanishni birlashtirish tezligini kamaytiradi. Lyft-da bizning elchi vagon konteynerlari juda past tezlikda ishlaydi, shuning uchun unumdorlik ular yonida o'tirgan xizmatlarga taxminan mos keladi. Biz Envoy-ni chekka proksi-server sifatida faqat maksimal bir vaqtda ishga tushiramiz.

Bloklanmaslik nimani anglatadi?

"Bloklanmaslik" atamasi hozirgacha asosiy va ishchi iplar qanday ishlashini muhokama qilishda bir necha marta ishlatilgan. Barcha kod hech qachon bloklanmagan degan taxmin asosida yozilgan. Biroq, bu mutlaqo to'g'ri emas (nima butunlay to'g'ri emas?).

Elchi bir nechta uzoq jarayon qulflaridan foydalanadi:

  • Muhokama qilinganidek, kirish jurnallarini yozishda barcha ishchi iplar xotiradagi jurnal buferi to'ldirilishidan oldin bir xil qulfga ega bo'ladi. Qulfni ushlab turish vaqti juda past bo'lishi kerak, lekin yuqori bir vaqtda va yuqori o'tkazuvchanlikda qulfga qarshi kurashish mumkin.
  • Elchi mavzu uchun mahalliy bo'lgan statistik ma'lumotlarni boshqarish uchun juda murakkab tizimdan foydalanadi. Bu alohida postning mavzusi bo'ladi. Biroq, qisqacha aytib o'tmoqchimanki, iplar statistikasini mahalliy darajada qayta ishlashning bir qismi sifatida ba'zan markaziy "statistik ma'lumotlar do'konida" qulfni sotib olish kerak bo'ladi. Bu qulflash hech qachon talab qilinmasligi kerak.
  • Asosiy ip vaqti-vaqti bilan barcha ishchi iplar bilan muvofiqlashtirilishi kerak. Bu asosiy ipdan ishchi iplarga, ba'zan esa ishchi iplardan asosiy ipga "nashr qilish" orqali amalga oshiriladi. Joβ€˜natilgan xabarni keyinroq yetkazib berish uchun navbatga qoβ€˜yish uchun joβ€˜natish qulfni talab qiladi. Ushbu qulflar hech qachon jiddiy e'tiroz bildirmasligi kerak, ammo ular hali ham texnik jihatdan bloklanishi mumkin.
  • Envoy tizim xatosi oqimiga jurnal yozganda (standart xato), u butun jarayon uchun blokirovka oladi. Umuman olganda, Elchining mahalliy daraxt kesishi ishlash nuqtai nazaridan dahshatli hisoblanadi, shuning uchun uni yaxshilashga unchalik e'tibor berilmagan.
  • Yana bir nechta tasodifiy qulflar mavjud, ammo ularning hech biri ishlash uchun muhim emas va hech qachon e'tiroz bildirmaslik kerak.

Mahalliy saqlash joyi

Elchi asosiy ipning mas'uliyatini ishchi ipning mas'uliyatidan ajratib qo'yganligi sababli, asosiy ipda murakkab ishlov berish va keyin har bir ishchi ipga yuqori darajada parallel ravishda berilishi mumkin bo'lgan talab mavjud. Ushbu bo'limda Envoy Thread Local Storage (TLS) yuqori darajada tasvirlangan. Keyingi bo'limda men klasterni boshqarish uchun qanday ishlatilishini tasvirlab beraman.
[Tarjima] Envoy threading modeli

Yuqorida ta'riflanganidek, asosiy tarmoq Envoy jarayonida deyarli barcha boshqaruv va boshqaruv tekisligi funksiyalarini boshqaradi. Boshqaruv tekisligi bu erda biroz haddan tashqari yuklangan, lekin siz uni Envoy jarayonining o'zida ko'rib chiqsangiz va uni ishchi iplar bajaradigan yo'naltirish bilan taqqoslasangiz, bu mantiqiy bo'ladi. Umumiy qoida shundan iboratki, asosiy ip jarayoni ba'zi ishlarni bajaradi va keyin har bir ishchi ipni shu ish natijasiga ko'ra yangilash kerak. bu holda, ishchi ip har bir kirish uchun qulf olish kerak emas.

Elchining TLS (Thread mahalliy saqlash) tizimi quyidagicha ishlaydi:

  • Asosiy tarmoqda ishlaydigan kod butun jarayon uchun TLS slotini ajratishi mumkin. Bu mavhum bo'lsa-da, amalda bu vektorga indeks bo'lib, O (1) ga kirishni ta'minlaydi.
  • Asosiy tarmoq o'z uyasiga ixtiyoriy ma'lumotlarni o'rnatishi mumkin. Bu amalga oshirilgandan so'ng, ma'lumotlar har bir ishchi ish zarrachasiga oddiy hodisa tsikli hodisasi sifatida nashr etiladi.
  • Ishchi iplar o'zlarining TLS uyasidan o'qishlari va u erda mavjud bo'lgan har qanday mahalliy tarmoq ma'lumotlarini olishlari mumkin.

Bu juda oddiy va nihoyatda kuchli paradigma bo'lsa-da, u RCU (Read-Copy-Update) blokirovkasi tushunchasiga juda o'xshaydi. Asosan, ishchi ish zarrachalari ishlayotgan vaqtda TLS slotlarida hech qanday ma'lumotlar o'zgarishini ko'rmaydi. O'zgarish faqat ish voqealari orasidagi dam olish davrida sodir bo'ladi.

Elchi bundan ikki xil usulda foydalanadi:

  • Har bir ishchi ish zarrachasida turli xil ma'lumotlarni saqlash orqali ma'lumotlarga hech qanday blokirovkasiz kirish mumkin.
  • Har bir ishchi ipda faqat o'qish rejimida global ma'lumotlarga umumiy ko'rsatgichni saqlash orqali. Shunday qilib, har bir ishchi ish zarrachasi ishlayotgan vaqtda kamaytirilmaydigan ma'lumotlarga havolalar soniga ega. Faqatgina barcha ishchilar tinchlanib, yangi umumiy ma'lumotlarni yuklashda eski ma'lumotlar yo'q qilinadi. Bu RCU bilan bir xil.

Klaster yangilanishi

Ushbu bo'limda men klasterni boshqarish uchun TLS (Thread local storage) qanday ishlatilishini tasvirlab beraman. Klaster boshqaruvi xDS API va/yoki DNS-ni qayta ishlash, shuningdek sog'liqni tekshirishni o'z ichiga oladi.
[Tarjima] Envoy threading modeli

Klaster oqimini boshqarish quyidagi komponentlar va bosqichlarni o'z ichiga oladi:

  1. Klaster menejeri barcha ma'lum klaster yuqori oqimlarini, Cluster Discovery Service (CDS) API, Secret Discovery Service (SDS) va Endpoint Discovery Service (EDS) API'larini, DNS va faol tashqi tekshiruvlarni boshqaradigan Envoy tarkibidagi komponent hisoblanadi. U har bir yuqori oqim klasterining "oxir-oqibat izchil" ko'rinishini yaratish uchun javobgardir, bu topilgan xostlar va sog'liq holatini o'z ichiga oladi.
  2. Salomatlik tekshiruvi faol sog'liqni tekshirishni amalga oshiradi va klaster menejeriga salomatlik holati o'zgarishi haqida xabar beradi.
  3. Klaster a'zoligini aniqlash uchun CDS (Cluster Discovery Service) / SDS (Secret Discovery Service) / EDS (Endpoint Discovery Service) / DNS amalga oshiriladi. Holat o'zgarishi klaster boshqaruvchisiga qaytariladi.
  4. Har bir ishchi ish zarrachasi doimiy ravishda voqea siklini bajaradi.
  5. Klaster menejeri klaster holati o'zgarganligini aniqlaganda, u klaster holatining faqat o'qish uchun yangi suratini yaratadi va uni har bir ishchi ipga yuboradi.
  6. Keyingi sokin davrda ishchi ip ajratilgan TLS uyasidagi suratni yangilaydi.
  7. Xostni yuklash balansini aniqlashi kerak bo'lgan kiritish-chiqarish hodisasi paytida yuk balanslagichi xost haqida ma'lumot olish uchun TLS (Thread local storage) slotini so'raydi. Bu qulflarni talab qilmaydi. Shuni ham yodda tutingki, TLS yangilanish hodisalarini ham ishga tushirishi mumkin, shunda yuk balanslagichlari va boshqa komponentlar keshlarni, ma'lumotlar tuzilmalarini va hokazolarni qayta hisoblashi mumkin. Bu post doirasidan tashqarida, lekin kodning turli joylarida qo'llaniladi.

Yuqoridagi protseduradan foydalangan holda, Elchi har qanday so'rovni hech qanday blokirovkasiz ko'rib chiqishi mumkin (avval tavsiflanganidan tashqari). TLS kodining murakkabligidan tashqari, kodning ko'p qismi ko'p ish zarrachalari qanday ishlashini tushunishga hojat yo'q va uni bitta ipli yozish mumkin. Bu yuqori ishlashga qo'shimcha ravishda kodning ko'p qismini yozishni osonlashtiradi.

TLS dan foydalanadigan boshqa quyi tizimlar

Envoy dasturida TLS (Thread local storage) va RCU (Read Copy Update) keng qo'llaniladi.

Foydalanish misollar:

  • Amalga oshirish jarayonida funksionallikni o'zgartirish mexanizmi: Yoqilgan funksiyalarning joriy ro'yxati asosiy mavzuda hisoblanadi. Keyin har bir ishchi ipga RCU semantikasidan foydalangan holda faqat o'qish uchun mo'ljallangan snapshot beriladi.
  • Marshrut jadvallarini almashtirish: RDS (Marshrutni aniqlash xizmati) tomonidan taqdim etilgan marshrut jadvallari uchun marshrut jadvallari asosiy ipda yaratiladi. Faqat o'qish uchun mo'ljallangan surat keyinchalik RCU (Read Copy Update) semantikasidan foydalangan holda har bir ishchi ipga taqdim etiladi. Bu o'zgaruvchan marshrut jadvallarini atomik jihatdan samarali qiladi.
  • HTTP sarlavhasini keshlash: Ma'lum bo'lishicha, har bir so'rov uchun HTTP sarlavhasini hisoblash (har bir yadro uchun ~25K+ RPS ishlayotganda) juda qimmat. Elchi markaziy ravishda sarlavhani taxminan har yarim soniyada hisoblab chiqadi va uni TLS va RCU orqali har bir ishchiga taqdim etadi.

Boshqa holatlar ham bor, lekin oldingi misollar TLS nima uchun ishlatilishini yaxshi tushunishi kerak.

Ma'lum bo'lgan ishlash tuzoqlari

Elchi umuman olganda juda yaxshi ishlasa-da, u juda yuqori parallellik va o'tkazish qobiliyati bilan foydalanilganda e'tiborni talab qiladigan bir nechta diqqatga sazovor joylar mavjud:

  • Ushbu maqolada ta'riflanganidek, hozirda barcha ishchi iplar kirish jurnali xotirasi buferiga yozishda blokirovka oladi. Yuqori parallellik va yuqori o'tkazuvchanlikda, yakuniy faylga yozishda buyurtmadan tashqari etkazib berish hisobiga har bir ishchi ip uchun kirish jurnallarini to'plashingiz kerak bo'ladi. Shu bilan bir qatorda, har bir ishchi ip uchun alohida kirish jurnalini yaratishingiz mumkin.
  • Statistik ma'lumotlar yuqori darajada optimallashtirilgan bo'lsa-da, juda yuqori parallellik va o'tkazish qobiliyatida individual statistika bo'yicha atomik tortishuvlar bo'lishi mumkin. Ushbu muammoni hal qilish - markaziy hisoblagichlarni davriy ravishda qayta o'rnatish bilan ishlaydigan ishchi ipga hisoblagichlar. Bu keyingi postda muhokama qilinadi.
  • Agar Envoy muhim qayta ishlash resurslarini talab qiladigan ulanishlar juda kam bo'lgan stsenariyda o'rnatilsa, joriy arxitektura yaxshi ishlamaydi. Ishchi iplar orasida ulanishlar teng taqsimlanishiga kafolat yo'q. Buni ishchi aloqa balansini amalga oshirish orqali hal qilish mumkin, bu esa ishchi iplar o'rtasidagi aloqalarni almashish imkonini beradi.

Xulosa

Elchining tishli modeli, agar to'g'ri sozlanmagan bo'lsa, potentsial isrof qiluvchi xotira va ulanishlar hisobiga dasturlash qulayligi va massiv parallellikni ta'minlash uchun mo'ljallangan. Ushbu model juda yuqori iplar soni va o'tkazuvchanlikda juda yaxshi ishlashga imkon beradi.
Twitter-da qisqacha aytib o'tganimdek, dizayn DPDK (Data Plane Development Kit) kabi to'liq foydalanuvchi rejimidagi tarmoq stekida ham ishlashi mumkin, bu esa an'anaviy serverlarning to'liq L7 ishlovi bilan soniyasiga millionlab so'rovlarni bajarishiga olib kelishi mumkin. Kelgusi bir necha yil ichida nima qurishni ko'rish juda qiziq bo'ladi.
Oxirgi tezkor izoh: Mendan nega Elchi uchun C++ tilini tanlaganimizni koβ€˜p marta soβ€˜rashgan. Sababi, bu hali ham ushbu postda tasvirlangan arxitektura qurilishi mumkin bo'lgan yagona keng tarqalgan sanoat tili bo'lib qolmoqda. C++, albatta, hamma yoki hatto ko'p loyihalar uchun mos emas, lekin ba'zi foydalanish holatlarida u hali ham ishni bajarish uchun yagona vositadir.

Kod uchun havolalar

Ushbu postda muhokama qilingan interfeyslar va sarlavhali ilovalarga ega fayllarga havolalar:

Manba: www.habr.com

a Izoh qo'shish