Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

NĂ« Mail.ru Group kemi Tarantool — njĂ« server aplikacionesh nĂ« Lua, i cili njĂ«kohĂ«sisht Ă«shtĂ« edhe njĂ« bazĂ« tĂ« dhĂ«nash (apo anasjelltas?). Ai Ă«shtĂ« i shpejtĂ« dhe i shkĂ«lqyer, por mundĂ«sitĂ« e njĂ« serveri nuk janĂ« pafund. ShkallĂ«zimi vertical gjithashtu nuk Ă«shtĂ« njĂ« zgjidhje universale, prandaj nĂ« Tarantool ka mjete pĂ«r shkallĂ«zim horizontal — moduli vshard. [1]. Ai lejon tĂ« ndahen tĂ« dhĂ«nat nĂ« disa servera, por do tĂ« nevojitet pak punĂ« pĂ«r ta konfiguruar dhe integruar logjikĂ«n biznesore.

Lajme të mira: ne kemi mbledhur disa përvoja (p.sh. [2], [3]) dhe kemi krijuar një framë të re, e cila do ta thjeshtojë dukshëm zgjidhjen e kësaj probleme.

Tarantool Cartridge — Ă«shtĂ« njĂ« framework i ri pĂ«r zhvillimin e sistemeve tĂ« ndara mĂ« kompleks. Ai lejon tĂ« pĂ«rqendrohemi nĂ« shkruarjen e logjikĂ«s biznesore pĂ«rpara se tĂ« merremi me problemet infrastrukturore. PoshtĂ« do tĂ« tregoj si Ă«shtĂ« ndĂ«rtuar ky framework dhe si me ndihmĂ«n e tij tĂ« shkruajmĂ« shĂ«rbime tĂ« ndara.

Cila është, pra, problemi?

Ne kemi Tarantool, kemi vshard — çfarĂ« tjetĂ«r mund tĂ« dĂ«shirojmĂ«?

Së pari, bëhet fjalë për komoditetin. Konfigurimi i vshard konfigurohet përmes tabelave Lua. Që një sistem i ndarë me disa procese Tarantool të funksionojë siç duhet, konfigurimi duhet të jetë uniform kudo. Askush nuk dëshiron të merret me këtë manualisht. Prandaj, dalin në përdorim skripte të ndryshme, Ansible, sisteme implementimi.

Cartridge menaxhon vetë konfigurimin e vshard, e bën këtë bazuar në konfigurimin e tij të shpërndarë. Në esencë, kjo është një skedar i thjeshtë YAML, një kopje e të cilit ruhen në çdo instancë Tarantool. Thjeshtësimi qëndron në faktin se framework-u vetë monitoron konfigurimin e tij dhe siguron që ai të jetë identik kudo.

SĂ« dyti, bĂ«het fjalĂ« pĂ«rsĂ«ri pĂ«r komoditetin. Konfigurimi i vshard nuk ka asnjĂ« lidhje me zhvillimin e logjikĂ«s biznesore dhe vetĂ«m e shpĂ«rqendron programuesin nga puna. Kur diskutojmĂ« mbi arkitekturĂ«n e ndonjĂ« projekti, zakonisht flasim pĂ«r komponente tĂ« veçanta dhe ndĂ«rveprimin e tyre. ËshtĂ« ende herĂ«t pĂ«r tĂ« menduar pĂ«r implementimin e njĂ« klasteri nĂ« 3 qendra tĂ« tĂ« dhĂ«nave.

Ne e zgjidhim këto probleme herë pas here, dhe në një moment arritëm të zhvillonim një qasje që lehtëson punën me aplikacionin gjatë të gjithë jetëgjatësisë së tij: krijimi, zhvillimi, testimi, CI/CD, mbështetje.

Cartridge prezanton konceptin e roleve për çdo proces Tarantool. Roli është ajo koncepci që lejon zhvilluesin të fokusohet në shkruajtjen e kodit. Të gjitha rolet e disponueshme në projekt mund të ekzekutohen në një instancë Tarantool, dhe për testimet kjo do të ishte e mjaftueshme.

