
Ne kemi Tarantool nĂ« Mail.ru Group â ky Ă«shtĂ« njĂ« server aplikacionesh nĂ« Lua, i cili nĂ« tĂ« njĂ«jtĂ«n kohĂ« Ă«shtĂ« edhe njĂ« bazĂ« tĂ« dhĂ«nash (apo anasjelltas?). ĂshtĂ« i shpejtĂ« dhe i shkĂ«lqyer, por mundĂ«sitĂ« e njĂ« serveri nuk janĂ« tĂ« pafundme. ShkallĂ«zimi vertikal gjithashtu nuk Ă«shtĂ« njĂ« panace, prandaj nĂ« Tarantool ka mjete pĂ«r shkallĂ«zim horizontal â moduli vshard . Ai lejon sharding tĂ« dhĂ«nash nĂ« disa servera, por do tĂ« duhet tĂ« merresh pak me tĂ« pĂ«r ta konfiguruar dhe pĂ«r tĂ« lidhur logjikĂ«n e biznesit.
Lajme të mira: ne kemi bërë gabime (për shembull , ) dhe krijuam një framework, i cili do ta thjeshtojë dukshëm zgjidhjen e kësaj problemi.
â Ă«shtĂ« njĂ« framework i ri pĂ«r zhvillimin e sistemeve tĂ« shpĂ«rndara tĂ« komplikuara. Ai lejon tĂ« fokusohemi nĂ« shkrimin e logjikĂ«s sĂ« biznesit nĂ« vend qĂ« tĂ« merremi me problemet infrastrukturore. MĂ« poshtĂ« do tĂ« flas pĂ«r mĂ«nyrĂ«n se si funksionon ky framework dhe si tĂ« shkruajmĂ« shĂ«rbime tĂ« shpĂ«rndara me ndihmĂ«n e tij.
Cila është, pra, problemi?
Kemi Tarantool, kemi vshard â çfarĂ« mĂ« shumĂ« tĂ« dĂ«shirojmĂ«?
Së pari, është çështje e komoditetit. Konfigurimi i vshard përcaktohet përmes tabelave Lua. Për të siguruar funksionimin e saktë të sistemit të shpërndarë nga disa procese Tarantool, konfigurimi duhet të jetë identik kudo. Askush nuk dëshiron të merret me këtë manualisht. Prandaj përdoren skripte të ndryshme, Ansible, dhe sisteme implementimi.
Cartridge menaxhon vetë konfiguracionin e vshard, duke e bërë këtë mbi bazën e saj konfigurimi të shpërndarë. Në thelb, kjo është një skedar YAML e thjeshtë, një kopje e së cilës ruhet në çdo instancë Tarantool. Lehtësimi është se framework-u vetë e ndjek konfigurimin e tij dhe siguron që ai të jetë identik kudo.
Së dyti, përsëri është çështje komoditeti. Konfigurimi i vshard nuk ka asnjë lidhje me zhvillimin e logjikës biznesore dhe vetëm e shpërqendron programuesin nga puna. Kur diskutojmë arkitekturën e ndonjë projekti, shpesh flasim për komponente të veçanta dhe ndërveprimin e tyre. Për të menduar për implementimin e një klasteri në 3 qendra të të dhënave, është ende herët.
Kemi zgjidhur këto probleme herë pas here, dhe në një moment arritëm të zhvillonim një qasje që thjeshton punën me aplikacionin gjatë gjithë ciklit të tij të jetës: krijimi, zhvillimi, testimi, CI/CD, mbështetje.
Cartridge prezanton konceptin e rolit për çdo proces Tarantool. Roli është ajo koncept që i lejon zhvilluesit të përqendrohet në shkruarjen e kodit. Të gjitha rolet ekzistuese në projekt mund të ekzekutohen në një instancë Tarantool, dhe për testet kjo do të jetë e mjaftueshme.
Kapacitetet kryesore të Tarantool Cartridge:
- orkestrimi automatizuar i klusterit;
- zgjatja e funksionalitetit të aplikacionit me anë të rolleve të reja;
- shabllon aplikacioni për zhvillim dhe implementim;
- shardim automatizuar të integruar;
- integimi me kuadrin e testimit Luatest;
- menaxhimi i klusterit përmes WebUI dhe API;
- mjetet e paketimit dhe shpërndarjes.
Përshëndetje, Botë!
Mezi pres të tregoj vetë kuadrin, prandaj do ta lëmë historinë për arkitekturën për më vonë, dhe do të fillojmë me të thjeshta. Nëse supozojmë se Tarantool është instaluar tashmë, atëherë mbetet të bëhet vetëm
$ tarantoolctl rocks install cartridge-cli
$ export PATH=$PWD/.rocks/bin/:$PATHKëto dy komandat do të instalojnë mjetet e komandës dhe do të lejojnë krijimin e aplikacionit tuaj të parë nga një model:
$ cartridge create --name myappDhe 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ë git-repozitor me një aplikacion të gatshëm "Hello, World!" Le të përpiqemi ta nisim menjëherë, duke instaluar varësitë (përfshirë edhe vetë framework-un):
$ tarantoolctl rocks make
$ ./init.lua --http-port 8080Pra, ne kemi nisur një nodë të aplikacionit të ardhshëm me ndarje. Një kurioz mund ta hapë menjëherë ndërfaqen web, të konfigurojë me miun një klaster me një nod dhe ta shijojë rezultatin, por është ende herët për të gëzuar. Deri tani, aplikacioni nuk di të bëjë asgjë të dobishme, kështu që do të flas për krijimin e tij më vonë, por tani është koha të shkruajmë kod.
Zhvillimi i aplikacioneve
Të imagjinojmë, ne po dizajnojmë një projekt që duhet të pranojë të dhëna, t'i ruajë ato dhe një herë në ditë të ndihmojë në ndërtimin e një raporti.

