[Котормо] Элчи жип модели

Макаланын котормосу: Элчи жип модели - https://blog.envoyproxy.io/envoy-threading-model-a8d44b922310

Мен бул макаланы абдан кызыктуу деп таптым жана Элчи көбүнчө "истионун" бөлүгү катары же жөн гана кубернеттердин "кирүүчү контроллери" катары колдонулгандыктан, көпчүлүк адамдар аны менен, мисалы, типтүү менен түз өз ара аракеттенишпейт. Nginx же Haproxy орнотуулары. Бирок, бир нерсе сынып калса, анын ичинен кантип иштээрин түшүнүп алсак жакшы болмок. Мүмкүн болушунча текстти орусчага которууга аракет кылдым, анын ичинде муну карап кыйналгандар үчүн оригиналдарды кашаага калтырдым; кош келиңиз.

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

Envoy жөнүндө мага эң көп түшкөн техникалык суроолордун бири - ал колдонгон жип моделинин төмөнкү деңгээлдеги сүрөттөмөсүн суроо. Бул постто мен Envoy кантип жиптерге туташуулар картасын түзөрүн, ошондой эле Thread Local Storage тутумунун ичинде кодду параллелдүү жана жогорку натыйжалуу кылуу үчүн колдонгонун сүрөттөп берем.

Жиптерге сереп салуу

[Котормо] Элчи жип модели

Элчи агымдын үч түрдүү түрүн колдонот:

  • Негизги: Бул жип процессти баштоону жана токтотууну, XDS (xDiscovery Service) API'нин бардык иштетилишин, анын ичинде DNS, ден соолукту текшерүү, жалпы кластерди жана иштөө убактысын башкаруу, статистиканы баштапкы абалга келтирүү, башкаруу жана жалпы процессти башкаруу - Linux сигналдарын өчүрүү жана башкалар Бул жипте болот асинхрондуу жана "бөгөтсүз". Жалпысынан алганда, негизги жип иштетүү үчүн көп сандагы CPU талап кылбаган бардык критикалык функционалдык процесстерди координациялайт. Бул башкаруу кодунун көпчүлүгүн бир жиптүү сыяктуу жазууга мүмкүндүк берет.
  • Жумушчу: Демейки боюнча, Элчи тутумдагы ар бир аппараттык жип үчүн жумушчу жипти түзөт, муну параметр аркылуу башкарууга болот --concurrency. Ар бир жумушчу жип жазуу учурунда (29-июль, 2017-ж.) ар бир угуучуну угууга жооптуу болгон "бөгөтсүз" окуя циклин иштетет, угуучунун эч кандай бөлүктөрү жок, жаңы байланыштарды кабыл алуу, чыпка стектерин түзүү; туташуу, жана туташуунун иштөө мөөнөтүнүн ичинде бардык киргизүү/чыгарма (IO) операцияларын иштетүү. Дагы бир жолу, бул көпчүлүк байланышты башкаруу кодун бир жип сыяктуу жазууга мүмкүндүк берет.
  • Файлды тазалоочу: Элчи жазган ар бир файл, негизинен журналдарга кирүү, учурда көз карандысыз бөгөттөөчү жипке ээ. Бул файлдык система тарабынан кэштелген файлдарга жазуу колдонулуп жатканда да байланыштуу O_NONBLOCK кээде тосулуп калышы мүмкүн (үшкүрөт). Жумушчу жиптер файлга жазуу керек болгондо, маалыматтар эстутумдагы буферге жылдырылып, акыры жип аркылуу тазаланат. файлды тазалоо. Бул эстутум буферин толтурууга аракет кылып жатканда техникалык жактан бардык жумушчу жиптери бирдей кулпуну бөгөттөй турган коддун бир аймагы.

Туташуу менен иштөө

Жогоруда кыскача талкуулангандай, бардык жумушчу жиптер бардык угуучуларды эч кандай сыныксыз угат. Ошентип, ядро ​​​​кабыл алынган розеткаларды жумушчу жиптерге жагымдуу түрдө жөнөтүү үчүн колдонулат. Заманбап ядролор көбүнчө бул жагынан абдан жакшы, алар бир эле розеткада угуп жаткан башка жиптерди колдоно баштаардан мурун жипти толтурууга аракет кылуу үчүн киргизүү/чыгарма (IO) артыкчылыктуулугун жогорулатуу сыяктуу функцияларды колдонушат, ошондой эле тегерек робинди колдонбойт. ар бир суроону иштетүү үчүн кулпулоо (Spinlock).
Жумушчу жипте байланыш кабыл алынгандан кийин, ал жиптен эч качан кетпейт. Байланыштын андан аркы бардык процесстери толугу менен жумушчу жипинде, анын ичинде ар кандай багыттоо жүрүм-турумунда жүргүзүлөт.

