Pri Mail.ru Group imamo Tarantool - to je aplikacijski strežnik v Lui, ki deluje tudi kot zbirka podatkov (ali obratno?). Je hiter in kul, vendar zmogljivosti enega strežnika še vedno niso neomejene. Tudi vertikalno skaliranje ni zdravilo, zato ima Tarantool orodja za horizontalno skaliranje – modul vshard
Dobra novica: zbrali smo nekaj velikih posnetkov (npr
Kaj točno je problem?
Imamo tarantelo, imamo vshard - kaj več bi si lahko želeli?
Prvič, to je stvar udobja. Konfiguracija vshard je konfigurirana prek tabel Lua. Da porazdeljeni sistem več procesov Tarantool deluje pravilno, mora biti konfiguracija povsod enaka. Nihče ne želi tega narediti ročno. Zato se uporabljajo vse vrste skriptov, Ansible in sistemi za uvajanje.
Kartuša sama upravlja konfiguracijo vshard, to počne na podlagi svojega lastno porazdeljeno konfiguracijo. To je v bistvu preprosta datoteka YAML, katere kopija je shranjena v vsakem primerku Tarantoola. Poenostavitev je v tem, da ogrodje samo spremlja svojo konfiguracijo in zagotavlja, da je povsod enaka.
Drugič, spet gre za udobje. Konfiguracija vshard nima nobene zveze z razvojem poslovne logike in samo odvrača programerja od njegovega dela. Ko govorimo o arhitekturi projekta, največkrat govorimo o posameznih komponentah in njihovi interakciji. Prezgodaj je razmišljati o uvedbi gruče v 3 podatkovne centre.
Te težave smo reševali znova in znova in na neki točki nam je uspelo razviti pristop, ki je poenostavil delo z aplikacijo v celotnem življenjskem ciklu: ustvarjanje, razvoj, testiranje, CI/CD, vzdrževanje.
Cartridge uvaja koncept vloge za vsak proces Tarantool. Vloge so koncept, ki razvijalcu omogoča, da se osredotoči na pisanje kode. Vse vloge, ki so na voljo v projektu, je mogoče izvajati na eni instanci Tarantoola in to bo dovolj za teste.
Glavne lastnosti Tarantool Cartridge:
- avtomatizirana orkestracija grozdov;
- razširitev funkcionalnosti aplikacije z uporabo novih vlog;
- predloga aplikacije za razvoj in uvajanje;
- vgrajeno samodejno drobljenje;
- integracija z ogrodjem za testiranje Luatest;
- upravljanje gruče z uporabo spletnega uporabniškega vmesnika in API-ja;
- orodja za pakiranje in uvajanje.
Pozdravljen, svet!
Komaj čakam, da pokažem sam okvir, zato bomo zgodbo o arhitekturi pustili za kasneje in začeli z nečim preprostim. Če predpostavimo, da je Tarantool sam že nameščen, potem je vse, kar ostane, narediti
$ tarantoolctl rocks install cartridge-cli
$ export PATH=$PWD/.rocks/bin/:$PATH
Ta dva ukaza bosta namestila pripomočke ukazne vrstice in vam omogočila, da ustvarite svojo prvo aplikacijo iz predloge:
$ cartridge create --name myapp
In tole dobimo:
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/
To je repozitorij git z že pripravljenim »Hello, World!« aplikacija. Poskusimo ga zagnati takoj, ko smo predhodno namestili odvisnosti (vključno s samim ogrodjem):
$ tarantoolctl rocks make
$ ./init.lua --http-port 8080
Torej imamo eno vozlišče, ki teče za prihodnjo razdeljeno aplikacijo. Radovedni laik lahko takoj odpre spletni vmesnik, z miško konfigurira gručo enega vozlišča in uživa v rezultatu, vendar je še prezgodaj za veselje. Zaenkrat aplikacija ne more narediti nič uporabnega, zato vam bom kasneje povedal o uvajanju, zdaj pa je čas za pisanje kode.
Razvoj aplikacij
Predstavljajte si, načrtujemo projekt, ki mora prejemati podatke, jih shranjevati in sestaviti poročilo enkrat na dan.
Začnemo risati diagram in nanj postavimo tri komponente: prehod, shrambo in planer. Nadaljujemo z arhitekturo. Ker uporabljamo vshard kot shrambo, shemi dodamo vshard-router in vshard-storage. Niti prehod niti razporejevalnik ne bosta neposredno dostopala do pomnilnika; usmerjevalnik je temu namenjen, za to je bil ustvarjen.
Ta diagram še vedno ne predstavlja natančno tega, kar bomo zgradili v projektu, ker so komponente videti abstraktno. Še vedno moramo videti, kako bo to projicirano na pravi Tarantool - združimo naše komponente po postopku.
Nima smisla obdržati vshard-router in prehod na ločenih instancah. Zakaj moramo še enkrat brskati po omrežju, če je to že odgovornost usmerjevalnika? Izvajati jih je treba znotraj istega procesa. To pomeni, da sta prehod in vshard.router.cfg inicializirana v enem procesu in ju pustita, da delujeta lokalno.
V fazi načrtovanja je bilo priročno delati s tremi komponentami, vendar jaz kot razvijalec med pisanjem kode ne želim razmišljati o zagonu treh primerkov Tarnatoola. Opraviti moram teste in preveriti, ali sem pravilno napisal prehod. Ali pa bi morda želel predstaviti funkcijo svojim kolegom. Zakaj bi moral iti skozi težave z uvajanjem treh kopij? Tako se je rodil koncept vlog. Vloga je običajni modul luash, katerega življenjski cikel upravlja Cartridge. V tem primeru so štirje - prehod, usmerjevalnik, shramba, razporejevalnik. Morda jih bo več v drugem projektu. Vse vloge se lahko izvajajo v enem procesu in to bo dovolj.
In ko gre za uvajanje v uprizoritev ali produkcijo, bomo vsakemu procesu Tarantool dodelili svoj niz vlog, odvisno od zmogljivosti strojne opreme:
Upravljanje topologije
Informacije o tem, kje se izvajajo katere vloge, morajo biti nekje shranjene. In to »nekje« je porazdeljena konfiguracija, ki sem jo že omenil zgoraj. Najpomembnejša stvar pri tem je topologija gruče. Tukaj so 3 replikacijske skupine 5 procesov Tarantool:
Ne želimo izgubiti podatkov, zato z informacijami o tekočih procesih ravnamo skrbno. Kartuša spremlja konfiguracijo z uporabo dvofazne potrditve. Ko želimo posodobiti konfiguracijo, najprej preveri, ali so vsi primerki na voljo in pripravljeni sprejeti novo konfiguracijo. Po tem druga faza uporabi konfiguracijo. Torej, tudi če se izkaže, da en izvod začasno ni na voljo, se ne bo zgodilo nič slabega. Konfiguracija preprosto ne bo uporabljena in vnaprej boste videli napako.
Tudi v razdelku o topologiji je naveden tako pomemben parameter, kot je vodja vsake replikacijske skupine. Običajno je to kopija, ki se snema. Ostali so najpogosteje samo za branje, čeprav lahko obstajajo izjeme. Včasih se pogumni razvijalci ne bojijo konfliktov in lahko zapisujejo podatke v več replik vzporedno, vendar obstajajo nekatere operacije, ki jih ne glede na vse ne bi smeli izvajati dvakrat. Za to obstaja znak vodje.
Življenje vlog
Da bi v takšni arhitekturi obstajala abstraktna vloga, jo mora okvir nekako upravljati. Seveda se nadzor izvede brez ponovnega zagona procesa Tarantool. Za upravljanje vlog so na voljo 4 povratni klici. Kartuša sama jih bo poklicala glede na to, kaj je zapisano v njeni porazdeljeni konfiguraciji, s čimer bo konfiguracijo uporabila za določene vloge.
function init()
function validate_config()
function apply_config()
function stop()
Vsaka vloga ima svojo funkcijo init
. Pokliče se enkrat, ko je vloga omogočena ali ko se Tarantool znova zažene. Tam je priročno na primer inicializirati box.space.create ali pa lahko razporejevalnik zažene neko vlakno v ozadju, ki bo opravilo delo v določenih časovnih intervalih.
Ena funkcija init
morda ne bo dovolj. Kartuša omogoča vlogam, da izkoristijo porazdeljeno konfiguracijo, ki jo uporablja za shranjevanje topologije. V isti konfiguraciji lahko deklariramo nov razdelek in vanj shranimo delček poslovne konfiguracije. V mojem primeru je to lahko podatkovna shema ali nastavitve urnika za vlogo načrtovalca.
Grozdni klici validate_config
и apply_config
vsakič, ko se porazdeljena konfiguracija spremeni. Ko se konfiguracija uporabi z dvofazno potrditvijo, gruča preveri, ali je vsaka vloga pripravljena sprejeti to novo konfiguracijo, in po potrebi sporoči uporabniku napako. Ko se vsi strinjajo, da je konfiguracija normalna, potem je apply_config
.
Tudi vloge imajo metodo stop
, ki je potreben za čiščenje izpisa vloge. Če rečemo, da razporejevalnik na tem strežniku ni več potreben, lahko ustavi tista vlakna, s katerimi je začel init
.
Vloge lahko medsebojno delujejo. Navajeni smo pisanja funkcijskih klicev v Lui, vendar se lahko zgodi, da dani proces nima vloge, ki jo potrebujemo. Za lažje klice po omrežju uporabljamo pomožni modul rpc (remote procedure call), ki je zgrajen na osnovi standardnega netboxa, vgrajenega v Tarantool. To je lahko uporabno, če želi na primer vaš prehod neposredno od načrtovalca zahtevati, da opravi delo zdaj, namesto da čaka en dan.
Druga pomembna točka je zagotavljanje tolerance napak. Kartuša uporablja protokol SWIM za spremljanje zdravja
Na podlagi tega protokola Cartridge organizira samodejno obdelavo napak. Vsak proces spremlja svoje okolje in če se vodilni nenadoma neha odzivati, lahko replika prevzame njegovo vlogo, Cartridge pa ustrezno konfigurira tekoče vloge.
Pri tem morate biti previdni, saj lahko pogosto preklapljanje naprej in nazaj povzroči spore podatkov med replikacijo. Seveda ne bi smeli naključno omogočiti samodejnega preklopa. Jasno moramo razumeti, kaj se dogaja, in biti prepričani, da se replikacija ne bo prekinila, ko bo vodja obnovljen in mu bo vrnjena krona.
Iz vsega tega boste morda dobili občutek, da so vloge podobne mikrostoritvam. V nekem smislu so prav to, samo kot moduli znotraj procesov Tarantool. Obstaja pa tudi vrsta temeljnih razlik. Prvič, vse projektne vloge morajo živeti v isti osnovi kode. In vsi Tarantool procesi bi se morali zagnati iz iste kodne baze, da ne bi prišlo do presenečenj, kot so tista, ko poskušamo inicializirati razporejevalnik, pa ga preprosto ni. Prav tako ne smete dovoliti razlik v različicah kode, ker je obnašanje sistema v takšni situaciji zelo težko predvideti in odpraviti napake.
Za razliko od Dockerja ne moremo preprosto vzeti "slike" vloge, jo odnesti na drug stroj in tam zagnati. Naše vloge niso tako izolirane kot vsebniki Docker. Prav tako ne moremo izvajati dveh enakih vlog na enem primerku. Vloga bodisi obstaja ali pa je ne; v nekem smislu je ena oseba. In tretjič, vloge morajo biti enake znotraj celotne replikacijske skupine, saj bi bilo sicer absurdno – podatki so isti, konfiguracija pa drugačna.
Orodja za uvajanje
Obljubil sem, da bom pokazal, kako Cartridge pomaga pri uvajanju aplikacij. Da bi olajšali življenje drugim, okvir vsebuje pakete RPM:
$ cartridge pack rpm myapp -- упакует для нас ./myapp-0.1.0-1.rpm
$ sudo yum install ./myapp-0.1.0-1.rpm
Nameščen paket vsebuje skoraj vse, kar potrebujete: tako aplikacijo kot nameščene odvisnosti. Tarantool bo prispel tudi na strežnik kot odvisnost od paketa RPM in naša storitev je pripravljena za zagon. To se naredi prek systemd, vendar morate najprej napisati nekaj konfiguracije. Določite vsaj URI vsakega procesa. Dovolj so na primer trije.
$ 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
Tukaj je zanimiva niansa. Namesto da podamo samo vrata binarnega protokola, podamo celoten javni naslov procesa, vključno z imenom gostitelja. To je potrebno, da se vozlišča gruče med seboj vedo, kako se povezati. Slaba ideja je, da kot naslov advertise_uri uporabite 0.0.0.0; to bi moral biti zunanji naslov IP in ne vezava vtičnice. Brez tega nič ne bo delovalo, zato vam Cartridge preprosto ne bo dovolil zagnati vozlišča z napačnim advertise_uri.
Zdaj, ko je konfiguracija pripravljena, lahko začnete s procesi. Ker navadna sistemska enota ne dovoljuje zagona več kot enega procesa, se aplikacije na Cartridge namestijo po t.i. instancirane enote, ki delujejo takole:
$ sudo systemctl start myapp@router
$ sudo systemctl start myapp@storage_A
$ sudo systemctl start myapp@storage_B
V konfiguraciji smo določili vrata HTTP, na katerih Cartridge streže spletni vmesnik - 8080. Pojdimo nanj in si oglejmo:
Vidimo, da čeprav se procesi izvajajo, še niso konfigurirani. Kartuša še ne ve, kdo naj se pri kom replicira in se ne more sama odločiti, zato čaka na naša dejanja. Vendar nimamo veliko izbire: življenje nove gruče se začne s konfiguracijo prvega vozlišča. Nato bomo druge dodali v gručo, jim dodelili vloge in na tej točki se lahko šteje, da je uvedba uspešno zaključena.
Natočimo si kozarček vaše najljubše pijače in se sprostimo po dolgem delovnem tednu. Aplikacijo je mogoče uporabiti.
Rezultati
Kakšni so rezultati? Preizkusite, uporabite, pustite povratne informacije, ustvarite vstopnice na Githubu.
reference
[1]
Vir: www.habr.com