Karakteristikat kryesore të Tarantool Cartridge:

  • orkestrimin automatizuar tĂ« klasterit;
  • zgjerimin e funksionalitetit tĂ« aplikacionit pĂ«rmes rolleve tĂ« reja;
  • shmablli i aplikacionit pĂ«r zhvillim dhe vendosje;
  • shkĂ«putje automatike tĂ« integruar;
  • integraimi me framework-un e testimit Luatest;
  • menaxhimi i klasterit pĂ«rmes WebUI dhe API;
  • mjetet pĂ«r paketimin dhe depolimin.

Hello, World!

Nuk mundem të pres që të tregoj framework-un vetë, kështu që do ta lëmë për më vonë bisedën për arkitekturën, dhe do të fillojmë me diçka të thjeshtë. Nëse supozoni se Tarantool është instaluar tashmë, atëherë duhet vetëm të bëni

$ tarantoolctl rocks install cartridge-cli
$ export PATH=$PWD/.rocks/bin/:$PATH

Këto dy komandat do të instalojnë utilitetet e linjës së komandës dhe do t'ju lejojnë të krijoni aplikacionin tuaj të parë nga një shabllon:

$ cartridge create --name myapp

Dhe ja çfarë do të marrim:

myapp/
├── .git/
├── .gitignore
├── app/roles/custom.lua
├── deps.sh
├── init.lua
├── myapp-scm-1.rockspec
├── test
│   ├── helper
│   │   ├── integration.lua
│   │   └── unit.lua
│   ├── helper.lua
│   ├── integration/api_test.lua
│   └── unit/sample_test.lua
└── tmp/

Ky është një depo git me një aplikacion të gatshëm "Hello, World!". Le të përpiqemi ta nisnim atë menjëherë, duke instaluar varësitë (përfshirë edhe vetë framework-un):

$ tarantoolctl rocks make
$ ./init.lua --http-port 8080

Pra, kemi nisur një nod të aplikacionit të ardhshëm të shqiptuar. Një qytetar kurioz mund të hapë menjëherë ndërfaqen e internetit, të konfiguronte me miun klasterin e një nodi dhe të shijonte rezultatin, por gëzimi duhet të presë. Për momentin aplikacioni nuk di të bëjë asgjë të dobishme, kështu që do të flas më vonë për depolimin, ndërsa tani është koha për të shkruar kod.

Zhvillimi i aplikacioneve

Imagjinoni, po dizajnojmë një projekt që duhet të pranojë të dhëna, t'i ruajë dhe një herë në ditë të ndihmojë në përgatitjen e raporteve.

Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

Fillojmë të vizatojmë skemën, dhe vendosim tre komponentë në të: gateway, storage, dhe scheduler. E zhvillojmë më tej arkitekturën. Duke qenë se ne përdorim vshard si ruajtje, shtojmë në skemë vshard-router dhe vshard-storage. As gateway dhe as scheduler nuk do të lidhen drejtpërdrejt me ruajtjen, për këtë është routeri, që është krijuar për këtë.

Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

Ky kjo skemĂ« ende nuk e reflekton plotĂ«sisht atĂ« qĂ« do tĂ« krijojmĂ« nĂ« projekt, sepse komponentĂ«t duken abstraktĂ«. Duhet tĂ« shohim se si do tĂ« projektejĂ« kjo nĂ« Tarantool-in e vĂ«rtetë—do t’i grupojmĂ« komponentĂ«t tanĂ« sipas proceseve.

Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

Të mbash vshard-router dhe gateway në ekzemplarë të ndarë nuk ka kuptim. Pse të shkojmë përsëri përmes rrjetit, kur kjo është pjesë e detyrave të router-it? Ata duhet të jenë të nisur brenda një procesi. Pra, në një proces do të inicializohen dhe gateway, dhe vshard.router.cfg, dhe le të bashkëpunojnë lokalë.