Fillojmë të krijojmë një skemë dhe vendosim tre komponentë në të: gateway, storage dhe scheduler. Vazhdimmë me punimin mbi arkitekturën. Duke përdorur vshard si ruajtje, shtojmë në skemë vshard-router dhe vshard-storage. As gateway, as scheduler nuk do të kenë akses direkt në ruajtje, për këtë ka router, i cili është krijuar për këtë qëllim.

Kjo skemë ende nuk e reflepton saktësisht atë që do të krijojmë në projekt, sepse komponentët duken abstrakt. Duhet të shohim si do të projektohet në Tarantool të vërtetë - të grupojmë komponentët tanë sipas proceseve.

Të mbash vshard-router dhe gateway në instanca të ndara nuk ka shumë kuptim. Pse të shkojmë përsëri nëpër rrjet, kur kjo është gjithashtu në detyrat e router-it? Ata duhet të nisen brenda një procesi. Pra, në një proces inicializohen si gateway ashtu dhe vshard.router.cfg, dhe le të komunikojnë lokal.
NĂ« fazĂ«n e projektimit, ishte e lehtĂ« tĂ« punoja me tre komponentĂ«, por unĂ«, si zhvillues, nuk dĂ«shiroj tĂ« mendoj pĂ«r nisjen e tre instancave tĂ« Tarantool derisa tĂ« shkruaj kodin. MĂ« duhen tĂ« filloj testet dhe tĂ« kontrolloj nĂ«se kam shkruar saktĂ« gateway-in. Ose, ndoshta, dĂ«shiroj tĂ« demonstroj njĂ« tipar kolegĂ«ve tĂ« mi. Pse tĂ« merrem me shpĂ«rndarjen e tre instancave? PikĂ«risht kĂ«shtu lindi koncepti i rolit. Roli Ă«shtĂ« njĂ« modul i zakonshĂ«m Lua, tĂ« cilin e menaxhon cikli i jetĂ«s sĂ« tij tĂ« performuar nga Cartridge. NĂ« kĂ«tĂ« shembull ka katĂ«r â gateway, router, storage, scheduler. NĂ« njĂ« projekt tjetĂ«r mund tĂ« ketĂ« mĂ« shumĂ«. TĂ« gjitha rolet mund tĂ« nisen nĂ« njĂ« proces, dhe kjo do tĂ« mjaftonte.

