Vitalu vya ujenzi wa programu zilizosambazwa. Ukadiriaji wa pili

Tangazo

Wenzangu, katikati ya majira ya joto ninapanga kutoa mfululizo mwingine wa makala kuhusu muundo wa mifumo ya kupanga foleni: "Jaribio la VTrade" - jaribio la kuandika mfumo wa mifumo ya biashara. Mfululizo utachunguza nadharia na mazoezi ya kujenga ubadilishaji, mnada na duka. Mwishoni mwa makala, ninakualika kupiga kura kwa mada zinazokuvutia zaidi.

Vitalu vya ujenzi wa programu zilizosambazwa. Ukadiriaji wa pili

Hili ni nakala ya mwisho katika mfululizo wa programu tendaji zilizosambazwa katika Erlang/Elixir. KATIKA makala ya kwanza unaweza kupata misingi ya kinadharia ya usanifu tendaji. Makala ya pili inaonyesha mifumo ya msingi na taratibu za kuunda mifumo kama hiyo.

Leo tutazungumzia masuala ya maendeleo ya msingi wa kanuni na miradi kwa ujumla.

Shirika la huduma

Katika maisha halisi, wakati wa kuendeleza huduma, mara nyingi unapaswa kuchanganya mifumo kadhaa ya mwingiliano katika mtawala mmoja. Kwa mfano, huduma ya watumiaji, ambayo hutatua tatizo la kudhibiti wasifu wa mtumiaji wa mradi, lazima ijibu maombi ya req-resp na kuripoti masasisho ya wasifu kupitia pub-sub. Kesi hii ni rahisi sana: nyuma ya ujumbe kuna kidhibiti kimoja kinachotekelezea mantiki ya huduma na kuchapisha masasisho.

Hali inakuwa ngumu zaidi tunapohitaji kutekeleza huduma iliyosambazwa inayostahimili hitilafu. Wacha tufikirie kuwa mahitaji ya watumiaji yamebadilika:

  1. sasa huduma inapaswa kushughulikia maombi kwenye nodi 5 za nguzo,
  2. kuwa na uwezo wa kufanya kazi za usindikaji wa usuli,
  3. na pia kuwa na uwezo wa kudhibiti orodha za usajili kwa masasisho ya wasifu.

Maoni: Hatuzingatii suala la uhifadhi thabiti na urudiaji wa data. Wacha tuchukue kuwa maswala haya yametatuliwa mapema na mfumo tayari una safu ya uhifadhi inayotegemewa na hatari, na washughulikiaji wana njia za kuingiliana nayo.

Maelezo rasmi ya huduma ya watumiaji yamekuwa ngumu zaidi. Kwa mtazamo wa mtayarishaji programu, mabadiliko ni machache kutokana na matumizi ya ujumbe. Ili kukidhi hitaji la kwanza, tunahitaji kusanidi kusawazisha katika sehemu ya kubadilishana ya req-resp.

Mahitaji ya kuchakata kazi za usuli hutokea mara kwa mara. Kwa watumiaji, hii inaweza kuwa kuangalia hati za watumiaji, kuchakata medianuwai zilizopakuliwa, au kusawazisha data na mitandao ya kijamii. mitandao. Kazi hizi zinahitaji kusambazwa kwa namna fulani ndani ya nguzo na maendeleo ya utekelezaji kufuatiliwa. Kwa hiyo, tuna chaguo mbili za ufumbuzi: ama kutumia template ya usambazaji wa kazi kutoka kwa makala iliyotangulia, au, ikiwa haifai, andika mpangilio wa kazi maalum ambayo itasimamia bwawa la wasindikaji kwa njia tunayohitaji.

Sehemu ya 3 inahitaji kiendelezi cha kiolezo cha baa-ndogo. Na kwa utekelezaji, baada ya kuunda sehemu ya kubadilishana ya baa, tunahitaji kuzindua kidhibiti cha sehemu hii ndani ya huduma yetu. Kwa hivyo, ni kana kwamba tunahamisha mantiki ya kuchakata usajili na kujiondoa kutoka kwa safu ya ujumbe hadi kwenye utekelezaji wa watumiaji.

Matokeo yake, mtengano wa tatizo ulionyesha kuwa ili kukidhi mahitaji, tunahitaji kuzindua matukio 5 ya huduma kwenye nodi tofauti na kuunda chombo cha ziada - mtawala mdogo wa pub, anayehusika na usajili.
Ili kuendesha vishikilizi 5, huna haja ya kubadilisha msimbo wa huduma. Hatua pekee ya ziada ni kuweka sheria za kusawazisha kwenye hatua ya kubadilishana, ambayo tutazungumzia baadaye kidogo.
Pia kuna utata wa ziada: kidhibiti kidogo cha baa na kipanga ratiba cha kazi maalum lazima kifanye kazi katika nakala moja. Tena, huduma ya ujumbe, kama ya msingi, lazima itoe utaratibu wa kuchagua kiongozi.