NĂ« fazĂ«n e projektimit, ishte e leverdisshme tĂ« punosh me tre komponentĂ«, por unĂ«, si zhvillues, ndĂ«rsa shkruaj kod, nuk dua tĂ« mendoj pĂ«r nisjen e tre ekzemplarĂ«ve tĂ« Tarantool. MĂ« duhet tĂ« nis testet dhe tĂ« kontrolloj nĂ«se e kam shkruar saktĂ« gatewayn. Ose, ndoshta, dua t'ua demonstroj kolegĂ«ve njĂ« veçori. Pse duhet tĂ« mundohesha me dislokimin e tre ekzemplarĂ«ve? KĂ«shtu lindi koncepti i rolit. NjĂ« rol Ă«shtĂ« njĂ« modul i zakonshĂ«m Lua, i cili menaxhohet nga Cartridge. NĂ« kĂ«tĂ« shembull, ka katĂ«r—gateway, router, storage, scheduler. NĂ« njĂ« projekt tjetĂ«r mund tĂ« ketĂ« mĂ« shumĂ«. TĂ« gjithĂ« rolet mund tĂ« nisen nĂ« njĂ« proces dhe kĂ«saj do tĂ« mjaftojĂ«.

Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

Dhe kur të flasim për dislokimin në staging ose në prodhim, atëherë do t'i caktojmë secilit proces Tarantool kompletin e vet të rolit në varësi të kapaciteteve harduerike.

Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

Menaxhimi i topologjisë

Informacioni rreth se ku janë aktivizuar rolet duhet të ruhet diku. Dhe ky "diku" është konfigurimi i shpërndarë, për të cilin kam përmendur më lart. Gjëja më e rëndësishme në të është topologjia e klasterit. Këtu janë paraqitur 3 grupe replikimi nga 5 procese Tarantool:

Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

Ne nuk duam të humbim të dhënat, prandaj i japim shumë rëndësi informacionit mbi proceset e aktivizuara. Cartridge monitoron konfigurimin me ndihmën e komitit me dy faza. Sa herë që duam të përditësojmë konfigurimin, ai së pari kontrollon disponueshmërinë e të gjithë ekzemplarëve dhe gatishmërinë e tyre për të pranuar konfigurimin e ri. Pas kësaj, në fazën e dytë, aplikohet konfigurimi. Kështu, edhe nëse një ekzemplar është përkohësisht i papastër, nuk do të ndodhin probleme. Konfigurimi thjesht nuk do të aplikohet dhe ju do të shihni paraprakisht një gabim.

Gjithashtu, në seksionin e topologjisë është specifikuar një parametr kaq i rëndësishëm si lideri i çdo grupi replikimi. Zakonisht, ky është ekzemplari në të cilin bëhet shkruarja. Të tjerët janë zakonisht read-only, megjithatë, këtu mund të ketë përjashtime. Ndonjëherë zhvilluesit guximtarë nuk kanë frikë nga konfliktet dhe mund të shkruajnë të dhëna në disa replika paralelisht, por ka disa operacione që, pavarësisht gjithçkaje, nuk duhet të kryhen dy herë. Për këtë ekziston treguesi i liderit.

Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

Jeta e roleve

Që një rol abstrakt të mund të ekzistojë në një arkitekturë të tillë, framework-u duhet të menaxhojë ata në ndonjë mënyrë. Sigurisht, menaxhimi ndodh pa rinisur procesin Tarantool. Për menaxhimin e roleve ekzistojnë 4 callback-e. Cartridge do t'i thërrasë ato në varësi të asaj që ka shkruar në konfigurimin e shpërndarë, duke aplikuar kështu konfigurimin në role specifike.

function init()
function validate_config()
function apply_config()
function stop()

Secili rol ka një funksion init. Ky funksion thirret një herë ose kur aktivizohet roli, ose kur rinitet Tarantool. Aty mund të inicializohet, për shembull, box.space.create, ose scheduler-i mund të niste ndonjë fiber në sfond, i cili do të kryejë punë nëpërmjet njëkohësish përkohësish.

Një funksion init mund të mos mjaftojë. Cartridge lejon rolet të përdorin atë konfigurimin e shpërndarë që përdor për ruajtjen e topologjisë. Ne mund ta shpallim në këtë konfigurim një seksion të ri dhe të ruajmë në të një fragment të konfigurimit të biznesit. Në shembulin tim, kjo mund të jetë një skemë të dhënash, ose cilësimet e orarit për rolin e scheduler-it.

Klastri thërret validate_config dhe apply_config me çdo ndryshim në konfigurimin e shpërndarë. Kur konfigurimi aplikohet me komit dy-fazësh, klastrin kontrollon që çdo rol të jetë i gatshëm të pranojë këtë konfigurim të ri, dhe, nëse është e nevojshme, i komunikon përdoruesit për ndonjë gabim. Kur të gjithë janë dakord që konfigurimi është në rregull, atëherë zbatohet apply_config.