Dhe kur të bëhet fjalë për shpërndarjen në staging ose në prodhim, atëherë ne do t'i caktojmë çdo procesi Tarantool grupe roli sipas mundësive harduerike:

Menaxhimi i topologjisë
Duhet të ruhet informacioni se ku janë të nisura të gjitha rolet. Dhe ky "diku" është konfigurationsi i shpërndarë, për të cilin kam përmendur më parë. E rëndësishmja në të është topologjia e klasterit. Këtu janë të paraqitura 3 grupe replikimi nga 5 procese Tarantool:

Ne duam të ruajmë të dhënat, prandaj trajtojmë me kujdes informacionin mbi proceset e aktivizuara. Cartridge mbikëqyr konfigurimin me anë të një komiti në dy faza. Sapo të dëshirojmë të përditësojmë konfigurimin, ai fillimisht kontrollon disponueshmërinë e të gjitha instancave dhe gatishmërinë e tyre për të pranuar konfigurimin e ri. Më pas, në fazën e dytë aplikohet konfigurimi. Kështu, edhe nëse një instancë është përkohësisht e paarritshme, asgjë e keqe nuk do të ndodhë. Konfigurimi thjesht nuk do të aplikohet dhe ju do të shihni një gabim paraprakisht.
Gjithashtu, në seksionin e topologjisë është e shënuar një parametër kaq i rëndësishëm si lideri i çdo grupi replikimi. Zakonisht, kjo është ajo instancë ku shkruhet informacioni. Të tjerët zakonisht janë vetëm lexues, megjithatë këtu mund të ketë përjashtime. Ndonjëherë zhvilluesit guximtarë nuk friksohen nga konfliktet dhe mund të shkruajnë të dhëna në disa replika njëkohësisht, por ka disa operacione që, pavarësisht nga çfarë, nuk duhet të ekzekutohen dy herë. Për këtë ekziston shenja e liderit.

