[Аударма] Envoy жіп үлгісі

Мақаланың аудармасы: Өкіл ағынының үлгісі - https://blog.envoyproxy.io/envoy-threading-model-a8d44b922310

Маған бұл мақала өте қызықты болды, және Envoy көбінесе «istio» бөлігі ретінде немесе жай кубернеттердің «кіру контроллері» ретінде пайдаланылатындықтан, көптеген адамдар онымен, мысалы, әдеттегідей тікелей әрекеттесе алмайды. Nginx немесе Haproxy қондырғылары. Дегенмен, егер бірдеңе бұзылса, оның ішінен қалай жұмыс істейтінін түсіну жақсы болар еді. Мәтінді мүмкіндігінше орыс тіліне аударуға тырыстым, оның ішінде арнайы сөздерді де қосамын, бұған қарап қиналатындар үшін түпнұсқаларды жақшаға қалдырдым. мысыққа қош келдіңіз.

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

Envoy туралы маған келетін ең көп таралған техникалық сұрақтардың бірі ол пайдаланатын жіп үлгісінің төмен деңгейлі сипаттамасын сұрау болып табылады. Бұл постта мен Envoy қосылымдарды ағындарға қалай салыстыратынын, сонымен қатар кодты параллельді және жоғары өнімді ету үшін ішкі пайдаланатын Thread Local Storage жүйесін сипаттайтын боламын.

Жіптерге шолу

[Аударма] Envoy жіп үлгісі

Өкіл үш түрлі ағын түрін пайдаланады:

  • Негізгі: Бұл ағын процестің іске қосылуын және аяқталуын, XDS (xDiscovery Service) API барлық өңдеуін, соның ішінде DNS, денсаулықты тексеру, жалпы кластер мен жұмыс уақытын басқару, статистиканы қалпына келтіру, басқару және жалпы процесті басқару - Linux сигналдары. ыстық қайта іске қосу және т.б. басқарады. бұл ағында орын алады асинхронды және «блокталмайтын». Жалпы алғанда, негізгі ағын іске қосу үшін үлкен көлемдегі процессорды қажет етпейтін барлық маңызды функционалдық процестерді үйлестіреді. Бұл басқару кодтарының көпшілігін бір ағынды сияқты жазуға мүмкіндік береді.
  • Жұмысшы: Әдепкі бойынша, Envoy жүйедегі әрбір аппараттық құрал үшін жұмыс ағынын жасайды, оны опция арқылы басқаруға болады. --concurrency. Әрбір жұмысшы ағыны әрбір тыңдаушыны тыңдауға жауап беретін «блокталмайтын» оқиғалар циклін іске қосады; жазу кезінде (29 ж. 2017 шілде) тыңдаушының бөлінуі, жаңа қосылымдарды қабылдау, сүзгі стегін іске қосу жоқ. қосылу және қосылымның қызмет ету мерзімі ішінде барлық енгізу/шығыс (IO) операцияларын өңдеу. Тағы да, бұл қосылымды өңдеу кодтарының көпшілігін бір ағынды сияқты жазуға мүмкіндік береді.
  • Файлды тазартқыш: Envoy жазатын әрбір файл, негізінен кіру журналдары, қазіргі уақытта тәуелсіз блоктау ағыны бар. Бұл пайдаланған кезде де файлдық жүйе кэштелген файлдарға жазу фактісіне байланысты O_NONBLOCK кейде бітеліп қалуы мүмкін (күрсініп). Жұмысшы ағындары файлға жазу қажет болғанда, деректер іс жүзінде жадтағы буферге жылжытылады, онда ол ақыр соңында ағын арқылы тазартылады. файлды тазалау. Бұл жад буферін толтыруға тырысқанда техникалық түрде барлық жұмысшы ағындары бірдей құлыпты блоктай алатын кодтың бір аймағы.

Қосылымды өңдеу

Жоғарыда қысқаша талқыланғандай, барлық жұмыс ағындары барлық тыңдаушыларды ешбір үзіндісіз тыңдайды. Осылайша, ядро ​​қабылданған розеткаларды жұмысшы ағындарына әдемі түрде жіберу үшін пайдаланылады. Қазіргі ядролар әдетте бұл үшін өте жақсы, олар кіріс/шығыс (IO) басымдылығын арттыру сияқты мүмкіндіктерді пайдаланады, олар бір ұяшықта тыңдайтын басқа ағындарды пайдалана бастағанға дейін жұмысты толтыруға тырысады, сондай-ақ round robin қолданбайды. әрбір сұрауды өңдеу үшін құлыптау (Spinlock).
Қосылым жұмысшы ағынында қабылданғаннан кейін ол ешқашан сол ағыннан шықпайды. Қосылымның барлық әрі қарай өңделуі толығымен жұмысшы ағынында өңделеді, соның ішінде кез келген қайта жіберу әрекеті.

