Ĉe Mail.ru Group ni havas Tarantool - ĉi tio estas aplikaĵoservilo en Lua, kiu ankaŭ duobliĝas kiel datumbazo (aŭ inverse?). Ĝi estas rapida kaj mojosa, sed la kapabloj de unu servilo ankoraŭ ne estas senlimaj. Vertikala skalado ankaŭ ne estas panaceo, do Tarantool havas ilojn por horizontala skalado - la vshard-modulo
Bona novaĵo: ni kolektis kelkajn grandajn pafojn (ekz
Kio ĝuste estas la problemo?
Ni havas tarantulon, ni havas vshard - kion pli vi povus deziri?
Unue, temas pri komforto. La vshard-agordo estas agordita per Lua-tabloj. Por ke distribuita sistemo de pluraj Tarantool-procezoj funkciu ĝuste, la agordo devas esti la sama ĉie. Neniu volas fari ĉi tion permane. Sekve, ĉiaj skriptoj, Ansible kaj deplojsistemoj estas uzataj.
Kartoĉo mem administras la vshard-agordon, ĝi faras tion surbaze de sia propra distribuita agordo. Ĝi estas esence simpla YAML-dosiero, kies kopio estas konservita en ĉiu kazo de Tarantool. La simpligo estas, ke la kadro mem kontrolas sian agordon kaj certigas, ke ĝi estas la sama ĉie.
Due, denove temas pri komforto. La vshard-agordo havas nenion komunan kun la disvolviĝo de komerca logiko kaj nur malatentigas la programiston de sia laboro. Kiam ni diskutas la arkitekturon de projekto, ni plej ofte parolas pri individuaj komponantoj kaj ilia interago. Estas tro frue por pensi pri ruligado de areto al 3 datumcentroj.
Ni solvis ĉi tiujn problemojn denove kaj denove, kaj iam ni sukcesis evoluigi aliron kiu simpligis labori kun la aplikaĵo dum ĝia tuta vivociklo: kreado, evoluo, testado, CI/KD, prizorgado.
Kartoĉo lanĉas la koncepton de rolo por ĉiu Tarantool-procezo. Roloj estas koncepto, kiu permesas al programisto koncentriĝi pri skribado de kodo. Ĉiuj roloj disponeblaj en la projekto povas esti rulitaj sur unu Tarantool-instanco, kaj tio sufiĉos por testoj.
Ĉefaj trajtoj de Tarantool Cartridge:
- aŭtomatigita grapolinstrumentado;
- vastigi la funkciecon de la aplikaĵo uzante novajn rolojn;
- aplikaĵa ŝablono por disvolviĝo kaj disfaldo;
- enkonstruita aŭtomata sharding;
- integriĝo kun la Luatest testa kadro;
- cluster-administrado uzante WebUI kaj API;
- pakado kaj deplojo iloj.
Saluton mondo!
Mi ne povas atendi montri la kadron mem, do ni lasos la rakonton pri la arkitekturo por poste kaj komencos per io simpla. Se ni supozas, ke Tarantool mem jam estas instalita, tiam restas nur fari
$ tarantoolctl rocks install cartridge-cli
$ export PATH=$PWD/.rocks/bin/:$PATH
Ĉi tiuj du komandoj instalos la komandliniajn ilojn kaj permesos al vi krei vian unuan aplikaĵon el la ŝablono:
$ cartridge create --name myapp
Kaj jen kion ni ricevas:
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/
Ĉi tio estas git-deponejo kun preta "Saluton, Mondo!" aplikaĵo. Ni provu ruli ĝin tuj, jam antaŭe instalinte la dependecojn (inkluzive de la kadro mem):
$ tarantoolctl rocks make
$ ./init.lua --http-port 8080
Do, ni havas unu nodon funkcianta por la estonta sharded aplikaĵo. Sciema laiko povas tuj malfermi la retan interfacon, agordi areton de unu nodo per la muso kaj ĝui la rezulton, sed estas tro frue por ĝoji. Ĝis nun, la aplikaĵo ne povas fari ion utilan, do mi rakontos al vi pri deplojo poste, sed nun estas tempo por skribi kodon.
Aplika Disvolviĝo
Nur imagu, ni desegnas projekton, kiu devas ricevi datumojn, konservi ĝin kaj konstrui raporton unufoje tage.
Ni komencas desegni diagramon kaj metas tri komponantojn sur ĝin: enirejo, stokado kaj planilo. Ni plu laboras pri la arkitekturo. Ĉar ni uzas vshard kiel stokadon, ni aldonas vshard-router kaj vshard-storage al la skemo. Nek la enirejo nek la planilo rekte aliros la stokadon; por tio estas la enkursigilo, por tio ĝi estis kreita.
Ĉi tiu diagramo ankoraŭ ne precize reprezentas tion, kion ni konstruos en la projekto ĉar la komponantoj aspektas abstraktaj. Ni ankoraŭ devas vidi kiel ĉi tio estos projekciita sur la realan Tarantool - ni grupigu niajn komponantojn laŭ procezo.
Ne utilas konservi vshard-enkursigilon kaj enirejon en apartaj okazoj. Kial ni bezonas navigi la reton denove se ĉi tio jam estas la respondeco de la enkursigilo? Ili devas esti rulitaj en la sama procezo. Tio estas, kaj enirejo kaj vshard.router.cfg estas pravigitaj en unu procezo, kaj lasas ilin interagi loke.
En la dezajnstadio, estis oportune labori kun tri komponantoj, sed mi, kiel programisto, skribante la kodon, ne volas pensi pri lanĉo de tri ekzemploj de Tarnatool. Mi devas fari testojn kaj kontroli, ke mi skribis ĝuste pordejon. Aŭ eble mi volas montri funkcion al miaj kolegoj. Kial mi devus trairi la ĝenon de deploji tri kopiojn? Tiel naskiĝis la koncepto de roloj. Rolo estas regula luash-modulo, kies vivociklo estas administrita de Cartridge. En ĉi tiu ekzemplo estas kvar el ili - enirejo, enkursigilo, stokado, horaro. Povas esti pli en alia projekto. Ĉiuj roloj povas esti rulitaj en unu procezo, kaj ĉi tio sufiĉos.
Kaj kiam temas pri deplojo al surscenigo aŭ produktado, tiam ni asignos al ĉiu Tarantool-procezo sian propran aron de roloj depende de la aparataj kapabloj:
Topologia administrado
Informoj pri kie, kiuj roloj funkcias, devas esti konservitaj ie. Kaj ĉi tiu "ie" estas la distribuita agordo, kiun mi jam menciis supre. La plej grava afero pri ĝi estas la cluster-topologio. Jen 3 reproduktaj grupoj de 5 Tarantool-procezoj:
Ni ne volas perdi datumojn, do ni zorge traktas informojn pri funkciado de procezoj. Kartoĉo konservas trakon de la agordo uzante dufazan devontigon. Post kiam ni volas ĝisdatigi la agordon, ĝi unue kontrolas, ke ĉiuj okazoj estas disponeblaj kaj pretaj akcepti la novan agordon. Post ĉi tio, la dua fazo aplikas la agordon. Tiel, eĉ se unu kopio montriĝas provizore neatingebla, nenio malbona okazos. La agordo simple ne estos aplikata kaj vi vidos eraron anticipe.
Ankaŭ en la topologia sekcio, tia grava parametro kiel la gvidanto de ĉiu replika grupo estas indikita. Kutime ĉi tio estas la kopio, kiu estas registrita. La ceteraj plej ofte estas nurlegeblaj, kvankam povas esti esceptoj. Kelkfoje kuraĝaj programistoj ne timas konfliktojn kaj povas skribi datumojn al pluraj kopioj paralele, sed ekzistas iuj operacioj, kiuj, ne gravas, ne devus esti faritaj dufoje. Por tio estas signo de gvidanto.
Vivo de roloj
Por ke abstrakta rolo ekzistu en tia arkitekturo, la kadro devas administri ilin iel. Nature, kontrolo okazas sen rekomenco de la Tarantool-procezo. Estas 4 revokoj por administri rolojn. Kartoĉo mem nomos ilin depende de kio estas skribita en sia distribuita agordo, tiel aplikante la agordon al specifaj roloj.
function init()
function validate_config()
function apply_config()
function stop()
Ĉiu rolo havas funkcion init
. Ĝi estas vokita unufoje aŭ kiam la rolo estas ebligita aŭ kiam Tarantool estas rekomencita. Estas oportune tie, ekzemple, pravalorigi box.space.create, aŭ la planilo povas lanĉi iun fonan fibron kiu plenumos laboron je certaj tempintervaloj.
Unu funkcio init
eble ne sufiĉas. Kartoĉo permesas al roloj utiligi la distribuitan konfiguracion, kiun ĝi uzas por stoki la topologion. Ni povas deklari novan sekcion en la sama agordo kaj stoki fragmenton de la komerca agordo en ĝi. En mia ekzemplo, ĉi tio povus esti datuma skemo aŭ horaraj agordoj por la planisto-rolo.
Grapovokoj validate_config
и apply_config
ĉiufoje kiam la distribuita agordo ŝanĝiĝas. Kiam agordo estas aplikata per dufaza kommit, la areto kontrolas, ke ĉiu rolo estas preta akcepti ĉi tiun novan agordon kaj, se necese, raportas eraron al la uzanto. Kiam ĉiuj konsentas, ke la agordo estas normala, tiam la apply_config
.
Ankaŭ roloj havas metodon stop
, kiu estas necesa por purigi la eligon de la rolo. Se ni diras, ke tiu planilo ne plu bezonas en ĉi tiu servilo, ĝi povas haltigi tiujn fibrojn, per kiuj ĝi komencis init
.
Roloj povas interagi unu kun la alia. Ni kutimas skribi funkciovokojn en Lua, sed povas okazi, ke donita procezo ne havas la rolon, kiun ni bezonas. Por faciligi vokojn tra la reto, ni uzas la helpan modulon rpc (fora procedovoko), kiu estas konstruita surbaze de la norma retkesto konstruita en Tarantool. Ĉi tio povas esti utila se, ekzemple, via enirejo volas rekte peti la planiston fari la laboron ĝuste nun, anstataŭ atendi tagon.
Alia grava punkto estas certigi misfunkciadon. Kartoĉo uzas la SWIM-protokolon por monitori sanon
Surbaze de ĉi tiu protokolo, Cartridge organizas aŭtomatan fiaskan prilaboradon. Ĉiu procezo monitoras sian medion, kaj se la gvidanto subite ĉesas respondi, la kopio povas transpreni sian rolon, kaj Cartridge agordas la rulajn rolojn laŭe.
Vi devas esti singarda ĉi tie, ĉar ofta ŝanĝado tien kaj reen povas konduki al datumkonfliktoj dum reproduktado. Kompreneble, vi ne devus ebligi aŭtomatan malsukceson hazarde. Ni devas klare kompreni kio okazas kaj certigi, ke reproduktado ne rompiĝos post kiam la gvidanto estas restarigita kaj la krono estas resendita al li.
De ĉio ĉi, vi eble havas la senton, ke roloj similas al mikroservoj. Iasence, ili estas nur tio, nur kiel moduloj ene de Tarantool-procezoj. Sed estas ankaŭ kelkaj fundamentaj diferencoj. Unue, ĉiuj projektaj roloj devas vivi en la sama kodbazo. Kaj ĉiuj Tarantool-procezoj devus esti lanĉitaj de la sama koda bazo, por ke ne estu surprizoj kiel tiuj kiam ni provas pravalorigi la planilon, sed ĝi simple ne ekzistas. Ankaŭ, vi ne devus permesi diferencojn en kodaj versioj, ĉar la konduto de la sistemo en tia situacio estas tre malfacile antaŭvidi kaj sencimigi.
Male al Docker, ni ne povas simple preni rolon "bildon", preni ĝin al alia maŝino kaj ruli ĝin tie. Niaj roloj ne estas tiel izolitaj kiel Docker-ujoj. Ankaŭ, ni ne povas ruli du identajn rolojn en unu okazo. Rolo aŭ ekzistas aŭ ĝi ne ekzistas; iusence, ĝi estas ununura. Kaj trie, la roloj devas esti la samaj ene de la tuta reprodukta grupo, ĉar alie estus absurde - la datumoj estas la samaj, sed la agordo estas malsama.
Deplojaj iloj
Mi promesis montri kiel Kartoĉo helpas disfaldi aplikaĵojn. Por faciligi la vivon al aliaj, la kadro pakas RPM-pakaĵojn:
$ cartridge pack rpm myapp -- упакует для нас ./myapp-0.1.0-1.rpm
$ sudo yum install ./myapp-0.1.0-1.rpm
La instalita pako enhavas preskaŭ ĉion, kion vi bezonas: kaj la aplikaĵon kaj la instalitajn dependecojn. Tarantool ankaŭ alvenos al la servilo kiel dependeco de la RPM-pakaĵo, kaj nia servo estas preta lanĉi. Ĉi tio estas farita per systemd, sed unue vi devas skribi etan agordon. Minimume, specifu la URI de ĉiu procezo. Tri sufiĉas ekzemple.
$ 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
Estas interesa nuanco ĉi tie. Anstataŭ specifi nur la binaran protokolhavenon, ni specifas la tutan publikan adreson de la procezo inkluzive de la gastiga nomo. Ĉi tio estas necesa por ke la grapolnodoj sciu kiel konekti unu al la alia. Estas malbona ideo uzi 0.0.0.0 kiel la advertise_uri-adreson; ĝi devus esti ekstera IP-adreso, ne socket-ligado. Sen ĝi, nenio funkcios, do Cartridge simple ne lasos vin lanĉi nodon kun malĝusta advertise_uri.
Nun kiam la agordo estas preta, vi povas komenci la procezojn. Ĉar regula systemd-unuo ne permesas pli ol unu procezon komenci, aplikoj sur la Kartoĉo estas instalitaj de la tn. instantigitaj unuoj kiuj funkcias tiel:
$ sudo systemctl start myapp@router
$ sudo systemctl start myapp@storage_A
$ sudo systemctl start myapp@storage_B
En la agordo, ni specifis la HTTP-havenon, sur kiu Kartoĉo servas la retinterfacon - 8080. Ni iru al ĝi kaj rigardu:
Ni vidas, ke kvankam la procezoj funkcias, ili ankoraŭ ne estas agorditaj. La kartoĉo ankoraŭ ne scias, kiu devus reprodukti kun kiu kaj ne povas fari decidon memstare, do ĝi atendas niajn agojn. Sed ni ne havas multe da elekto: la vivo de nova areto komenciĝas per la agordo de la unua nodo. Tiam ni aldonos la aliajn al la areto, asignos al ili rolojn, kaj ĉe ĉi tiu punkto la disfaldiĝo povas esti konsiderata sukcese finita.
Ni verŝu glason da via plej ŝatata trinkaĵo kaj malstreĉu post longa laborsemajno. La aplikaĵo povas esti uzata.
Rezultoj
Kio estas la rezultoj? Provu ĝin, uzu ĝin, lasu komentojn, kreu biletojn sur Github.
referencoj
[1]
fonto: www.habr.com