Бул бир нече маанилүү кесепеттерге ээ:

  • Элчидеги бардык байланыш бассейндери жумушчу жипке дайындалган. Ошентип, HTTP/2 туташуу бассейндери бир эле учурда ар бир жогорудагы хост менен бир гана туташууну түзсө да, төрт жумушчу жип бар болсо, туруктуу абалда ар бир жогорудагы хост үчүн төрт HTTP/2 туташуусу болот.
  • Envoy мындай иштешинин себеби, бардыгын бир жумушчу жипте сактоо менен дээрлик бардык кодду бөгөттөлбөй жана бир жип сыяктуу жазууга болот. Бул дизайн көптөгөн коддорду жазууну жеңилдетет жана жумушчу жиптердин дээрлик чексиз санына укмуштуудай жакшы масштабдалат.
  • Бирок, негизги нерселердин бири - эс тутумунун бассейни жана туташуу натыйжалуулугу жагынан алганда, конфигурациялоо чындыгында абдан маанилүү. --concurrency. Керектүүдөн көп жумушчу жиптерге ээ болуу эстутумду текке кетирет, көбүрөөк бош туташууларды жаратат жана туташууну бириктирүү ылдамдыгын азайтат. Lyftте, биздин өкүлдүн каптал контейнерлери өтө төмөн мезгилде иштешет, андыктан аткаруу алардын жанында отурган кызматтарга болжол менен дал келет. Биз Envoy прокси катары максималдуу мезгилде гана иштетебиз.

Бөгөт коюу деген эмнени билдирет?

Негизги жана жумушчу жиптер кантип иштээрин талкуулоодо "бөгөт кылбоо" термини буга чейин бир нече жолу колдонулган. Бардык код эч качан бөгөттөлбөйт деген божомол менен жазылган. Бирок, бул толугу менен туура эмес (эмне толугу менен туура эмес?).

Элчи бир нече узун процесс кулпуларын колдонот:

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

Жергиликтүү сактагыч

Элчи негизги жиптин жоопкерчилигин жумушчу жиптин жоопкерчилигинен ажыраткандыктан, негизги жипте комплекстүү иштетүүнү жасап, андан кийин ар бир жумушчу жипке жогорку деңгээлде бирдей шартта берилиши керек деген талап бар. Бул бөлүмдө Envoy Thread Local Storage (TLS) жогорку деңгээлде сүрөттөлөт. Кийинки бөлүмдө мен кластерди башкаруу үчүн кандайча колдонуларын сүрөттөп берем.
[Котормо] Элчи жип модели

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

Элчинин TLS (Thread жергиликтүү сактагыч) системасы төмөнкүдөй иштейт:

  • Негизги жипте иштеген код бүт процесс үчүн TLS уячасын бөлүп бере алат. Бул абстракцияланган болсо да, иш жүзүндө бул O(1) мүмкүнчүлүгүн камсыз кылуучу векторго индекс.
  • Негизги жип өз уясына каалаган маалыматтарды орното алат. Бул жасалганда, маалыматтар ар бир жумушчу жипке кадимки окуя циклинин окуясы катары жарыяланат.
  • Жумушчу жиптери TLS слотунан окуп, ал жердеги бардык жип-локалдык маалыматтарды ала алат.

Бул абдан жөнөкөй жана укмуштуудай күчтүү парадигма болсо да, ал RCU (Окуу-Көчүрүү-Жаңыртуу) бөгөттөө түшүнүгүнө абдан окшош. Негизи, жумушчу жиптер жумуш жүрүп жатканда TLS уячаларында эч кандай маалымат өзгөрүүсүн көрбөйт. Өзгөртүү иш окуялардын ортосундагы эс алуу мезгилинде гана болот.

Элчи муну эки башка жол менен колдонот:

  • Ар бир жумушчу жипте ар кандай маалыматтарды сактоо менен, маалыматтарга эч кандай бөгөт коюусуз кирүүгө болот.
  • Ар бир жумушчу жипте окуу үчүн гана режимде глобалдык маалыматтарга жалпы көрсөткүчтү сактоо менен. Ошентип, ар бир жумушчу жиптин маалымат шилтемеси бар, аны жумуш иштеп жатканда азайтууга болбойт. Бардык жумушчулар тынчып, жаңы бөлүшүлгөн маалыматтарды жүктөгөндө гана эски маалыматтар жок кылынат. Бул RCU менен окшош.

Кластерди жаңыртуу

Бул бөлүмдө мен TLS (Thread локалдык сактагычы) кластерди башкаруу үчүн кандайча колдонуларын сүрөттөп берем. Кластерди башкаруу xDS API жана/же DNS иштетүүнү, ошондой эле ден соолукту текшерүүнү камтыйт.
[Котормо] Элчи жип модели

Кластердик агымды башкаруу төмөнкү компоненттерди жана кадамдарды камтыйт:

  1. Кластер менеджери Элчи ичиндеги бардык белгилүү кластердик агымдарды, Cluster Discovery Service (CDS) API, Secret Discovery Service (SDS) жана Endpoint Discovery Service (EDS) API'лерин, DNSти жана активдүү тышкы текшерүүлөрдү башкарган компонент. Ал табылган хостторду, ошондой эле ден соолук абалын камтыган ар бир жогорудагы кластердин "акыры ырааттуу" көрүнүшүн түзүүгө жооптуу.
  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) Элчиде кеңири колдонулат.

колдонуу мисалдары:

  • Аткаруу учурунда функцияны өзгөртүү механизми: Иштетилген функциялардын учурдагы тизмеси негизги жипте эсептелет. Ар бир жумушчу жипке RCU семантикасын колдонуу менен окуу үчүн гана сүрөт берилет.
  • Маршруттук таблицаларды алмаштыруу: RDS (Route Discovery Service) тарабынан берилген маршруттук таблицалар үчүн маршруттук таблицалар негизги жипте түзүлөт. Окуу үчүн гана сүрөт кийинчерээк RCU (Read Copy Update) семантикасын колдонуу менен ар бир жумушчу жипке берилет. Бул маршруттук таблицаларды өзгөртүүнү атомдук жактан натыйжалуу кылат.
  • HTTP башын кэштөө: Көрүнүп тургандай, ар бир суроо үчүн HTTP башын эсептөө (бир ядродо ~25K+ RPS иштеп жатканда) абдан кымбатка турат. Элчи борбордон башты болжол менен ар бир жарым секундада эсептейт жана аны ар бир жумушчуга TLS жана RCU аркылуу берет.

Башка учурлар да бар, бирок мурунку мисалдар TLS эмне үчүн колдонуларын жакшы түшүнүшү керек.

Белгилүү аткаруу кемчиликтери

Элчи жалпысынан абдан жакшы иштегени менен, ал өтө жогорку шайкештик жана өткөрүү жөндөмдүүлүгү менен колдонулганда көңүл бурууну талап кылган бир нече көрүнүктүү тармактар ​​бар:

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

Корутунду

Envoy'дун жип модели туура конфигурацияланбаса, потенциалдуу ысырапкорчулуктун жана туташуулардын эсебинен программалоонун жөнөкөйлүгүн жана массалык параллелизмди камсыз кылуу үчүн иштелип чыккан. Бул модель абдан жогорку жип саны жана өткөрүү жөндөмдүүлүгү абдан жакшы аткарууга мүмкүндүк берет.
Твиттерде кыскача айткандай, дизайн DPDK (Data Plane Development Kit) сыяктуу толук колдонуучу режиминдеги тармактык стектин үстүндө иштей алат, натыйжада кадимки серверлер секундасына миллиондогон суроо-талаптарды толук L7 иштетүү менен иштетет. Кийинки бир нече жылда эмне курулаарын көрүү абдан кызыктуу болот.
Акыркы кыска комментарий: Менден эмне үчүн Элчи үчүн C++ тилин тандаганыбызды көп жолу сурашкан. Себеби, ал дагы эле бул постто сүрөттөлгөн архитектураны курууга мүмкүн болгон бирден-бир кеңири колдонулган өнөр жайлык тил болуп саналат. C++, албетте, бардык, ал тургай, көптөгөн долбоорлор үчүн ылайыктуу эмес, бирок кээ бир колдонуу учурлары үчүн ал дагы эле ишти бүтүрүү үчүн жалгыз курал болуп саналат.

Кодго шилтемелер

Бул постто талкууланган интерфейстери жана башын ишке ашыруулары бар файлдарга шилтемелер:

Source: www.habr.com

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