Мұның бірнеше маңызды салдары бар:

  • Envoy ішіндегі барлық қосылым пулдары жұмысшы ағынына тағайындалады. Сонымен, HTTP/2 қосылым пулдары әрбір жоғары ағындық хостқа бір уақытта тек бір қосылым жасағанымен, төрт жұмыс ағыны болса, тұрақты күйде әрбір жоғары ағындық хост үшін төрт HTTP/2 қосылымы болады.
  • Envoy осылай жұмыс істеуінің себебі, барлығын бір жұмыс ағынында сақтау арқылы барлық дерлік кодты блоктаусыз және бір ағынды сияқты жазуға болады. Бұл дизайн көптеген кодтарды жазуды жеңілдетеді және жұмысшы ағындарының шексіз санына керемет жақсы масштабталады.
  • Дегенмен, негізгі нәтижелердің бірі - жад пулы және қосылым тиімділігі тұрғысынан, конфигурациялау өте маңызды. --concurrency. Қажеттіден көп жұмыс ағындарының болуы жадты жұмсайды, бос қосылымдарды жасайды және қосылымды біріктіру жылдамдығын азайтады. Lyft-те біздің елші бүйірлік контейнерлері өте төмен параллельділікпен жұмыс істейді, сондықтан өнімділік олар жанында орналасқан қызметтерге сәйкес келеді. Біз Envoy қызметін тек максималды параллельдікте шеткі прокси ретінде іске қосамыз.

Блокталмайтын нені білдіреді?

Негізгі және жұмысшы ағындардың қалай жұмыс істейтінін талқылау кезінде «блокталмаған» термині осы уақытқа дейін бірнеше рет қолданылған. Барлық код ешнәрсе ешқашан блокталмаған деген болжаммен жазылған. Дегенмен, бұл мүлдем дұрыс емес (не мүлдем дұрыс емес?).

Өкіл бірнеше ұзақ процесс құлыптарын пайдаланады:

  • Талқыланғандай, кіру журналдарын жазғанда, жадтағы журнал буфері толтырылғанға дейін барлық жұмысшы ағындары бірдей құлыпты алады. Құлыпты ұстау уақыты өте аз болуы керек, бірақ жоғары параллельділік пен жоғары өткізу қабілеттілігінде құлыпқа қарсы шығуға болады.
  • Envoy ағынға жергілікті статистиканы өңдеу үшін өте күрделі жүйені пайдаланады. Бұл бөлек посттың тақырыбы болады. Дегенмен, қысқаша айта кетейін, жіп статистикасын жергілікті түрде өңдеудің бір бөлігі ретінде кейде орталық «статистика дүкенінде» құлыпты алу қажет. Бұл құлыптау ешқашан талап етілмеуі керек.
  • Негізгі ағын мезгіл-мезгіл барлық жұмысшы ағындарымен үйлестірілуі керек. Бұл негізгі ағыннан жұмыс ағындарына, кейде жұмысшы ағындарынан негізгі ағынға «жариялау» арқылы орындалады. Жіберу жарияланған хабарды кейінірек жеткізу үшін кезекке қою үшін құлыптауды қажет етеді. Бұл құлыптармен ешқашан дауласпау керек, бірақ олар әлі де техникалық түрде бұғатталуы мүмкін.
  • Envoy жүйе қатесі ағынына журнал жазғанда (стандартты қате), ол бүкіл процесте құлыпты алады. Тұтастай алғанда, Envoy жергілікті ағаш кесу өнімділік тұрғысынан қорқынышты болып саналады, сондықтан оны жақсартуға көп көңіл бөлінбеді.
  • Бірнеше басқа кездейсоқ құлыптар бар, бірақ олардың ешқайсысы өнімділік үшін маңызды емес және ешқашан дау туғызбауы керек.

Жергілікті жады