Jeta e roleve
Në mënyrë që një rol abstrakt të ekzistojë në një arkitekturë të tillë, shablloni duhet ta menaxhojë atë në një farë mënyre. Natyrisht, menaxhimi ndodh pa e rinisur procesin Tarantool. Ka 4 thirrje për menaxhimin e rolëve. Cartridge do t'i thërrasë ato ndihmuar nga konfigurimi i shpërndarë, duke aplikuar kështu konfigurimin në rol konkret.
function init()
function validate_config()
function apply_config()
function stop()
Ădo rol ka njĂ« funksion procesi. Ai thirret njĂ« herĂ« ose kur aktivizohet roli, ose kur riniset Tarantool. Atje Ă«shtĂ« e pĂ«rshtatshme, pĂ«r shembull, tĂ« inicializosh box.space.create, ose programatori mund tĂ« niste ndonjĂ« fiber tĂ« prapambetur, i cili do tĂ« kryejĂ« punĂ« nĂ« intervale tĂ« caktuara.
Një funksion procesi mund të jetë i pamjaftueshëm. Cartridge lejon rolëve të përdorin atë konfigurimin e shpërndarë që ai e përdor për ruajtjen e topologjisë. Ne mund të shpallim një seksion të ri në këtë konfigurim dhe të ruajmë në të një fragment të konfigurimit të biznesit. Në shembullin tim, kjo mund të jetë një skemë të dhënash, ose cilësime për orarin e rolit të programatorit.
Klastri thërret validate_config dhe apply_config me çdo ndryshim në konfigurimin e shpërndarë. Kur konfigurimi aplikohet me një angazhim në dy faza, klasteri 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ë bien dakord që konfigurimi është në rregull, atëherë ekzekutohet apply_config.
Gjithashtu rolet kanë një metodë ndalo, e cila është e nevojshme për të pastruar rezultatet e aktiviteteve të 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 nisur me procesi.
Rolet mund të bashkëveprojnë me njëra-tjetrën. Jemi të zakonshëm të shkruajmë thirrje funksionesh në Lua, por mund të ndodhë që në këtë proces të mos ketë rolin që na nevojitet. Për të lehtësuar thirrjet përmes rrjetit, ne përdorim një modul ndihmës rpc (thirrje procedurale nga një distancë), i cili është ndërtuar mbi netbox-in standard, i 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 për të bërë një punë tani, dhe jo të presë një ditë.
NjĂ« çështje tjetĂ«r e rĂ«ndĂ«sishme Ă«shtĂ« sigurimi i qĂ«ndrueshmĂ«risĂ« sĂ« shĂ«rbimit. PĂ«r monitorimin e shĂ«ndetit nĂ« Cartridge pĂ«rdoret protokolli SWIM . NĂ«se flasim shkurt, proceset shkĂ«mbejnĂ« "thashetheme" me njĂ«ra-tjetrĂ«n pĂ«rmes UDP â çdo proces i tregon fqinjeve tĂ« tij lajmet e fundit, dhe ata pĂ«rgjigjen. NĂ«se ndodhtĂ« qĂ« pĂ«rgjigje nuk ka ardhur, Tarantool fillon tĂ« dyshojĂ« se diçka nuk shkon, dhe pas njĂ« kohe fillon tĂ« shpallĂ« vdekjen dhe t'u tregojĂ« tĂ« gjithĂ«ve kĂ«tĂ« lajm.

Bazuar nĂ« kĂ«tĂ« protokoll, Cartridge organizon pĂ«rpunimin automatizues tĂ« dĂ«shtimeve. Ădo proces monitoron ambientin e tij, dhe nĂ«se lideri papritur nuk pĂ«rgjigjet, njĂ« kopje mund ta marrĂ« atĂ« rol pĂ«r vete, dhe Cartridge konfiguron pĂ«rkatĂ«sisht rolet e nisura.

Këtu duhet të jemi të kujdesshëm, sepse kalimi i shpeshtë nga njëra anë në tjetrën mund të çojë në konflikte të dhënash gjatë replikimit. Aktivizimi i automatik të dështimeve pa menduar, sigurisht, nuk është e mençur. Duhet të kuptojmë qartë se çfarë po ndodh dhe të jemi të sigurt se replikimi nuk do të prishet pasi lideri të rikthehet dhe t'i kthehet kurora.
Nga gjithçka e thënë, mund të krijohet përshtypja se rolet janë të ngjashme me mikroserviset. Në një farë mënyre, ato janë në të vërtetë, por si module brenda proceseve Tarantool. Por ka edhe disa dallime thelbësore. Së pari, të gjitha rolet e projektit duhet të jetojnë në të njëjtin bazë kodi. Të gjitha proceset Tarantool duhet të nisen nga e njëjta bazë kodi, për të evituar surpriza të tilla si ato kur përpiqemi të inicializojmë scheduler, dhe ai thjesht nuk është aty. Gjithashtu, nuk duhet lejuar ndryshime në versionet e kodit, sepse sjellja e sistemit në një situatë të tillë është shumë e vështirë për t'u parashikuar dhe debugging.
Ndryshe nga Docker, ne nuk mund tĂ« thjesht tĂ« marrim "imazhin" e rolit, ta çojmĂ« atĂ« nĂ« njĂ« makinĂ« tjetĂ«r dhe ta nisim atje. Rolet tona nuk janĂ« aq tĂ« izoluara sa kontenierĂ«t Docker. Gjithashtu, ne nuk mund tĂ« ndihmojmĂ« dy role identike nĂ« njĂ« instancĂ« tĂ« vetme. NjĂ« rol Ă«shtĂ« ose ekziston, ose nuk ekziston, nĂ« njĂ« farĂ« kuptimi, ky Ă«shtĂ« njĂ« singleton. Dhe nĂ« tĂ« tretĂ«n, brenda gjithĂ« grupit tĂ« replikimit rolet duhet tĂ« jenĂ« identike, sepse pĂ«rndryshe do tĂ« ishte qesharake â tĂ« dhĂ«nat janĂ« tĂ« njĂ«jta, por konfigurimi Ă«shtĂ« i ndryshĂ«m.
Mjetet e vendosjes
Premtova të tregoj se si Cartridge ndihmon në deployimin e aplikacioneve. Për t'i bërë gjërat më të lehta për të tjerët, kuadri paketizon 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.rpmPaketa e instaluar përmban pothuajse gjithçka të nevojshme: aplikacionin dhe varësitë luash. Tarantool do të vijë gjithashtu në server si një varësi e paketës RPM, dhe shërbimi ynë është gati për të nisur. Kjo bëhet përmes systemd, por më parë nevojitet të shkruajmë pak konfiguracion. Të paktën, duhet të specifikojmë URI-në e çdo procesi. Tre janë të mjaftueshme si shembuj.
$ 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}
CONFIGKaçka interesante Ă«shtĂ«. NĂ« vend qĂ« tĂ« tregojmĂ« vetĂ«m portin e protokollit binar, ne tregojmĂ« adresĂ«n publike tĂ« procesit tĂ« tĂ«rĂ«, duke pĂ«rfshirĂ« emrin e host-it. Kjo Ă«shtĂ« e nevojshme qĂ« nodet e klasterit tĂ« dinĂ« si tĂ« lidhen me njĂ«ri-tjetrin. ĂshtĂ« njĂ« ide e keqe tĂ« pĂ«rdorĂ«sh si advertise_uri adresĂ«n 0.0.0.0; duhet tĂ« jetĂ« njĂ« IP e jashtme, jo njĂ« soket i lidhur. Pa tĂ«, asgjĂ« nuk do tĂ« funksionojĂ«, prandaj Cartridge thjesht nuk do tĂ« lejojĂ« tĂ« nisni njĂ« node me njĂ« advertise_uri tĂ« gabuar.
Tani, kur konfigurimi është gati, mund të fillojmë proceset. Duke qenë se një njësi e zakonshme systemd nuk lejon të fillosh më shumë se një proces, aplikacionet në Cartridge vendosin njësi të ashtuquajtura instancuara, të cilat punojnë kështu:
$ sudo systemctl start myapp@router
$ sudo systemctl start myapp@storage_A
$ sudo systemctl start myapp@storage_BNĂ« konfigurim, ne treguam portin HTTP, nĂ« tĂ« cilin Cartridge shĂ«rben ndĂ«rfaqen e uebit â 8080. Le tĂ« hyjmĂ« atje dhe ta shohim:

Vërejmë se proceset janë nisur, por ende nuk janë konfiguruar. Kartoni nuk e di ende kush duhet të replikojë me kë dhe nuk mund të marrë një vendim në mënyrë të pavarur, prandaj po pret veprimet tona. Zgjedhja jonë është e vogël: jeta e klasterit të ri nis me konfigurimin e nyjës së parë. Pastaj do të shtojmë të tjerët në klaster, do t'u caktojmë role dhe atëherë mund të themi se deploy është përfunduar me sukses.
Të derdhim një gotë të pijes sonë të preferuar dhe të relaksohemi pas një java të gjatë pune. Aplikacioni mund të shfrytëzohet.

Përfundimet
Dhe si përfundimet? Provoni, përdorni, lëreni përshtypjet tuaja, krijoni tikete në GitHub.
Linke
[1]
[2]
[3]
[4]
[5]
[6]
Burimi: habr.com
