Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

Meil on Mail.ru Groupis Tarantool - see on Lua rakendusserver, mis toimib ka andmebaasina (või vastupidi?). See on kiire ja lahe, kuid ühe serveri võimalused pole siiski piiramatud. Vertikaalne skaleerimine pole ka imerohi, seega on Tarantoolil horisontaalse skaleerimise tööriistad – vshardi moodul [1]. See võimaldab teil andmeid killustada mitme serveri vahel, kuid selle seadistamiseks ja äriloogika kinnitamiseks peate selle kallal nokitsema.

Hea uudis: oleme kogunud mõned suured kaadrid (nt [2], [3]) ja lõi teise raamistiku, mis lihtsustab oluliselt selle probleemi lahendust.

Tarantooli kassett on uus raamistik keeruliste hajutatud süsteemide arendamiseks. See võimaldab infrastruktuuriprobleemide lahendamise asemel keskenduda äriloogika kirjutamisele. Lõike all räägin teile, kuidas see raamistik töötab ja kuidas seda kasutades hajutatud teenuseid kirjutada.

Milles täpselt probleem seisneb?

Meil on tarantel, meil on vshard - mida veel tahta?

Esiteks on see mugavuse küsimus. Vshardi konfiguratsioon konfigureeritakse Lua tabelite kaudu. Mitmest Tarantooli protsessist koosneva hajutatud süsteemi õigeks toimimiseks peab konfiguratsioon olema kõikjal sama. Keegi ei taha seda käsitsi teha. Seetõttu kasutatakse igasuguseid skripte, Ansible ja juurutussüsteeme.

Kassett ise haldab vshardi konfiguratsiooni, teeb seda selle põhjal enda hajutatud konfiguratsioon. See on sisuliselt lihtne YAML-fail, mille koopia on salvestatud igasse Tarantooli eksemplari. Lihtsus seisneb selles, et raamistik ise jälgib selle konfiguratsiooni ja tagab, et see on kõikjal ühesugune.

Teiseks on see jällegi mugavuse küsimus. Vshardi konfiguratsioonil pole äriloogika arendamisega mingit pistmist ja see tõmbab programmeerija tähelepanu ainult tema töölt kõrvale. Kui arutame projekti arhitektuuri, räägime kõige sagedamini üksikutest komponentidest ja nende koostoimest. On liiga vara mõelda klastri kasutuselevõtule kolmele andmekeskusele.

Lahendasime neid probleeme ikka ja jälle ning mingil hetkel õnnestus meil välja töötada lähenemine, mis lihtsustas rakendusega töötamist kogu selle elutsükli jooksul: loomine, arendus, testimine, CI/CD, hooldus.

Kassett tutvustab iga Tarantooli protsessi jaoks rolli kontseptsiooni. Rollid on kontseptsioon, mis võimaldab arendajal keskenduda koodi kirjutamisele. Kõiki projektis saadaolevaid rolle saab käivitada ühes Tarantooli eksemplaris ja sellest piisab testideks.

Tarantooli kasseti peamised omadused:

  • automatiseeritud klastri orkestreerimine;
  • rakenduse funktsionaalsuse laiendamine uute rollide abil;
  • rakenduse mall arendamiseks ja juurutamiseks;
  • sisseehitatud automaatne killustik;
  • integreerimine Luatesti testimisraamistikuga;
  • klastri haldamine WebUI ja API abil;
  • pakendamise ja juurutamise tööriistad.

Tere, Maailm!

Ma ei jõua ära oodata, millal saab raamistikku ennast näidata, seega jätame arhitektuuriloo hilisemaks ja alustame millegi lihtsaga. Kui eeldame, et Tarantool ise on juba installitud, siis jääb üle vaid teha

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

Need kaks käsku installivad käsurea utiliidid ja võimaldavad teil mallist luua oma esimese rakenduse:

$ cartridge create --name myapp

Ja see on see, mida me saame:

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/

See on git-hoidla, millel on valmis tekst "Tere, maailm!" rakendus. Proovime seda kohe käivitada, olles eelnevalt installinud sõltuvused (sh raamistik ise):

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

Seega on meil tulevase killustatud rakenduse jaoks üks sõlm. Uudishimulik võhik saab kohe avada veebiliidese, konfigureerida hiirega ühe sõlme klastri ja nautida tulemust, kuid rõõmustada on veel vara. Siiani ei saa rakendus midagi kasulikku teha, seega räägin teile juurutamisest hiljem, kuid nüüd on aeg kood kirjutada.

Rakenduste arendamine

Kujutage ette, me kavandame projekti, mis peab kord päevas andmeid vastu võtma, salvestama ja koostama aruande.

Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

Alustame diagrammi joonistamist ja asetame sellele kolm komponenti: lüüs, salvestusruum ja ajakava. Töötame arhitektuuri kallal edasi. Kuna kasutame salvestusruumina vshardi, lisame skeemi vshard-ruuteri ja vshard-storage. Lüüs ega ajakava ei pääse otse salvestusruumi juurde; selleks ruuter on mõeldud, selleks see loodi.

Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

See diagramm ei kajasta ikka veel täpselt seda, mida me projektis ehitame, kuna komponendid näevad välja abstraktsed. Peame veel nägema, kuidas see tegelikule Tarantoolile projitseeritakse – rühmitame oma komponendid protsesside kaupa.

Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

Pole mõtet hoida vshard-ruuterit ja lüüsi eraldi eksemplaridel. Miks me peame veel kord võrgus surfama, kui see on juba ruuteri kohustus? Neid tuleb käivitada sama protsessi raames. See tähendab, et nii lüüs kui ka vshard.router.cfg lähtestatakse ühes protsessis ja võimaldavad neil lokaalselt suhelda.

Projekteerimisetapis oli mugav töötada kolme komponendiga, kuid mina kui arendaja ei taha koodi kirjutades mõelda kolme Tarnatooli eksemplari käivitamisele. Pean käivitama testid ja kontrollima, kas kirjutasin lüüsi õigesti. Või äkki tahan oma kolleegidele mõnda omadust demonstreerida. Miks ma peaksin kolme koopia kasutuselevõtuga vaeva nägema? Nii sündis rollide kontseptsioon. Roll on tavaline luashi moodul, mille elutsüklit haldab Cartridge. Selles näites on neid neli - lüüs, ruuter, salvestusruum, planeerija. Mõnes teises projektis võib olla rohkem. Kõiki rolle saab täita ühe protsessiga ja sellest piisab.

Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

Ja mis puudutab lavastamise või tootmise juurutamist, siis määrame igale Tarantooli protsessile sõltuvalt riistvara võimalustest oma rollid:

Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

Topoloogia haldamine

Teave selle kohta, kus millised rollid töötavad, tuleb kuskil salvestada. Ja see "kusagil" on hajutatud konfiguratsioon, mida ma juba eespool mainisin. Kõige olulisem selle juures on klastri topoloogia. Siin on 3 Tarantooli protsessi 5 replikatsioonirühma:

Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

Me ei taha andmeid kaotada, seetõttu käsitleme jooksvate protsesside teavet ettevaatlikult. Kassett jälgib konfiguratsiooni kahefaasilise kinnituse abil. Kui soovime konfiguratsiooni värskendada, kontrollib see esmalt, et kõik eksemplarid on saadaval ja valmis uue konfiguratsiooni vastuvõtmiseks. Pärast seda rakendab teine ​​faas konfiguratsiooni. Seega, isegi kui üks eksemplar osutub ajutiselt kättesaamatuks, ei juhtu midagi hullu. Konfiguratsiooni lihtsalt ei rakendata ja näete eelnevalt viga.

Ka topoloogia jaotises on märgitud selline oluline parameeter nagu iga replikatsioonirühma juht. Tavaliselt on see koopia, mida salvestatakse. Ülejäänud on enamasti kirjutuskaitstud, kuigi võib olla ka erandeid. Mõnikord ei karda julged arendajad konflikte ja võivad kirjutada andmeid paralleelselt mitmesse koopiasse, kuid on mõned toimingud, mida ei tohiks kaks korda teha. Selle jaoks on juhi märk.

Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

Rollide elu

Abstraktse rolli olemasoluks sellises arhitektuuris peab raamistik neid kuidagi haldama. Loomulikult toimub kontroll ilma Tarantooli protsessi taaskäivitamiseta. Rollide haldamiseks on 4 tagasihelistamist. Kassett ise helistab neile sõltuvalt sellest, mis on kirjutatud selle hajutatud konfiguratsioonis, rakendades seeläbi konfiguratsiooni konkreetsetele rollidele.

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

Igal rollil on funktsioon init. Seda kutsutakse üks kord, kui roll on lubatud või kui Tarantool taaskäivitatakse. Seal on mugav näiteks initsialiseerida box.space.create või saab planeerija käivitada mõne taustakiu, mis teatud ajavahemike järel tööd teeb.

Üks funktsioon init ei pruugi piisata. Kassett võimaldab rollidel kasutada ära hajutatud konfiguratsiooni, mida ta kasutab topoloogia salvestamiseks. Saame samas konfiguratsioonis deklareerida uue jaotise ja salvestada selles fragmendi ärikonfiguratsioonist. Minu näites võib selleks olla plaanija rolli andmeskeem või ajakava sätted.

Klastrikõned validate_config и apply_config iga kord, kui hajutatud konfiguratsioon muutub. Kui konfiguratsiooni rakendatakse kahefaasilise kinnistamise abil, kontrollib klaster, kas iga roll on uue konfiguratsiooni vastuvõtmiseks valmis, ja vajadusel teatab kasutajale veast. Kui kõik nõustuvad, et konfiguratsioon on normaalne, siis apply_config.

Ka rollidel on oma meetod stop, mida on vaja rolli väljundi puhastamiseks. Kui ütleme, et selles serveris pole plaanijat enam vaja, võib see peatada need kiud, millega ta alustas init.

Rollid võivad üksteisega suhelda. Oleme harjunud Luas funktsioonikutseid kirjutama, kuid võib juhtuda, et antud protsessil pole meile vajalikku rolli. Üle võrgu kõnede hõlbustamiseks kasutame rpc (remote procedur call) abimoodulit, mis on ehitatud Tarantooli sisse ehitatud standardse netboxi baasil. See võib olla kasulik näiteks siis, kui teie lüüs soovib päeva ootamise asemel paluda planeerijal töö kohe ära teha.

Teine oluline punkt on veataluvuse tagamine. Kassett kasutab tervise jälgimiseks SWIM-protokolli [4]. Lühidalt öeldes vahetavad protsessid UDP kaudu üksteisega "kuulujutte" - iga protsess edastab oma naabritele viimaseid uudiseid ja nad vastavad. Kui ühtäkki vastust ei tule, hakkab Tarantool kahtlustama, et midagi on valesti, ning mõne aja pärast loeb surma ja hakkab sellest uudisest rääkima kõigile.

Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

Selle protokolli alusel korraldab Cartridge automaatse rikete töötlemise. Iga protsess jälgib oma keskkonda ja kui juht äkitselt reageerimise lõpetab, võib koopia oma rolli üle võtta ja Cartridge konfigureerib jooksvad rollid vastavalt.

Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

Siin peate olema ettevaatlik, sest sagedane edasi-tagasi vahetamine võib replikatsiooni ajal põhjustada andmekonflikte. Loomulikult ei tohiks te juhuslikku automaatset tõrkesiiret lubada. Peame selgelt aru saama, mis toimub, ja olema kindlad, et replikatsioon ei purune pärast juhi taastamist ja krooni tagastamist.

Sellest kõigest võib tekkida tunne, et rollid sarnanevad mikroteenustega. Teatud mõttes on nad just sellised, ainult moodulitena Tarantooli protsessides. Kuid on ka mitmeid põhimõttelisi erinevusi. Esiteks peavad kõik projektirollid elama samas koodibaasis. Ja kõik Tarantooli protsessid tuleks käivitada samast koodibaasist, et ei tekiks selliseid üllatusi, kui proovime planeerijat lähtestada, kuid seda lihtsalt pole. Samuti ei tohiks lubada koodiversioonide erinevusi, sest süsteemi käitumist on sellises olukorras väga raske ennustada ja siluda.

Erinevalt Dockerist ei saa me lihtsalt rolli "pilti" võtta, viia seda teise masinasse ja seal käivitada. Meie rollid ei ole nii isoleeritud kui Dockeri konteinerid. Samuti ei saa me ühel eksemplaril käitada kahte identset rolli. Roll kas on olemas või ei ole; teatud mõttes on see üksik. Ja kolmandaks, rollid peavad olema samad kogu replikatsioonigrupi sees, sest muidu oleks see absurd – andmed on samad, aga konfiguratsioon erinev.

Juurutustööriistad

Lubasin näidata, kuidas Cartridge aitab rakendusi juurutada. Teiste elu hõlbustamiseks pakib raamistik RPM-pakette:

$ cartridge pack rpm myapp -- упакует для нас ./myapp-0.1.0-1.rpm
$ sudo yum install ./myapp-0.1.0-1.rpm

Paigaldatud pakett sisaldab peaaegu kõike, mida vajate: nii rakendust kui ka installitud sõltuvusi. Tarantool jõuab serverisse ka RPM-paketi sõltuvusena ja meie teenus on käivitamiseks valmis. Seda tehakse systemd kaudu, kuid kõigepealt peate kirjutama väikese konfiguratsiooni. Määrake vähemalt iga protsessi URI. Piisab näiteks kolmest.

$ 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

Siin on huvitav nüanss. Selle asemel, et määrata ainult binaarprotokolli port, määrame protsessi kogu avaliku aadressi, sealhulgas hostinime. See on vajalik selleks, et klastri sõlmed teaksid, kuidas üksteisega ühendust luua. Halb mõte on reklaami_uri aadressina kasutada aadressi 0.0.0.0; see peaks olema väline IP-aadress, mitte pesaühendus. Ilma selleta ei tööta miski, nii et Cartridge lihtsalt ei lase teil käivitada sõlme vale reklaami_uriga.

Nüüd, kui konfiguratsioon on valmis, saate protsesse alustada. Kuna tavaline süsteemne seade ei lase käivituda rohkem kui ühte protsessi, siis installitakse Kassetile olevad rakendused nn. instanteeritud üksused, mis töötavad järgmiselt:

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

Konfiguratsioonis määrasime HTTP-pordi, millel Cartridge veebiliidest teenindab - 8080. Läheme selle juurde ja vaatame:

Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

Näeme, et kuigi protsessid töötavad, pole need veel konfigureeritud. Kassett ei tea veel, kes kellega kopeerima peaks ja ei saa ise otsust langetada, seega ootab ta meie tegusid. Kuid meil pole palju valikut: uue klastri eluiga algab esimese sõlme konfigureerimisest. Seejärel lisame teised klastrisse, määrame neile rollid ja siinkohal võib juurutamise lugeda edukalt lõpetatuks.

Valame klaasi sinu lemmikjooki ja lõõgastume pärast pikka töönädalat. Rakendust saab kasutada.

Tarantooli kassett: Lua taustaprogrammi jagamine kolmes reas

Tulemused

Millised on tulemused? Proovige seda, kasutage seda, jätke tagasisidet, looge pileteid Githubis.

Viited

[1] Tarantool » 2.2 » Viide » Kivimite viide » Moodul vshard

[2] Kuidas me Tarantoolil põhineva Alfa-Panga investeerimisäri tuuma juurutasime

[3] Uue põlvkonna arveldusarhitektuur: ümberkujundamine üleminekuga Tarantoolile

[4] SWIM – klastri ehitamise protokoll

[5] GitHub – tarantool/kassett-cli

[6] GitHub – tarantool/kassett

Allikas: www.habr.com

Lisa kommentaar