Envoy негізгі жіптің жауапкершілігін жұмысшы жіптің жауапкершілігінен ажырататындықтан, күрделі өңдеуді негізгі жіпте орындауға, содан кейін әрбір жұмысшы жіпке жоғары параллельді түрде қамтамасыз етуге болатын талап бар. Бұл бөлімде Envoy Thread Local Storage (TLS) жоғары деңгейде сипатталады. Келесі бөлімде мен оның кластерді басқару үшін қалай қолданылатынын сипаттаймын.
[Аударма] Envoy жіп үлгісі

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

Envoy's TLS (Thread local storage) жүйесі келесідей жұмыс істейді:

  • Негізгі ағында жұмыс істейтін код бүкіл процесс үшін TLS ұяшығын бөле алады. Бұл абстракцияланған болса да, іс жүзінде ол O(1) қатынасын қамтамасыз ететін вектордың индексі болып табылады.
  • Негізгі ағын өз ұясына ерікті деректерді орната алады. Бұл орындалғанда, деректер әрбір жұмысшы ағынына қалыпты оқиға циклінің оқиғасы ретінде жарияланады.
  • Жұмысшы ағындары TLS ұяшығынан оқи алады және сол жерде қол жетімді кез келген жергілікті ағын деректерін ала алады.

Бұл өте қарапайым және керемет қуатты парадигма болса да, ол RCU (оқу-көшіру-жаңарту) блоктау тұжырымдамасына өте ұқсас. Негізінде, жұмыс ағындары жұмыс істеп тұрған кезде TLS ұяшықтарында ешбір деректер өзгерістерін көрмейді. Өзгеріс жұмыс оқиғалары арасындағы демалыс кезеңінде ғана болады.

Елші мұны екі түрлі жолмен пайдаланады:

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

Кластерді жаңарту ағыны

Бұл бөлімде мен кластерді басқару үшін TLS (Thread local storage) қалай пайдаланылатынын сипаттаймын. Кластерді басқару xDS API және/немесе DNS өңдеуді, сондай-ақ денсаулықты тексеруді қамтиды.
[Аударма] Envoy жіп үлгісі

Кластер ағынын басқару келесі компоненттер мен қадамдарды қамтиды:

  1. Кластер менеджері барлық белгілі кластердің жоғары ағындарын, Cluster Discovery Service (CDS) API, Secret Discovery Service (SDS) және Endpoint Discovery Service (EDS) API интерфейстерін, DNS және белсенді сыртқы тексерулерді басқаратын Envoy ішіндегі құрамдас болып табылады. Ол табылған хосттарды, сондай-ақ денсаулық күйін қамтитын әрбір жоғарғы кластердің "соңында дәйекті" көрінісін жасауға жауап береді.
  2. Денсаулық тексерушісі белсенді денсаулық тексеруін орындайды және денсаулық күйінің өзгерістерін кластер басқарушысына хабарлайды.
  3. CDS (Cluster Discovery Service) / SDS (Secret Discovery Service) / EDS (Endpoint Discovery Service) / DNS кластер мүшелігін анықтау үшін орындалады. Күй өзгерісі кластер басқарушысына қайтарылады.
  4. Әрбір жұмысшы ағыны оқиғалар циклін үздіксіз орындайды.
  5. Кластер басқарушысы кластердің күйі өзгергенін анықтағанда, ол кластер күйінің тек оқуға арналған жаңа суретін жасайды және оны әрбір жұмысшы ағынына жібереді.
  6. Келесі тыныш кезеңде жұмысшы ағыны бөлінген TLS ұяшығындағы суретті жаңартады.
  7. Жүктеуге арналған хостты анықтауы тиіс енгізу/шығару оқиғасы кезінде жүктеме балансы хост туралы ақпаратты алу үшін TLS (Thread жергілікті сақтау) ұясын сұрайды. Бұл құлыптарды қажет етпейді. Сондай-ақ, TLS жаңарту оқиғаларын іске қоса алатынын ескеріңіз, осылайша жүктеме теңестірушілері және басқа компоненттер кэштерді, деректер құрылымдарын және т.б. қайта есептей алады. Бұл осы жазбаның ауқымынан тыс, бірақ кодтың әртүрлі жерлерінде қолданылады.

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

TLS пайдаланатын басқа ішкі жүйелер

TLS (Thread local storage) және RCU (Read Copy Update) Envoy бағдарламасында кеңінен қолданылады.