Gjithashtu, rolet kanë metodën stop, e cila nevojitet për pastrimin e rezultateve të ekzistencës së rolit. Nëse themi se scheduler-i në këtë server nuk është më i nevojshëm, ai mund të ndalojë ato fibra që ka nisin përmes init.

Rolet mund të ndërveprojnë me njëra-tjetrën. Ne jemi mësuar të shkruajmë thirrje funksionesh në Lua, por ndonjëherë ndodh që roli që na nevojitet nuk është në procesin përkatës. Për të lehtësuar komunikimin në rrjet, ne përdorim modul ndihmës rpc (thirrje procedurale të largët), i cili është ndërtuar mbi bazën e netbox-it standard të integruar në Tarantool. Kjo mund të jetë e dobishme, nëse, për shembull, gateway juaj dëshiron të kërkojë drejtpërdrejt nga scheduler-i që të bëjë punën tani, në vend të pritjes për një ditë.

Një tjetër moment i rëndësishëm është sigurimi i qëndrueshmërisë. Për monitorimin e shëndetit, në Cartridge përdoret protokolli SWIM. [4]Nëse flasim shkurtazi, proceset ndajnë mes tyre "thashetheme" përmes UDP - çdo proces i tregon fqinjëve të tij lajmet e fundit, dhe ata përgjigjen. Nëse ndonjëherë përgjigjja nuk ka ardhur, Tarantool fillon të dyshojë se diçka nuk shkon mirë, dhe pas një kohe shpall vdekjen dhe fillon të tregojë të gjitha këto lajme të rrethit.

Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

NĂ« bazĂ« tĂ« kĂ«tij protokolli, Cartridge organizon pĂ«rpunimin automatik tĂ« dĂ«shtimeve. Çdo proces ndjek mjedisin e tij, dhe nĂ«se lideri papritmas pushon sĂ« pĂ«rgjiguri, njĂ« replikĂ« mund ta marrĂ« rolin e tij, dhe Cartridge konfiguroni rolet e lidhura siç duhet.

Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

Këtu duhet të jemi të kujdesshëm, sepse kalimi i shpeshtë mbrapa e përpara mund të çojë në konflikte të të dhënave gjatë replikimit. Activizimi i failover-it automatik në mënyrë të rastësishme, natyrisht, nuk është një ide e mirë. Duhet të kuptojmë qartë se çfarë po ndodh dhe të jemi të sigurt se replikimi nuk do të dështojë pasi lideri të rikuperohet dhe t'i jepet kurora përsëri.

Nga e gjithë kjo që u tha, mund të krijohet përshtypja se rolet janë të ngjashme me mikroshërbimet. Në një sens, ato janë pikërisht ato, vetëm si module brenda proceseve Tarantool. Por ka edhe disa dallime themelore. Në radhë të parë, të gjitha rolet e projektit duhet të jetojnë në një bazë kodi të vetme. Të gjitha proceset e Tarantool duhet të fillojnë nga një bazë e përbashkët kodi, në mënyrë që të mos ndodhin surpriza si ato kur përpiqemi të inicializojmë scheduler-in, por ai thjesht nuk ekziston. Gjithashtu, nuk duhet të lejojmë dallime në versionet e kodit, sepse sjellja e sistemit në një situatë të tillë është shumë e vështirë për t'u parashikuar dhe ndrequr.

NĂ« krahasim me Docker-in, nuk mund tĂ« marrim thjesht "imazhin" e rolit, ta çojmĂ« nĂ« njĂ« makinĂ« tjetĂ«r dhe ta aktivizojmĂ« atje. Roli ynĂ« nuk Ă«shtĂ« aq i izoluar sa kontejnerĂ«t Docker. Gjithashtu, nuk mund tĂ« aktivizojmĂ« dy role identike nĂ« njĂ« instancĂ«. Roli ose Ă«shtĂ« aty, ose nuk Ă«shtĂ«, nĂ« njĂ« kuptim kjo Ă«shtĂ« njĂ« singleton. Dhe sĂ« treti, brenda gjithĂ« grupit tĂ« replikimit, role duhet tĂ« jenĂ« identike, sepse ndryshe do tĂ« ishte absurd — tĂ« dhĂ«nat janĂ« tĂ« njĂ«jta, por konfigurimi Ă«shtĂ« ndryshe.

Mjetet e dërgimit

Premtova tĂ« tregoj se si Cartridge ndihmon nĂ« dĂ«rgimin e aplikacioneve. PĂ«r ta bĂ«rĂ« jetĂ«n mĂ« tĂ« lehtĂ« tĂ« tjerĂ«ve, Ă§æĄ†dmia paketat RPM:

$ cartridge pack rpm myapp -- do të paketojë për ne .\/myapp-0.1.0-1.rpm
$ sudo yum install .\/myapp-0.1.0-1.rpm

Paketa e instaluar përmban pothuajse gjithçka të nevojshme: si aplikacionin, ashtu edhe varësitë e instaluara Lua. Tarantool do të vijë gjithashtu në server si varësi e paketës RPM, dhe shërbimi ynë është gati për aktivizim. Kjo bëhet përmes systemd, por së pari nevojitet të shkruhen disa konfigurime. Të paktën, duhet të tregojmë URI-në e çdo procesi. Tre si shembull mjaftojnë.

$ sudo tee \/etc\/tarantool\/conf.d\/demo.yml <<CONFIG
myapp.router: {"advertise_uri": "localhost:3301", "http_port": 8080}
myapp.storage_A: {"advertise_uri": "localhost:3302", "http_enabled": False}
myapp.storage_B: {"advertise_uri": "localhost:3303", "http_enabled": False}
CONFIG

Këtu ka një nuancë interesante. Në vend që të tregojmë vetëm portin e protokollit binar, ne tregojmë adresën publike të procesit tërësisht duke përfshirë emrin e hostit. Kjo është e nevojshme që nyjat e grumbullit të dinë si të lidhen me njëri-tjetrin. Një ide e keqe është të përdorim si advertise_uri adresën 0.0.0.0, ajo duhet të jetë një adresë e jashtme IP dhe jo një soket bind. Pa të, asgjë nuk do të funksionojë, prandaj Cartridge thjesht nuk do të lejojë aktivizimin e një nyjeje me advertise_uri të gabuar.

Tani, kur konfigurimi është i gatshëm, mund të aktivizojmë proceset. Ndërsa një njësinë e zakonshme systemd nuk lejon aktivizimin e më shumë se një procesi, aplikacionet në Cartridge vendosin njësitë e quajtura instancuara, të cilat funksionojnë kështu:

$ sudo systemctl start myapp@router
$ sudo systemctl start myapp@storage_A
$ sudo systemctl start myapp@storage_B

NĂ« konfigurim kemi vendosur portin HTTP, nĂ« tĂ« cilin Cartridge shĂ«rben ndĂ«rfaqen e uebit — 8080. Le tĂ« hyjmĂ« atje dhe ta shqyrtojmĂ«:

Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

Ne shohim se proceset janë të nisura, por ende nuk janë konfiguruar. Kartëdridha ende nuk e di se kush duhet të riplikohet dhe nuk mund të marrë vendime vetë, prandaj po pret veprimet tona. Dhe zgjedhja jonë nuk është e madhe: jeta e një klasteri të ri fillon me konfigurimin e nyjës së parë. Më pas do t'i shtojmë të tjerët në klaster, do të caktojmë role për ta, dhe kështu deploy do të konsiderohet i përfunduar me sukses.

Të derdhim një gotë me pijen tonë të preferuar dhe të relaksohemi pas një jave të gjatë pune. Aplikimi mund të eksploatohet.

Tarantool Cartridge: sharding i backend-it Lua në tri rreshta

Përfundime

Cila është përmbledhja? Provoni, përdorni, lëreni feedback, hapni tiket në GitHub.

Linket

[1] Tarantool » 2.2 » Referenca » Referenca për Rocks » Moduli vshard

[2] Si e implementuam kernin e biznesit të investimeve të Alfa-Bankës mbi bazën e Tarantool

[3] Arkitektura e sistemit të faturimit të brezit të ri: transformimi me kalimin në Tarantool

[4] SWIM — protokolli i ndĂ«rtimit tĂ« klasterit

[5] GitHub — tarantool/cartridge-cli

[6] GitHub — tarantool/cartridge

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster