37,529 чытанні
37,529 чытанні

Надзейны абмен паведамленнямі ў размеркаваных сістэмах

па Aleksei8m2024/03/18
Read on Terminal Reader
Read this story w/o Javascript

Занадта доўга; Чытаць

Пабудова надзейнай, высокадаступнай, маштабуемай размеркаванай сістэмы патрабуе захавання пэўных метадаў, прынцыпаў і шаблонаў.
featured image - Надзейны абмен паведамленнямі ў размеркаваных сістэмах
Aleksei HackerNoon profile picture

Праблема падвойнага запісу

Пабудова надзейнай, высокадаступнай, маштабаванай размеркаванай сістэмы патрабуе прытрымлівання пэўных метадаў, прынцыпаў і шаблонаў. Распрацоўка такіх сістэм прадугледжвае вырашэнне мноства задач. Сярод найбольш распаўсюджаных і фундаментальных праблем - праблема двайнога запісу .


«Праблема двайнога запісу» - гэта праблема, якая ўзнікае ў размеркаваных сістэмах, у асноўным пры працы з некалькімі крыніцамі даных або базамі даных, якія неабходна сінхранізаваць. Гэта адносіцца да цяжкасцей забеспячэння таго, каб змены даных паслядоўна запісваліся ў розныя сховішчы даных, такія як базы дадзеных або кэшы, без узнікнення такіх праблем, як неадпаведнасць даных, канфлікты або вузкія месцы ў прадукцыйнасці.


Архітэктура мікрасэрвісаў і база дадзеных шаблонаў для кожнай службы прыносяць вам шмат пераваг, такіх як незалежнае разгортванне і маштабаванне, ізаляваныя збоі і патэнцыйнае павышэнне хуткасці распрацоўкі. Аднак аперацыі патрабуюць змяненняў паміж многімі мікрасэрвісамі, што прымушае вас думаць аб надзейным рашэнні для вырашэння гэтай праблемы.

Амаль рэальны прыклад

Давайце разгледзім сцэнар, у якім наш дамен прадугледжвае прыняцце заявак на пазыку, іх ацэнку, а затым адпраўку апавяшчэнняў кліентам.


У духу прынцыпу адзінай адказнасці, закона Конвея і падыходу праектавання, арыентаванага на дамен, пасля некалькіх сеансаў штурму падзей увесь дамен быў падзелены на тры паддамены з вызначанымі абмежаванымі кантэкстамі, якія маюць выразныя межы, мадэлі даменаў і ўсюдыісную мову.


Першаму даручана падрыхтоўка і складанне новых заявак на пазыку. Другая сістэма ацэньвае гэтыя заяўкі і прымае рашэнні на аснове прадстаўленых даных. Гэты працэс ацэнкі, уключаючы праверку KYC/KYB, барацьбу з махлярствам і крэдытную рызыку, можа заняць шмат часу, што патрабуе магчымасці апрацоўваць тысячы заявак адначасова. Такім чынам, гэтая функцыя была дэлегавана спецыяльнаму мікрасэрвісу з уласнай базай дадзеных, што дазваляе незалежнае маштабаванне.

Акрамя таго, гэтымі падсістэмамі кіруюць дзве розныя каманды, кожная са сваімі ўласнымі цыкламі выпуску, пагадненнямі аб узроўні абслугоўвання (SLA) і патрабаваннямі да маштабаванасці.


Нарэшце , існуе спецыялізаваная служба апавяшчэнняў для адпраўкі папярэджанняў кліентам.



Вось удакладненае апісанне асноўнага выпадку выкарыстання сістэмы:

  1. Кліент падае заяўку на крэдыт.
  2. Служба заяўкі на пазыку запісвае новую заяўку са статусам "У чаканні" і ініцыюе працэс ацэнкі, перасылаючы заяўку ў службу ацэнкі.
  3. Служба ацэнкі ацэньвае уваходную заяўку на пазыку і пасля паведамляе Службе заяўкі на пазыку аб сваім рашэнні.
  4. Пасля атрымання рашэння Служба заяўкі на пазыку адпаведным чынам абнаўляе статус заяўкі на пазыку і запускае Службу апавяшчэнняў для інфармавання кліента аб выніку.
  5. Служба апавяшчэнняў апрацоўвае гэты запыт і адпраўляе апавяшчэнні кліенту па электроннай пошце, SMS або іншым спосабам сувязі ў адпаведнасці з наладамі кліента.


На першы погляд гэта даволі простая і прымітыўная сістэма, але давайце паглыбімся ў тое, як служба заяўкі на пазыку апрацоўвае каманду падаць заяўку на пазыку.


Мы можам разгледзець два падыходы да ўзаемадзеяння сэрвісаў:

  1. First-Local-Commit-Ten-Publish: Пры такім падыходзе сэрвіс абнаўляе сваю лакальную базу дадзеных (фіксуе), а затым публікуе падзею або паведамленне для іншых сэрвісаў.

  2. First-Publish-Then-Local-Commit: Наадварот, гэты метад прадугледжвае публікацыю падзеі або паведамлення перад унясеннем змяненняў у лакальную базу дадзеных.


Абодва метады маюць свае недахопы і толькі часткова бяспечныя для сувязі ў размеркаваных сістэмах.


Гэта схема паслядоўнасці прымянення першага падыходу.


Спачатку лакальнае фіксаванне, потым публікацыя


У гэтым сцэнары Служба заяўкі на пазыку выкарыстоўвае падыход "Спачатку лакальнае прыняцце, потым публікацыя" , дзе яна спачатку фіксуе транзакцыю, а потым спрабуе адправіць апавяшчэнне ў іншую сістэму. Аднак гэты працэс успрымальны да збою, калі, напрыклад, ёсць праблемы з сеткай, служба ацэнкі недаступная або служба падачы заявак на пазыку сутыкаецца з памылкай "Не хапае памяці" (OOM) і выходзіць з ладу. У такіх выпадках паведамленне будзе страчана, а Ацэнка будзе пакінута без паведамлення аб новай заяўцы на крэдыт, калі не будуць прыняты дадатковыя меры.


І другі.

Спачатку публікацыя, потым лакальнае фіксаванне
У сцэнарыі "Спачатку публікацыя-потым-лакальнае прыняцце" Служба падачы заявак на пазыку сутыкаецца з больш значнымі рызыкамі. Ён можа інфармаваць службу ацэнкі аб новым дадатку, але не можа захаваць гэта абнаўленне лакальна з-за такіх праблем, як праблемы з базай дадзеных, памылкі памяці або памылкі кода. Такі падыход можа прывесці да значных неадпаведнасцей у дадзеных, што можа выклікаць сур'ёзныя праблемы ў залежнасці ад таго, як Служба разгляду пазык апрацоўвае ўваходныя заяўкі.


Такім чынам, мы павінны вызначыць рашэнне, якое прапануе надзейны механізм для публікацыі падзей знешнім спажыўцам. Але перш чым паглыбляцца ў патэнцыйныя рашэнні, мы павінны спачатку ўдакладніць тыпы гарантый дастаўкі паведамленняў, дасягальныя ў размеркаваных сістэмах.

Гарантыі дастаўкі паведамленняў

Мы можам дасягнуць чатырох тыпаў гарантый.

  1. Без гарантый
    Няма гарантыі, што паведамленне будзе дастаўлена да месца прызначэння. Падыход «Спачатку лакальнае фіксаванне-потым-публікацыя» якраз пра гэта. Спажыўцы могуць атрымліваць паведамленні адзін раз, некалькі разоў або наогул ніколі.

  2. Максімум аднаразовая дастаўка
    Дастаўка не больш за адзін раз азначае, што паведамленне будзе дастаўлена да месца прызначэння не больш за 1 раз. Падыход First-Local-Commit-Ten-Publish можа быць рэалізаваны такім чынам, а таксама з палітыкай паўторных спроб са значэннем адзін.

  3. Прынамсі адна дастаўка\Спажыўцы атрымаюць і апрацуюць кожнае паведамленне, але могуць атрымаць адно і тое ж паведамленне некалькі разоў.

  4. Дастаўка роўна адзін раз\Дастаўка роўна адзін раз азначае, што спажывец атрымае паведамленне фактычна адзін раз.
    Тэхнічна гэта магчыма дасягнуць з дапамогай транзакцый Кафкі і канкрэтнай ідэмпэнтнай рэалізацыі вытворцы і спажыўца.