Uchaguzi wa kiongozi

Katika mifumo iliyosambazwa, uchaguzi wa kiongozi ni utaratibu wa kuteua mchakato mmoja unaohusika na kuratibu uchakataji uliosambazwa wa baadhi ya mzigo.

Katika mifumo ambayo haielekei kuwa kati, algorithms ya ulimwengu wote na ya makubaliano, kama vile paxos au raft, hutumiwa.
Kwa kuwa ujumbe ni wakala na kipengele cha kati, inajua kuhusu watawala wote wa huduma - viongozi wa wagombea. Ujumbe unaweza kuteua kiongozi bila kupiga kura.

Baada ya kuanza na kuunganisha kwenye hatua ya kubadilishana, huduma zote hupokea ujumbe wa mfumo #'$leader'{exchange = ?EXCHANGE, pid = LeaderPid, servers = Servers}. Kama LeaderPid sanjari na pid mchakato wa sasa, inateuliwa kama kiongozi, na orodha Servers inajumuisha nodi zote na vigezo vyake.
Kwa sasa mpya inaonekana na nodi ya nguzo ya kazi imekatwa, watawala wote wa huduma hupokea #'$slave_up'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts} ΠΈ #'$slave_down'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts} ipasavyo.

Kwa njia hii, vipengele vyote vinafahamu mabadiliko yote, na nguzo imehakikishiwa kuwa na kiongozi mmoja wakati wowote.

Waamuzi

Ili kutekeleza michakato ngumu ya usindikaji iliyosambazwa, na pia katika shida za kuboresha usanifu uliopo, ni rahisi kutumia waamuzi.
Ili usibadilishe msimbo wa huduma na kutatua, kwa mfano, matatizo ya usindikaji wa ziada, uelekezaji au ujumbe wa magogo, unaweza kuwezesha mtoaji wa wakala kabla ya huduma, ambayo itafanya kazi yote ya ziada.

Mfano wa kawaida wa uboreshaji wa sehemu ndogo ya baa ni programu iliyosambazwa yenye msingi wa biashara ambayo huzalisha matukio ya sasisho, kama vile mabadiliko ya bei kwenye soko, na safu ya ufikiaji - Seva za N ambazo hutoa API ya soketi ya wavuti kwa wateja wa wavuti.
Ukiamua moja kwa moja, basi huduma kwa wateja inaonekana kama hii:

  • mteja huanzisha miunganisho na jukwaa. Kwa upande wa seva ambayo inakomesha trafiki, mchakato unazinduliwa ili kuhudumia muunganisho huu.
  • Katika muktadha wa mchakato wa huduma, idhini na usajili wa sasisho hufanyika. Mchakato huita njia ya kujiandikisha kwa mada.
  • Mara tu tukio linapotolewa kwenye kernel, huwasilishwa kwa michakato ya kuhudumia miunganisho.

Hebu tufikirie kuwa tuna watu 50000 wanaofuatilia mada ya "habari". Wasajili wanasambazwa sawasawa katika seva 5. Kama matokeo, kila sasisho, likifika mahali pa kubadilishana, litaiga mara 50000: mara 10000 kwenye kila seva, kulingana na idadi ya waliojiandikisha juu yake. Sio mpango mzuri sana, sawa?
Ili kuboresha hali hiyo, hebu tuanzishe proksi ambayo ina jina sawa na sehemu ya kubadilishana. Msajili wa jina la kimataifa lazima awe na uwezo wa kurudisha mchakato wa karibu kwa jina, hii ni muhimu.

Hebu tuzindue proksi hii kwenye seva za safu ya ufikiaji, na michakato yetu yote inayohudumia api ya websocket itajisajili kwayo, na sio sehemu ya kubadilishana ya pub-sub kwenye kernel. Wakala hujiandikisha kwa msingi tu katika kesi ya usajili wa kipekee na kunakili ujumbe unaoingia kwa watumiaji wake wote.
Kama matokeo, ujumbe 5 utatumwa kati ya kernel na seva za ufikiaji, badala ya 50000.

Kuelekeza na kusawazisha

Req-Resp

