Boublokken fan ferspraat applikaasjes. Twadde approximation

Meidieling

Kollega's, yn 'e midden fan' e simmer bin ik fan plan om in oare searje artikels frij te litten oer it ûntwerp fan wachtrige systemen: "The VTrade Experiment" - in besykjen om in ramt te skriuwen foar hannelsystemen. De searje sil de teory en praktyk ûndersykje fan it bouwen fan in útwikseling, feiling en winkel. Oan 'e ein fan it artikel noegje ik jo út om te stimmen foar de ûnderwerpen dy't jo it meast ynteressearje.

Boublokken fan ferspraat applikaasjes. Twadde approximation

Dit is it lêste artikel yn 'e searje oer ferspraat reaktive applikaasjes yn Erlang / Elixir. YN earste artikel jo kinne de teoretyske fûneminten fan reaktive arsjitektuer fine. Twadde artikel yllustrearret de basis patroanen en meganismen foar it bouwen fan sokke systemen.

Hjoed sille wy problemen oproppe oer ûntwikkeling fan 'e koadebasis en projekten yn it algemien.

Organisaasje fan tsjinsten

Yn it echte libben, by it ûntwikkeljen fan in tsjinst, moatte jo faaks ferskate ynteraksjepatroanen kombinearje yn ien controller. Bygelyks, de brûkerstsjinst, dy't it probleem oplost fan it behearen fan projektbrûkersprofilen, moat reagearje op req-resp-oanfragen en rapportearje profylupdates fia pub-sub. Dit gefal is frij simpel: efter messaging is d'r ien controller dy't de tsjinstlogika ymplementearret en updates publisearret.

De situaasje wurdt yngewikkelder as wy in fouttolerante ferdielde tsjinst moatte ymplementearje. Litte wy ús foarstelle dat de easken foar brûkers binne feroare:

  1. no moat de tsjinst oanfragen ferwurkje op 5 klusterknooppunten,
  2. yn steat wêze om eftergrûnferwurkingstaken út te fieren,
  3. en ek yn steat wêze om abonnemintlisten dynamysk te behearjen foar profylupdates.

Opmerking: Wy beskôgje it probleem fan konsekwinte opslach en gegevensreplikaasje net. Lit ús oannimme dat dizze problemen binne oplost earder en it systeem hat al in betrouber en scalable opslach laach, en handlers hawwe meganismen om te ynteraksje mei it.

De formele beskriuwing fan 'e brûkerstsjinst is yngewikkelder wurden. Fanút it eachpunt fan in programmeur binne feroarings minimaal troch it gebrûk fan berjochten. Om oan 'e earste eask te foldwaan, moatte wy balâns konfigurearje op it req-resp-útwikselpunt.

De eask om eftergrûntaken te ferwurkjen komt faak foar. By brûkers kin dit it kontrolearjen fan brûkersdokuminten wêze, it ferwurkjen fan ynladen multimedia, of it syngronisearjen fan gegevens mei sosjale media. netwurken. Dizze taken moatte op ien of oare manier binnen it kluster ferdield wurde en de fuortgong fan útfiering wurde kontrolearre. Dêrom hawwe wy twa oplossingsopsjes: of brûk it sjabloan foar taakferdieling fan it foarige artikel, of, as it net past, skriuw in oanpaste taakplanner dy't it pool fan processors beheart op 'e manier dy't wy nedich binne.

Punt 3 fereasket de pub-sub template extension. En foar ymplemintaasje, nei it meitsjen fan in pub-sub-útwikselpunt, moatte wy ek de controller fan dit punt yn ús tsjinst starte. Sa is it as ferpleatse wy de logika foar it ferwurkjen fan abonneminten en ôfskriuwingen fan 'e messaging-laach nei de ymplemintaasje fan brûkers.