У большасці выпадкаў дастаўка «хаця б раз» гарантуе вырашэнне многіх праблем, забяспечваючы дастаўку паведамленняў хаця б адзін раз, але спажыўцы павінны быць ідэмпэнтнымі. Аднак, улічваючы непазбежныя збоі ў сетцы, уся спажывецкая логіка павінна быць ідэмпэнтнай, каб пазбегнуць апрацоўкі дублікатаў паведамленняў, незалежна ад гарантый вытворцы. Такім чынам, гэта патрабаванне не столькі недахоп, колькі адлюстроўвае рэчаіснасць.

Рашэнні

Існуе мноства рашэнняў гэтай праблемы, якія маюць свае перавагі і недахопы.

Двухфазная фіксацыя

Згодна з Вікіпедыяй, Two-Phase Commit (2PC) - гэта пратакол размеркаваных транзакцый, які выкарыстоўваецца ў інфарматыцы і сістэмах кіравання базамі дадзеных для забеспячэння паслядоўнасці і надзейнасці размеркаваных транзакцый. Ён прызначаны для сітуацый, калі некалькі рэсурсаў (напрыклад, баз дадзеных) павінны ўдзельнічаць у адной транзакцыі, і ён гарантуе, што або ўсе яны здзяйсняюць транзакцыю, або ўсе яны перапыняюць яе, падтрымліваючы тым самым узгодненасць дадзеных. Гучыць менавіта тое, што нам трэба, але двухфазная фіксацыя мае некалькі недахопаў:

  • Калі адзін з рэсурсаў-удзельнікаў перастае рэагаваць або адчувае збой, увесь працэс можа быць заблакіраваны, пакуль праблема не будзе вырашана. Гэта можа прывесці да магчымых праблем з прадукцыйнасцю і даступнасцю.
  • Two-Phase Commit не забяспечвае ўбудаваныя механізмы адмоваўстойлівасці. Ён абапіраецца на знешнія механізмы або ручное ўмяшанне для ліквідацыі збояў.
  • Не ўсе сучасныя базы даных падтрымліваюць двухфазную фіксацыю.

Агульная база дадзеных

Найбольш відавочным рашэннем для архітэктуры мікрасэрвісаў з'яўляецца прымяненне шаблону (або нават часам антышаблона) - агульнай базы дадзеных. Гэты падыход вельмі інтуітыўна зразумелы, калі вам патрэбна ўзгодненасць транзакцый у некалькіх табліцах у розных базах дадзеных, проста выкарыстоўвайце адну агульную базу дадзеных для гэтых мікрасэрвісаў.


Недахопы гэтага падыходу ўключаюць у сябе ўвядзенне адзінай кропкі адмовы, забарону незалежнаму маштабаванню базы дадзеных і абмежаванне магчымасці выкарыстання розных рашэнняў базы дадзеных, найбольш прыдатных для канкрэтных патрабаванняў і выпадкаў выкарыстання. Акрамя таго, для падтрымкі такой формы размеркаванай транзакцыі спатрэбяцца мадыфікацыі кодавых баз мікрасэрвісаў.

Выходныя транзакцыі