Пайдалану мысалдары:

  • Орындау кезінде функционалдылықты өзгерту механизмі: Қосылған функциялардың ағымдағы тізімі негізгі ағында есептеледі. Әр жұмысшы ағынына RCU семантикасы арқылы тек оқуға арналған сурет беріледі.
  • Маршрут кестелерін ауыстыру: RDS (Маршрутты табу қызметі) ұсынған маршрут кестелері үшін маршрут кестелері негізгі ағында жасалады. Тек оқуға арналған сурет кейіннен RCU (Read Copy Update) семантикасы арқылы әрбір жұмысшы ағынына беріледі. Бұл маршрут кестелерін өзгертуді атомдық тиімді етеді.
  • HTTP тақырыбын кэштеу: Белгілі болғандай, әрбір сұрау үшін HTTP тақырыбын есептеу (әр ядроға ~25K+ RPS іске қосылғанда) өте қымбат. Өкіл орталықтан шамамен жарты секунд сайын тақырыпты есептеп, оны әрбір жұмысшыға TLS және RCU арқылы береді.

Басқа жағдайлар бар, бірақ алдыңғы мысалдар TLS не үшін қолданылатынын жақсы түсінуге мүмкіндік береді.

Белгілі өнімділік қателері

Envoy жалпы алғанда өте жақсы жұмыс істегенімен, оны өте жоғары параллельділікпен және өткізу қабілетімен пайдаланған кезде назар аударуды қажет ететін бірнеше маңызды аймақтар бар:

  • Осы мақалада сипатталғандай, қазіргі уақытта барлық жұмыс ағындары кіру журналының жады буферіне жазу кезінде құлыпты алады. Жоғары параллельділік пен жоғары өткізу қабілеттілігінде, соңғы файлға жазу кезінде тапсырыстан тыс жеткізу есебінен әрбір жұмысшы ағыны үшін кіру журналдарын пакеттеу қажет болады. Немесе, әрбір жұмысшы ағыны үшін бөлек кіру журналын жасауға болады.
  • Статистика жоғары оңтайландырылғанымен, өте жоғары параллельділік пен өткізу қабілеттілігінде жеке статистика бойынша атомдық даулар болуы мүмкін. Бұл мәселенің шешімі - орталық есептегіштерді мерзімді қалпына келтірумен жұмысшы ағынына есептегіштер. Бұл келесі постта талқыланады.
  • Өңдеу ресурстарын қажет ететін қосылымдар өте аз болатын сценарийде Envoy қолданылса, ағымдағы архитектура жақсы жұмыс істемейді. Қосылымдар жұмысшы ағындары арасында біркелкі бөлінетініне кепілдік жоқ. Бұл жұмысшы ағындары арасындағы байланыстарды алмасуға мүмкіндік беретін жұмысшы қосылымын теңдестіру арқылы шешуге болады.

Қорытынды

Envoy ағынды үлгісі дұрыс конфигурацияланбаған жағдайда ықтимал бос жады мен қосылымдар есебінен бағдарламалаудың қарапайымдылығын және жаппай параллелизмді қамтамасыз етуге арналған. Бұл модель оған өте жоғары ағындар саны мен өткізу қабілеттілігінде өте жақсы жұмыс істеуге мүмкіндік береді.
Twitter-де қысқаша айтып өткенімдей, дизайн DPDK (Data Plane Development Kit) сияқты толық пайдаланушы режиміндегі желілік стек үстінде де жұмыс істей алады, бұл әдеттегі серверлердің толық L7 өңдеуімен секундына миллиондаған сұрауларды өңдеуіне әкелуі мүмкін. Алдағы бірнеше жылда не салынатынын көру өте қызықты болады.
Соңғы қысқа түсініктеме: Менен неліктен C++ тілін Envoo тілін таңдағанымызды бірнеше рет сұрады. Себебі, бұл әлі күнге дейін осы мақалада сипатталған архитектураны құруға болатын кең таралған өнеркәсіптік деңгейдегі жалғыз тіл болып табылады. C++ барлық жобаларға немесе тіпті көптеген жобаларға сәйкес келмейтіні сөзсіз, бірақ кейбір пайдалану жағдайлары үшін ол әлі де жұмысты орындаудың жалғыз құралы болып табылады.

Кодқа сілтемелер

Интерфейстері бар файлдарға сілтемелер мен тақырыпты іске асыру осы постта талқыланады:

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

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