Katika utekelezaji wa sasa wa ujumbe, kuna mikakati 7 ya usambazaji wa ombi:

  • default. Ombi linatumwa kwa vidhibiti vyote.
  • round-robin. Maombi yanaorodheshwa na kusambazwa kwa mzunguko kati ya vidhibiti.
  • consensus. Watawala wanaotumikia huduma wamegawanywa katika viongozi na watumwa. Maombi yanatumwa kwa kiongozi pekee.
  • consensus & round-robin. Kikundi kina kiongozi, lakini maombi yanasambazwa kati ya wanachama wote.
  • sticky. Chaguo za kukokotoa za heshi huhesabiwa na kupewa kidhibiti maalum. Maombi yanayofuata na sahihi hii yanaenda kwa kidhibiti sawa.
  • sticky-fun. Wakati wa kuanzisha sehemu ya kubadilishana, kazi ya kukokotoa heshi kwa sticky kusawazisha.
  • fun. Sawa na kufurahisha-nata, ni wewe tu unaweza kuielekeza kwingine, kuikataa au kuichakata mapema.

Mkakati wa usambazaji huwekwa wakati sehemu ya kubadilishana imeanzishwa.

Mbali na kusawazisha, utumaji ujumbe hukuruhusu kutambulisha huluki. Wacha tuangalie aina za vitambulisho kwenye mfumo:

  • Lebo ya muunganisho. Inakuruhusu kuelewa ni kwa njia gani matukio yalikuja. Inatumika wakati mchakato wa kidhibiti unaunganishwa kwenye sehemu moja ya kubadilishana, lakini kwa vitufe tofauti vya kuelekeza.
  • Lebo ya huduma. Hukuruhusu kuchanganya vidhibiti katika vikundi kwa huduma moja na kupanua uwezo wa uelekezaji na kusawazisha. Kwa muundo wa req-resp, uelekezaji ni wa mstari. Tunatuma ombi kwa hatua ya kubadilishana, kisha huipitisha kwa huduma. Lakini ikiwa tunahitaji kugawanya washughulikiaji katika vikundi vya mantiki, basi kugawanyika kunafanywa kwa kutumia vitambulisho. Wakati wa kubainisha lebo, ombi litatumwa kwa kikundi maalum cha watawala.
  • Ombi la lebo. Inakuruhusu kutofautisha kati ya majibu. Kwa kuwa mfumo wetu haulingani, ili kuchakata majibu ya huduma tunahitaji kuweza kubainisha RequestTag tunapotuma ombi. Kutoka kwake tutaweza kuelewa jibu ambalo ombi lilikuja kwetu.

Pub-ndogo

Kwa pub-sub kila kitu ni rahisi kidogo. Tuna sehemu ya kubadilishana ambapo ujumbe huchapishwa. Sehemu ya kubadilishana inasambaza ujumbe kati ya waliojiandikisha ambao wamejiandikisha kwa funguo za uelekezaji wanazohitaji (tunaweza kusema kwamba hii ni sawa na mada).

Scalability na uvumilivu wa makosa

Kuongezeka kwa mfumo kwa ujumla inategemea kiwango cha uboreshaji wa tabaka na vifaa vya mfumo:

  • Huduma hupimwa kwa kuongeza nodi za ziada kwenye nguzo na vidhibiti vya huduma hii. Wakati wa uendeshaji wa majaribio, unaweza kuchagua sera mojawapo ya kusawazisha.
  • Huduma ya utumaji ujumbe yenyewe ndani ya kundi tofauti kwa ujumla hupunguzwa ama kwa kusogeza sehemu za kubadilishana zilizopakiwa ili kutenganisha nodi za nguzo, au kwa kuongeza michakato ya proksi kwa maeneo yaliyopakiwa hasa ya nguzo.
  • Kuongezeka kwa mfumo mzima kama tabia inategemea kubadilika kwa usanifu na uwezo wa kuchanganya makundi ya mtu binafsi katika chombo cha kawaida cha mantiki.

Mafanikio ya mradi mara nyingi hutegemea unyenyekevu na kasi ya kuongeza. Utumaji ujumbe katika toleo lake la sasa hukua pamoja na programu. Hata kama tunakosa nguzo ya mashine 50-60, tunaweza kuamua shirikisho. Kwa bahati mbaya, mada ya shirikisho iko nje ya upeo wa nakala hii.

Uhifadhi

Wakati wa kuchanganua kusawazisha mzigo, tayari tulijadili upunguzaji wa vidhibiti vya huduma. Hata hivyo, ujumbe lazima pia uhifadhiwe. Katika tukio la nodi au ajali ya mashine, ujumbe unapaswa kurejesha kiotomatiki, na kwa muda mfupi iwezekanavyo.

Katika miradi yangu mimi hutumia nodi za ziada ambazo huchukua mzigo katika kesi ya kuanguka. Erlang ina utekelezaji wa hali ya kawaida ya usambazaji kwa programu za OTP. Hali iliyosambazwa hufanya ahueni ikiwa itashindwa kwa kuzindua programu iliyoshindwa kwenye nodi nyingine iliyozinduliwa hapo awali. Mchakato ni wazi; baada ya kutofaulu, programu huhamia kiotomatiki kwa nodi ya kushindwa. Unaweza kusoma zaidi kuhusu utendaji huu hapa.

Uzalishaji

Hebu tujaribu angalau kulinganisha takribani utendakazi wa rabbitmq na utumaji ujumbe wetu maalum.
nilipata matokeo rasmi majaribio ya rabbitmq kutoka kwa timu ya openstack.

Katika aya ya 6.14.1.2.1.2.2. Hati asili inaonyesha matokeo ya RPC CAST:
Vitalu vya ujenzi wa programu zilizosambazwa. Ukadiriaji wa pili

Hatutafanya mipangilio yoyote ya ziada kwa OS kernel au erlang VM mapema. Masharti ya majaribio:

  • erl opts: +A1 +sbtu.
  • Jaribio ndani ya nodi moja ya erlang inaendeshwa kwenye kompyuta ndogo na i7 ya zamani katika toleo la rununu.
  • Majaribio ya makundi hufanywa kwenye seva zilizo na mtandao wa 10G.
  • Nambari inaendesha kwenye vyombo vya docker. Mtandao katika hali ya NAT.

Nambari ya jaribio:

req_resp_bench(_) ->
  W = perftest:comprehensive(10000,
    fun() ->
      messaging:request(?EXCHANGE, default, ping, self()),
      receive
        #'$msg'{message = pong} -> ok
      after 5000 ->
        throw(timeout)
      end
    end
  ),
  true = lists:any(fun(E) -> E >= 30000 end, W),
  ok.

Hali ya 1: Jaribio linaendeshwa kwenye kompyuta ya mkononi yenye toleo la zamani la simu ya i7. Mtihani, ujumbe na huduma hutekelezwa kwenye nodi moja kwenye chombo kimoja cha Docker:

Sequential 10000 cycles in ~0 seconds (26987 cycles/s)
Sequential 20000 cycles in ~1 seconds (26915 cycles/s)
Sequential 100000 cycles in ~4 seconds (26957 cycles/s)
Parallel 2 100000 cycles in ~2 seconds (44240 cycles/s)
Parallel 4 100000 cycles in ~2 seconds (53459 cycles/s)
Parallel 10 100000 cycles in ~2 seconds (52283 cycles/s)
Parallel 100 100000 cycles in ~3 seconds (49317 cycles/s)

Hali ya 2: Nodi 3 zinazoendesha kwenye mashine tofauti chini ya docker (NAT).

Sequential 10000 cycles in ~1 seconds (8684 cycles/s)
Sequential 20000 cycles in ~2 seconds (8424 cycles/s)
Sequential 100000 cycles in ~12 seconds (8655 cycles/s)
Parallel 2 100000 cycles in ~7 seconds (15160 cycles/s)
Parallel 4 100000 cycles in ~5 seconds (19133 cycles/s)
Parallel 10 100000 cycles in ~4 seconds (24399 cycles/s)
Parallel 100 100000 cycles in ~3 seconds (34517 cycles/s)

Katika visa vyote, matumizi ya CPU hayazidi 250%

Matokeo ya

Natumai mzunguko huu hauonekani kama dampo la akili na uzoefu wangu utakuwa wa manufaa ya kweli kwa watafiti wote wa mifumo iliyosambazwa na watendaji ambao wako mwanzoni mwa ujenzi wa usanifu uliosambazwa wa mifumo yao ya biashara na wanaangalia Erlang/Elixir kwa maslahi. , lakini kuwa na shaka ni thamani ...

picha @chuttersnap

Watumiaji waliojiandikisha pekee ndio wanaweza kushiriki katika utafiti. Weka sahihitafadhali.

Je, ni mada gani ninapaswa kuzungumzia kwa undani zaidi kama sehemu ya mfululizo wa Majaribio ya VTrade?

  • Nadharia: Masoko, maagizo na muda wao: DAY, GTD, GTC, IOC, FOK, MOO, MOC, LOO, LOC

  • Kitabu cha maagizo. Nadharia na mazoezi ya kutekeleza kitabu na vikundi

  • Taswira ya biashara: Kupe, baa, maazimio. Jinsi ya kuhifadhi na jinsi ya gundi

  • Ofisi ya nyuma. Mipango na maendeleo. Ufuatiliaji wa wafanyikazi na uchunguzi wa matukio

  • API. Wacha tujue ni miingiliano gani inahitajika na jinsi ya kuzitekeleza

  • Uhifadhi wa habari: PostgreSQL, Timescale, Tarantool katika mifumo ya biashara

  • Reactivity katika mifumo ya biashara

  • Nyingine. Nitaandika kwenye maoni

Watumiaji 6 walipiga kura. Watumiaji 4 walijizuia.

Chanzo: mapenzi.com

Kuongeza maoni