As gefolch, de ûntbining fan it probleem die bliken dat om te foldwaan oan de easken, wy moatte lansearje 5 eksimplaren fan de tsjinst op ferskillende knopen en meitsje in ekstra entiteit - in pub-sub controller, ferantwurdlik foar it abonnemint.
Foar in run 5 handlers, jo hoege net te feroarjen de tsjinst koade. De ienige ekstra aksje is it opsetten fan balânsregels op it wikselpunt, dêr't wy in bytsje letter oer prate.
D'r is ek in ekstra kompleksiteit: de pub-sub-controller en oanpaste taakplanner moatte wurkje yn ien eksimplaar. Nochris moat de messagingtsjinst, as fûnemintele, in meganisme leverje foar it selektearjen fan in lieder.

Leader's Choice

Yn ferdielde systemen is liederferkiezing de proseduere foar it beneamen fan ien proses ferantwurdlik foar it plannen fan ferdielde ferwurking fan guon lading.

Yn systemen dy't net gefoelich binne foar sintralisaasje, wurde universele en konsensus-basearre algoritmen, lykas paxos of raft, brûkt.
Sûnt messaging is in makelder en in sintraal elemint, it wit oer alle tsjinst controllers - kandidaat lieders. Messaging kin in lieder beneame sûnder te stimmen.

Nei it starten en ferbinen mei it útwikselpunt krije alle tsjinsten in systeemberjocht #'$leader'{exchange = ?EXCHANGE, pid = LeaderPid, servers = Servers}. As LeaderPid komt oerien mei pid hjoeddeistige proses, it wurdt beneamd as de lieder, en de list Servers befettet alle knopen en harren parameters.
Op it stuit in nije ferskynt en in wurkjende kluster knooppunt wurdt loskeppele, alle tsjinst controllers ûntfange #'$slave_up'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts} и #'$slave_down'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts} respektivelik.

Op dizze manier binne alle komponinten bewust fan alle feroaringen, en it kluster wurdt garandearre om ien lieder op elts momint te hawwen.

Bemiddelers

Om komplekse ferdielde ferwurkingsprosessen út te fieren, lykas yn problemen mei it optimalisearjen fan in besteande arsjitektuer, is it handich om tuskenpersoanen te brûken.
Om de tsjinstkoade net te feroarjen en bygelyks problemen fan ekstra ferwurking, routing of logging fan berjochten op te lossen, kinne jo in proxy-hanneler foar de tsjinst ynskeakelje, dy't al it ekstra wurk sil útfiere.

In klassyk foarbyld fan pub-sub optimalisaasje is in ferspraat applikaasje mei in saaklike kearn dy't generearret update eveneminten, lykas priis feroarings yn 'e merk, en in tagong laach - N tsjinners dy't soargje foar in websocket API foar web kliïnten.
As jo ​​​​head-on beslute, dan sjocht klanttsjinst der sa út:

  • de klant stelt ferbinings mei it platfoarm. Oan 'e kant fan' e tsjinner dy't it ferkear beëiniget, wurdt in proses lansearre om dizze ferbining te tsjinjen.
  • Yn 'e kontekst fan it tsjinstproses komme autorisaasje en abonnemint op updates foar. It proses neamt de abonnemintmetoade foar ûnderwerpen.
  • Sadree't in evenemint wurdt generearre yn 'e kernel, it wurdt levere oan de prosessen tsjinst de ferbinings.

Litte wy ús foarstelle dat wy 50000 abonnees hawwe op it ûnderwerp "nijs". Abonnees wurde gelyk ferdield oer 5 servers. As resultaat sil elke fernijing, dy't oankomt op it wikselpunt, 50000 kear wurde replikearre: 10000 kear op elke server, neffens it oantal abonnees derop. Net in heul effektyf skema, toch?
Om de situaasje te ferbetterjen, litte wy in proxy ynfiere dy't deselde namme hat as it wikselpunt. De wrâldwide nammeregistrator moat it tichtste proses by namme kinne weromjaan, dit is wichtich.

Litte wy dizze proxy starte op 'e tagongslaach-tsjinners, en al ús prosessen dy't de websocket-api betsjinje, sille derop abonnearje, en net op it orizjinele pub-sub-útwikselpunt yn 'e kernel. Proxy abonnearret allinich op 'e kearn yn it gefal fan in unyk abonnemint en replikearret it ynkommende berjocht nei al har abonnees.
As gefolch, 5 berjochten wurde ferstjoerd tusken de kernel en tagong tsjinners, ynstee fan 50000.

Routing en balâns

Req-Resp

Yn 'e hjoeddeistige ymplemintaasje fan messaging binne d'r 7 strategyen foar distribúsje fan fersyk:

  • default. It fersyk wurdt stjoerd nei alle controllers.
  • round-robin. Fersiken wurde opnomd en syklik ferdield tusken controllers.
  • consensus. De kontrôlers dy't de tsjinst tsjinje binne ferdield yn lieders en slaven. Oanfragen wurde allinich nei de lieder stjoerd.
  • consensus & round-robin. De groep hat in lieder, mar fersiken wurde ferdield ûnder alle leden.
  • sticky. De hash funksje wurdt berekkene en tawiisd oan in spesifike handler. Folgjende oanfragen mei dizze hantekening geane nei deselde handler.
  • sticky-fun. By inisjalisearjen fan de útwikseling punt, de hash berekkening funksje foar sticky balancing.
  • fun. Fergelykber mei sticky-fun, allinich kinne jo it ekstra omliede, ôfwize of foarferwurkje.

De distribúsje strategy wurdt ynsteld as de útwikseling punt wurdt inisjalisearre.

Neist balânsjen kinne berjochten jo entiteiten taggje. Litte wy nei de soarten tags yn it systeem sjen:

  • Ferbining tag. Stelt jo yn steat om te begripen troch hokker ferbining de barrens kamen. Wurdt brûkt as in controller proses ferbynt mei itselde útwikseling punt, mar mei ferskillende routing kaaien.
  • Service tag. Stelt jo yn steat om handlers te kombinearjen yn groepen foar ien tsjinst en útwreidzje rûte- en balânsmooglikheden. Foar it req-resp-patroan is routing lineêr. Wy stjoere in fersyk nei it wikselpunt, dan jout it troch oan de tsjinst. Mar as wy de handlers moatte splitse yn logyske groepen, dan wurdt de splitsing dien mei tags. By it opjaan fan in tag sil it fersyk stjoerd wurde nei in spesifike groep controllers.
  • Fersyk tag. Stelt jo yn steat om te ûnderskieden tusken antwurden. Om't ús systeem asyngroan is, moatte wy om tsjinstantwurden te ferwurkjen in RequestTag kinne opjaan by it ferstjoeren fan in fersyk. Dêrút sille wy it antwurd kinne begripe op hokker fersyk by ús kaam.

Pub-sub

Foar pub-sub is alles wat ienfâldiger. Wy hawwe in útwikseling punt dêr't berjochten wurde publisearre. It útwikselpunt ferspriedt berjochten ûnder abonnees dy't har ynskreaun hawwe op de routing-kaaien dy't se nedich binne (wy kinne sizze dat dit analoog is oan ûnderwerpen).

Skalberens en fouttolerânsje

De skaalberens fan it systeem as gehiel hinget ôf fan 'e mjitte fan skalberens fan' e lagen en komponinten fan it systeem:

  • Tsjinsten wurde skalearre troch it tafoegjen fan ekstra knopen oan it kluster mei handlers foar dizze tsjinst. Tidens proefoperaasje kinne jo it optimale balânsbelied kieze.
  • De berjochtentsjinst sels binnen in apart kluster wurdt oer it algemien skalearre troch it ferpleatsen fan benammen laden útwikselingspunten nei aparte klusterknooppunten, of troch it tafoegjen fan proxyprosessen oan benammen laden gebieten fan it kluster.
  • De skalberens fan it hiele systeem as karakteristyk hinget ôf fan de fleksibiliteit fan 'e arsjitektuer en de mooglikheid om yndividuele klusters te kombinearjen yn in mienskiplike logyske entiteit.

It sukses fan in projekt hinget faaks ôf fan 'e ienfâld en snelheid fan skaalfergrutting. Berjochten yn syn hjoeddeistige ferzje groeit tegearre mei de applikaasje. Ek as wy misse in kluster fan 50-60 masines, wy kinne taflecht ta federaasje. Spitigernôch is it ûnderwerp fan federaasje bûten it berik fan dit artikel.

Reservaat

By it analysearjen fan load balancing, hawwe wy al besprutsen oerstallichheid fan tsjinst controllers. Berjochten moatte lykwols ek reservearre wurde. Yn it gefal fan in knooppunt of masine crash, berjochten moatte automatysk herstelle, en yn 'e koartst mooglike tiid.

Yn myn projekten brûke ik ekstra knopen dy't de lading ophelje yn gefal fan in fal. Erlang hat in standert ferspraat modus ymplemintaasje foar OTP applikaasjes. Ferspraat modus fiert herstel út yn gefal fan mislearring troch it lansearjen fan de mislearre applikaasje op in oare earder lansearre knooppunt. It proses is transparant; nei in mislearring ferpleatst de applikaasje automatysk nei it failoverknooppunt. Jo kinne mear lêze oer dizze funksjonaliteit hjir.

Produktiviteit

Litte wy besykje de prestaasjes fan rabbitmq en ús oanpaste messaging op syn minst rûch te fergelykjen.
ik fûn offisjele resultaten rabbitmq-testen fan it openstack-team.

Yn paragraaf 6.14.1.2.1.2.2. It orizjinele dokumint toant it resultaat fan 'e RPC CAST:
Boublokken fan ferspraat applikaasjes. Twadde approximation

Wy sille foarôf gjin ekstra ynstellings meitsje foar de OS-kern of erlang VM. Betingsten foar testen:

  • erl opts: +A1 +sbtu.
  • De test binnen in inkele erlang node wurdt útfierd op in laptop mei in âlde i7 yn mobile ferzje.
  • Clustertests wurde útfierd op servers mei in 10G-netwurk.
  • De koade rint yn docker-konteners. Netwurk yn NAT modus.

Testkoade:

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.

Senario 1: De test wurdt útfierd op in laptop mei in âlde i7 mobile ferzje. De test, berjochten en tsjinst wurde útfierd op ien knooppunt yn ien Docker-container:

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)

Senario 2: 3 knopen rinne op ferskate masines ûnder 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)

Yn alle gefallen wie CPU-gebrûk net mear as 250%

Resultaten

Ik hoopje dat dizze syklus net liket op in geast dump en myn ûnderfining sil fan wirklik foardiel wêze foar sawol ûndersikers fan ferdielde systemen as praktiken dy't oan it begjin binne fan it bouwen fan ferdielde arsjitektueren foar har bedriuwssystemen en sjogge nei Erlang / Elixir mei belangstelling , mar twifelje is it wurdich ...

foto @chuttersnap

Allinnich registrearre brûkers kinne meidwaan oan 'e enkête. Ynlogge, asjebleaft.

Hokker ûnderwerpen moat ik yn mear detail dekke as ûnderdiel fan 'e VTrade Experiment-searje?

  • Teory: Merken, oarders en harren timing: DAY, GTD, GTC, IOC, FOK, MOO, MOC, LOO, LOC

  • Boek fan oarders. Teory en praktyk fan it útfieren fan in boek mei groepearrings

  • Fisualisaasje fan hannel: Tikken, bars, resolúsjes. Hoe te bewarjen en hoe te lijm

  • Administraasje. Planning en ûntwikkeling. Meiwurker tafersjoch en ynsidint ûndersyk

  • API. Litte wy útfine hokker ynterfaces nedich binne en hoe't se se ymplementearje

  • Ynformaasje opslach: PostgreSQL, Timescale, Tarantool yn hannelsystemen

  • Reaktiviteit yn hannelsystemen

  • Oar. Ik sil skriuwe yn 'e kommentaren

6 brûkers stimden. 4 brûkers ûntholden har.

Boarne: www.habr.com

Add a comment