Tarantool Cartridge: sharding Lua backend en tri linioj

Tarantool Cartridge: sharding Lua backend en tri linioj

Ĉ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 [1]. Ĝi permesas vin dividi datumojn tra pluraj serviloj, sed vi devas tuŝi ĝin por agordi ĝin kaj kunligi la komercan logikon.

Bona novaĵo: ni kolektis kelkajn grandajn pafojn (ekz [2], [3]) kaj kreis alian kadron, kiu signife simpligos la solvon de tiu ĉi problemo.

Tarantool Kartoĉo estas nova kadro por disvolvi kompleksajn distribuitajn sistemojn. Ĝi permesas vin koncentriĝi pri skribi komercan logikon anstataŭ solvi infrastrukturajn problemojn. Sub la tranĉo mi rakontos al vi kiel ĉi tiu kadro funkcias kaj kiel verki distribuitajn servojn uzante ĝin.

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.

Tarantool Cartridge: sharding Lua backend en tri linioj

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.

Tarantool Cartridge: sharding Lua backend en tri linioj

Ĉ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.

Tarantool Cartridge: sharding Lua backend en tri linioj

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.

Tarantool Cartridge: sharding Lua backend en tri linioj

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:

Tarantool Cartridge: sharding Lua backend en tri linioj

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:

Tarantool Cartridge: sharding Lua backend en tri linioj

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.

Tarantool Cartridge: sharding Lua backend en tri linioj

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 [4]. Resume, procezoj interŝanĝas "onidirojn" inter si super UDP—ĉiu procezo rakontas al siaj najbaroj la plej novajn novaĵojn, kaj ili respondas. Se subite la respondo ne venas, Tarantool komencas suspekti, ke io estas malĝusta, kaj post iom da tempo ĝi deklamas morton kaj komencas rakonti al ĉiuj ĉi tiun novaĵon.

Tarantool Cartridge: sharding Lua backend en tri linioj

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.

Tarantool Cartridge: sharding Lua backend en tri linioj

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:

Tarantool Cartridge: sharding Lua backend en tri linioj

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.

Tarantool Cartridge: sharding Lua backend en tri linioj

Rezultoj

Kio estas la rezultoj? Provu ĝin, uzu ĝin, lasu komentojn, kreu biletojn sur Github.

referencoj

[1] Tarantool » 2.2 » Referenco » Rokoj-referenco » Modulo vshard

[2] Kiel ni efektivigis la kernon de la investa komerco de Alfa-Banko bazita sur Tarantool

[3] Novgeneracia faktura arkitekturo: transformo kun la transiro al Tarantool

[4] SWIM - protokolo pri konstruo de aretoj

[5] GitHub - tarantool/cartridge-cli

[6] GitHub - tarantool/kartoĉo

fonto: www.habr.com

Aldoni komenton