Транзакцыйная выходная скрыня - гэта шаблон праектавання, які выкарыстоўваецца ў размеркаваных сістэмах для забеспячэння надзейнага распаўсюджвання паведамленняў, нават ва ўмовах ненадзейных сістэм абмену паведамленнямі. Гэта ўключае ў сябе захаванне падзей у спецыяльнай табліцы "OutboxEvents" у той жа транзакцыі, што і сама аперацыя. Гэты падыход добра спалучаецца са ўласцівасцямі ACID рэляцыйных баз даных. Наадварот, многія базы дадзеных No-SQL не цалкам падтрымліваюць уласцівасці ACID, выбіраючы замест гэтага прынцыпы тэарэмы CAP і філасофіі BASE, якія аддаюць прыярытэт даступнасці і канчатковай паслядоўнасці перад строгай паслядоўнасцю.


Транзакцыйная выходная скрыня забяспечвае хаця б адзін раз гарантыю і можа быць рэалізавана з дапамогай некалькіх падыходаў:

  1. Хвасты часопіса транзакцый

  2. Выдавец апытання


Падыход да адліку журналаў транзакцый прадугледжвае выкарыстанне спецыяльных рашэнняў для базы дадзеных, такіх як CDC (Change Data Capture). Асноўныя недахопы гэтага падыходу:

  • Спецыяльныя рашэнні для базы даных

  • Павялічаная затрымка з-за асаблівасцяў рэалізацыі CDC


Іншы метад - Polling Publisher , які палягчае разгрузку выходных скрынь шляхам апытання табліцы выходных. Галоўным недахопам гэтага падыходу з'яўляецца магчымасць павелічэння нагрузкі на базу дадзеных, што можа прывесці да росту выдаткаў. Акрамя таго, не ўсе базы дадзеных No-SQL падтрымліваюць эфектыўныя запыты для пэўных сегментаў дакумента. Такім чынам, выманне цэлых дакументаў можа прывесці да зніжэння прадукцыйнасці.


Вось невялікая схема паслядоўнасці, якая тлумачыць, як гэта працуе.


Слухай сябе

Асноўная праблема шаблону Transactional Outbox заключаецца ў яго залежнасці ад уласцівасцей ACID базы дадзеных. Гэта можа быць проста ў тыповых базах дадзеных OLTP, але стварае праблемы ў сферы NoSQL. Каб вырашыць гэтую праблему, магчымым рашэннем з'яўляецца выкарыстанне журнала дапаўненняў (напрыклад, Kafka) адразу пасля пачатку апрацоўкі запыту.


Замест таго, каб непасрэдна апрацоўваць каманду «адправіць заяўку на пазыку», мы неадкладна адпраўляем яе ва ўнутраную тэму Kafka, а потым вяртаем кліенту вынік «прыняты». Аднак, паколькі вельмі верагодна, што каманду яшчэ трэба апрацаваць, мы не можам адразу паведаміць кліенту аб выніку. Каб кіраваць гэтай канчатковай узгодненасцю, мы можам выкарыстоўваць такія метады, як доўгае апытанне, апытанне па ініцыятыве кліента, аптымістычныя абнаўленні карыстацкага інтэрфейсу або выкарыстанне WebSockets або падзей, адпраўленых серверам, для апавяшчэнняў. Аднак гэта зусім асобная тэма, таму вернемся да нашай першапачатковай тэмы.


Мы адправілі паведамленне на ўнутраную кафкаўскую тэму. Затым служба заяўкі на пазыку прымае гэтае паведамленне — тую ж каманду, якую яна атрымала ад кліента — і пачынае апрацоўку. Па-першае, ён выконвае некаторую бізнес-логіку; толькі пасля паспяховага выканання гэтай логікі і захавання вынікаў, ён публікуе новыя паведамленні на публічную тэму Кафкі.


Давайце паглядзім на псеўдакод.


 public async Task HandleAsync(SubmitLoanApplicationCommand command, ...) { //First, process business logic var loanApplication = await _loanApplicationService.HandleCommandAsync(command, ...); //Then, send new events to public Kafka topic producer.Send(new LoanApplicationSubmittedEvent(loanApplication.Id)); //Then, commit offset consumer.Commit(); }


Што рабіць, калі апрацоўка бізнес-логікі дае збой? Не турбуйцеся, паколькі зрушэнне яшчэ не было зроблена, паведамленне будзе адпраўлена паўторна.


Што рабіць, калі адпраўка новых падзей у Кафку не атрымаецца? Не турбуйцеся, паколькі бізнес-логіка ідэмпэнтная, яна не створыць дублікат заяўкі на крэдыт. Замест гэтага ён паспрабуе паўторна адправіць паведамленні ў публічную тэму Кафкі.


Што рабіць, калі паведамленні адпраўляюцца Kafka, але фіксацыя зрушэння не ўдаецца? Не турбуйцеся, паколькі бізнес-логіка ідэмпэнтная, яна не створыць дублікат заяўкі на крэдыт. Замест гэтага ён паўторна адправіць паведамленні ў публічную тэму Kafka і спадзяецца, што на гэты раз фіксацыя зрушэння ўдасца.


Галоўныя недахопы гэтага падыходу ўключаюць дадатковую складанасць, звязаную з новым стылем праграмавання, канчатковую паслядоўнасць (паколькі кліент не адразу даведаецца пра вынік) і патрабаванне, каб уся бізнес-логіка была ідэмпэнтнай.

Пошук падзей

Што такое пошук падзей і як гэта можна тут прымяніць? Пошук падзей - гэта архітэктурны шаблон праграмнага забеспячэння, які выкарыстоўваецца для мадэлявання стану сістэмы шляхам фіксацыі ўсіх змяненняў у яе дадзеных у выглядзе серыі нязменных падзей. Гэтыя падзеі ўяўляюць сабой факты або змены стану і служаць адзінай крыніцай праўды для бягучага стану сістэмы. Такім чынам, тэхнічна, укараніўшы сістэму пошуку падзей, мы ўжо маем усе падзеі ў EventStore, і спажыўцы могуць выкарыстоўваць гэтую EventStore як адзіную крыніцу праўды аб тым, што адбылося. Няма неабходнасці ў спецыяльным рашэнні базы дадзеных для адсочвання ўсіх змяненняў або праблем наконт упарадкавання, адзіная праблема заключаецца ў чытанні, бо для таго, каб атрымаць фактычны стан аб'екта, неабходна прайграць усе падзеі.

Заключэнне

У гэтым артыкуле мы разгледзелі некалькі падыходаў для стварэння надзейнага абмену паведамленнямі ў размеркаваных сістэмах. Ёсць некалькі рэкамендацый, якія мы маглі б разгледзець пры стварэнні сістэм з такімі характарыстыкамі

  1. Заўсёды развівайце ідэмпэнтных спажыўцоў, бо збой сеткі непазбежны.
  2. Уважліва выкарыстоўвайце First-Local-Commit-Ten-Publish з дакладным разуменнем гарантыйных патрабаванняў.
  3. Ніколі не выкарыстоўвайце падыход "Спачатку публікацыя-потым-лакальна-фіксацыя" , бо гэта можа прывесці да сур'ёзнай неадпаведнасці дадзеных у вашай сістэме.
  4. Калі існуючае рашэнне аб выбары базы дадзеных, хутчэй за ўсё, можа змяніцца або тэхнічная стратэгія прадугледжвае выбар найлепшага рашэння для захоўвання дадзеных — не стварайце агульныя бібліятэкі шляхам прывязкі да рашэнняў базы дадзеных, такіх як CDC .
  5. Выкарыстоўвайце падыход Transactional Outbox як стандартнае рашэнне для дасягнення хаця б адной гарантыі.
  6. Разгледзьце магчымасць выкарыстання падыходу "Слухайце сябе", калі выкарыстоўваюцца базы дадзеных без SQL.


У наступны раз мы разгледзім больш практычны прыклад рэалізацыі транзакцыйнай выходнай скрыні. Глядзіце

вы!


Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks