Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

Bei Mail.ru Group hu mir Tarantool - dëst ass en Applikatiounsserver am Lua, deen och als Datebank verduebelt (oder vice versa?). Et ass séier a cool, awer d'Fäegkeete vun engem Server sinn nach ëmmer net onlimitéiert. Vertikal Skalen ass och keng Panacea, sou datt Tarantool Tools fir horizontal Skalen huet - de vshard Modul [1]. Et erlaabt Iech Daten iwwer e puer Serveren ze zerstéieren, awer Dir musst matmaachen fir se opzestellen an d'Geschäftslogik ze befestigen.

Gutt Noriicht: Mir hunn e puer grouss Schëss gesammelt (z.B [2], [3]) an en anere Kader erstallt deen d'Léisung fir dëse Problem wesentlech vereinfacht.

Tarantool Cartouche ass en neie Kader fir komplex verdeelt Systemer z'entwéckelen. Et erlaabt Iech ze fokusséieren op Geschäftslogik ze schreiwen anstatt Infrastrukturproblemer ze léisen. Ënnert dem Schnëtt wäert ech Iech soen wéi dëse Kader funktionnéiert a wéi Dir verdeelt Servicer benotzt.

Wat ass genee de Problem?

Mir hunn eng Tarantel, mir hunn vshard - wat méi wëllt Dir?

Als éischt ass et eng Saach vu Komfort. D'vshard Konfiguratioun ass duerch Lua Dëscher konfiguréiert. Fir datt e verdeelt System vu multiple Tarantool Prozesser korrekt funktionnéiert, muss d'Konfiguratioun iwwerall d'selwecht sinn. Keen wëll dat manuell maachen. Dofir ginn all Zorte vu Scripten, Ansible an Deploymentsystemer benotzt.

Cartouche selwer geréiert der vshard Configuratioun, et mécht dat baséiert op seng eege verdeelt Configuratioun. Et ass am Wesentlechen eng einfach YAML Datei, eng Kopie vun deenen an all Tarantool Instanz gespäichert ass. D'Vereinfachung ass datt de Kader selwer seng Konfiguratioun iwwerwaacht a garantéiert datt et iwwerall d'selwecht ass.

Zweetens ass et erëm eng Saach vu Komfort. D'vshard Konfiguratioun huet näischt mat der Entwécklung vun der Geschäftslogik ze dinn an distractéiert nëmmen de Programméierer vu senger Aarbecht. Wa mir d'Architektur vun engem Projet diskutéieren, schwätze mir meeschtens iwwer eenzel Komponenten an hir Interaktioun. Et ass ze fréi ze denken iwwer d'Ausrollung vun engem Cluster an 3 Datenzenteren.

Mir hunn dës Problemer ëmmer erëm geléist, an iergendwann hu mir et fäerdeg bruecht eng Approche z'entwéckelen déi d'Aarbecht mat der Applikatioun duerch säi ganze Liewenszyklus vereinfacht huet: Kreatioun, Entwécklung, Testen, CI / CD, Ënnerhalt.

Cartouche féiert d'Konzept vun enger Roll fir all Tarantool Prozess. Rollen sinn e Konzept dat en Entwéckler erlaabt sech op Code ze schreiwen. All Rollen, déi am Projet verfügbar sinn, kënnen op enger Tarantool Instanz lafen, an dëst wäert genuch fir Tester sinn.

Schlëssel Fonctiounen vun Tarantool Cartridge:

  • automatiséiert Cluster Orchestratioun;
  • d'Funktionalitéit vun der Applikatioun erweidert mat neie Rollen;
  • Applikatioun Schabloun fir Entwécklung an Détachement;
  • gebaut-an automatesch sharding;
  • Integratioun mam Luatest Testkader;
  • Clustermanagement mat WebUI an API;
  • Verpakung an Deployment Tools.

Moien Welt!

Ech kann net waarden fir de Kader selwer ze weisen, also wäerte mir d'Geschicht iwwer d'Architektur fir spéider verloossen a mat eppes einfaches ufänken. Wa mir unhuelen datt Tarantool selwer schonn installéiert ass, da bleift alles ze maachen

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

Dës zwee Kommandoen installéieren d'Command Line Utilities an erlaben Iech Är éischt Applikatioun aus der Schabloun ze kreéieren:

$ cartridge create --name myapp

An dat ass wat mir kréien:

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/

Dëst ass e Git Repository mat engem fäerdege "Hallo, Welt!" Applikatioun. Loosst eis probéieren et direkt ze lafen, nodeems Dir d'Ofhängegkeete virdru installéiert hutt (inklusiv de Kader selwer):

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

Also, mir hunn een Node fir déi zukünfteg sharded Applikatioun. En virwëtzeg Laie kann direkt d'Webinterface opmaachen, e Cluster vun engem Node mat der Maus konfiguréieren an d'Resultat genéissen, awer et ass ze fréi fir sech ze freeën. Bis elo kann d'Applikatioun näischt nëtzlech maachen, also wäert ech Iech méi spéit iwwer d'Deployment soen, awer elo ass et Zäit fir Code ze schreiwen.

Applikatioun Entwécklung

Stellt Iech vir, mir entwerfen e Projet deen Daten muss kréien, späicheren an eemol am Dag e Bericht bauen.

Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

Mir fänken un en Diagramm ze zéien an dräi Komponenten drop ze setzen: Paart, Lagerung a Scheduler. Mir schaffen weider un der Architektur. Well mir vshard als Späichere benotzen, addéiere mir vshard-Router a vshard-Storage zum Schema. Weder de Paart nach de Scheduler wäerten direkt op d'Späichere kommen; dat ass wat de Router fir ass, dat ass fir wat et erstallt gouf.

Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

Dëst Diagramm representéiert nach ëmmer net genau wat mir am Projet bauen well d'Komponente abstrakt ausgesinn. Mir mussen nach ëmmer kucken wéi dëst op de richtege Tarantool projizéiert gëtt - loosst eis eis Komponenten no Prozess gruppéieren.

Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

Et gëtt wéineg Sënn fir vshard-Router a Gateway op getrennten Instanzen ze halen. Firwat musse mir nach eng Kéier um Netz surfen wann dat schonn d'Responsabilitéit vum Router ass? Si mussen am selwechte Prozess lafen. Dat ass, souwuel Gateway an vshard.router.cfg sinn an engem Prozess initialiséiert, a loosse se lokal interagéieren.

Op der Designstadium war et bequem mat dräi Komponenten ze schaffen, awer ech, als Entwéckler, beim Schreiwen vum Code, wëll net drun denken iwwer dräi Instanzen vun Tarnatool ze lancéieren. Ech muss Tester ausféieren a kontrolléieren ob ech de Gateway richteg geschriwwen hunn. Oder vläicht wëll ech menge Kollegen eng Feature weisen. Firwat soll ech duerch d'Schwieregkeet goen fir dräi Exemplare z'installéieren? Dëst ass wéi d'Konzept vun de Rollen gebuer gouf. Eng Roll ass e reegelméissege Luash Modul deem säi Liewenszyklus vum Cartridge geréiert gëtt. An dësem Beispill ginn et véier vun hinnen - Paart, Router, Stockage, Scheduler. Et kann méi an engem anere Projet ginn. All Rollen kënnen an engem Prozess lafen, an dëst wäert genuch sinn.

Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

A wann et ëm d'Deployment an d'Inszenéierung oder d'Produktioun kënnt, da wäerte mir all Tarantool Prozess säin eegene Set vu Rollen zouginn ofhängeg vun den Hardwarefäegkeeten:

Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

Topologie Gestioun

Informatioun iwwer wou wéi eng Rolle lafen, muss iergendwou gespäichert ginn. An dëst "irgendwo" ass déi verdeelt Konfiguratioun, déi ech schonn uewen ernimmt hunn. Déi wichtegst Saach doriwwer ass d'Clustertopologie. Hei sinn 3 Replikatiounsgruppen vu 5 Tarantool Prozesser:

Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

Mir wëllen d'Donnéeën net verléieren, dofir behandele mir Informatioun iwwer Lafen Prozesser mat Suergfalt. Cartouche hält d'Konfiguratioun mat engem Zwee-Phase Verpflichtung. Wann mir d'Konfiguratioun aktualiséieren wëllen, kontrolléiert et als éischt datt all Instanzen verfügbar sinn a prett sinn fir déi nei Konfiguratioun ze akzeptéieren. Duerno gëlt déi zweet Phase d'Konfiguratioun. Also, och wann eng Kopie temporär net verfügbar ass, geschitt näischt Schlechtes. D'Konfiguratioun gëtt einfach net ugewannt an Dir gesitt e Feeler am Viraus.

Och an der Topologie Sektioun gëtt sou e wichtege Parameter wéi de Leader vun all Replikatiounsgrupp uginn. Normalerweis ass dëst d'Kopie déi opgeholl gëtt. De Rescht sinn meeschtens nëmme liesen, obwuel et Ausnahmen ginn. Heiansdo hu brave Entwéckler keng Angscht vu Konflikter a kënnen Donnéeën op e puer Repliken parallel schreiwen, awer et ginn e puer Operatiounen déi, egal wéi, net zweemol ausgefouert ginn. Fir dëst gëtt et en Zeechen vun engem Leader.

Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

Liewen vun Rollen

Fir eng abstrakt Roll an esou enger Architektur ze existéieren, muss de Kader se iergendwéi verwalten. Natierlech geschitt d'Kontroll ouni den Tarantool Prozess nei ze starten. Et gi 4 Callbacks fir Rollen ze managen. Cartouche selwer nennt se ofhängeg vun deem wat a senger verdeelerer Konfiguratioun geschriwwen ass, an doduerch d'Konfiguratioun op spezifesch Rollen applizéiert.

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

All Roll huet eng Funktioun init. Et gëtt eemol genannt entweder wann d'Roll aktivéiert ass oder wann Tarantool nei gestart gëtt. Et ass bequem do, zum Beispill, fir box.space.create ze initialiséieren, oder de Scheduler kann e puer Backgroundfaser lancéieren, déi Aarbecht a bestëmmten Zäitintervaller ausféieren.

Eng Funktioun init vläicht net genuch ginn. Cartouche erlaabt Rollen ze profitéieren vun der verdeeler Konfiguratioun déi se benotzt fir d'Topologie ze späicheren. Mir kënnen eng nei Sektioun an der selwechter Konfiguratioun deklaréieren an e Fragment vun der Geschäftskonfiguratioun dran späicheren. A mengem Beispill kann dëst en Dateschema oder Zäitplang Astellunge fir d'Roll vum Scheduler sinn.

Cluster rifft validate_config и apply_config all Kéier wann déi verdeelt Konfiguratioun ännert. Wann eng Konfiguratioun vun engem Zwee-Phase Engagement applizéiert gëtt, kontrolléiert de Cluster datt all Roll prett ass fir dës nei Konfiguratioun ze akzeptéieren an, wann néideg, mellt de Benotzer e Feeler. Wann jiddereen averstanen ass, datt d'Configuratioun normal ass, dann de apply_config.

Och Rollen hunn eng Method stop, déi néideg ass fir d'Ausgab vun der Roll ze botzen. Wa mir soen datt de Scheduler net méi op dësem Server gebraucht gëtt, kann et dës Faseren stoppen, mat deenen et ugefaang huet init.

Rollen kënne matenee interagéieren. Mir si gewinnt Funktiounsruffen am Lua ze schreiwen, awer et ka geschéien datt e bestëmmte Prozess net déi Roll huet déi mir brauchen. Fir Uriff iwwer dem Netz ze erliichteren, benotze mir den rpc (Remote Procedure Call) Hëllefsmodul, deen op Basis vun der Standard Netbox gebaut ass an Tarantool gebaut. Dëst kann nëtzlech sinn wann, zum Beispill, Äre Paart wëll de Scheduler direkt froen fir d'Aarbecht elo ze maachen, anstatt en Dag ze waarden.

En anere wichtege Punkt ass d'Feeltoleranz ze garantéieren. Cartouche benotzt de SWIM Protokoll fir d'Gesondheet ze iwwerwaachen [4]. Kuerz gesot, Prozesser austauschen "Rumeuren" mateneen iwwer UDP - all Prozess erzielt seng Noperen déi lescht Neiegkeeten, a si reagéieren. Wann op eemol d'Äntwert net kënnt, fänkt Tarantool un ze verdächtegen datt eppes falsch ass, an no enger Zäit recitéiert hien den Doud a fänkt jidderengem ronderëm dës Neiegkeet ze soen.

Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

Baséierend op dësem Protokoll organiséiert Cartridge automatesch Feelerveraarbechtung. All Prozess iwwerwaacht seng Ëmwelt, a wann de Leader op eemol ophält ze reagéieren, kann d'Replika seng Roll iwwerhuelen, a Cartridge konfiguréiert déi lafend Rollen entspriechend.

Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

Dir musst hei virsiichteg sinn, well heefeg Schalter zréck an zréck kann zu Datekonflikter während der Replikatioun féieren. Natierlech sollt Dir den automateschen Failover net zoufälleg aktivéieren. Mir musse kloer verstoen wat geschitt a sécher sinn datt d'Replikatioun net brécht nodeems de Leader restauréiert ass an d'Kroun him zréckginn.

Vun all deem kënnt Dir d'Gefill kréien datt Rollen ähnlech wéi Mikroservicer sinn. An engem Sënn si se just dat, nëmmen als Moduler bannent Tarantool Prozesser. Mä et ginn och eng Rei vun fundamental Differenzen. Als éischt mussen all Projetsrollen an der selwechter Codebasis liewen. An all Tarantool Prozesser sollen aus der selwechter Code Basis lancéiert ginn, sou datt et keng Iwwerraschungen wéi déi sinn wa mir probéieren de Scheduler ze initialiséieren, awer et gëtt et einfach net. Och, sollt Dir keng Differenzen an Code Versiounen erlaben, well d'Behuele vum System an esou enger Situatioun ass ganz schwéier virauszesoen an Debug.

Am Géigesaz zu Docker kënne mir net nëmmen eng Roll "Bild" huelen, se op eng aner Maschinn huelen an do lafen. Eis Rollen sinn net sou isoléiert wéi Docker Container. Och kënne mir net zwou identesch Rollen op enger Instanz lafen. Eng Roll existéiert entweder oder et gëtt et net; an engem Sënn ass et e Singleton. An drëttens, d'Rollen mussen d'selwecht sinn an der ganzer Replikatiounsgrupp, well soss wier et absurd - d'Donnéeën sinn d'selwecht, awer d'Konfiguratioun ass anescht.

Deployment Tools

Ech hu versprach ze weisen wéi Cartridge hëlleft Uwendungen z'installéieren. Fir d'Liewen fir anerer méi einfach ze maachen, packt de Kader RPM Packagen:

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

Den installéierten Package enthält bal alles wat Dir braucht: souwuel d'Applikatioun wéi och déi installéiert Ofhängegkeeten. Tarantool kënnt och op de Server als Ofhängegkeet vum RPM Package, an eise Service ass prett fir ze starten. Dëst gëtt duerch Systemd gemaach, awer als éischt musst Dir e bësse Konfiguratioun schreiwen. Op e Minimum spezifizéiert d'URI vun all Prozess. Dräi ass genuch zum Beispill.

$ 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

Et gëtt eng interessant Nuance hei. Amplaz just de binäre Protokollport ze spezifizéieren, spezifizéiere mir déi ganz ëffentlech Adress vum Prozess inklusiv den Hostnumm. Dëst ass néideg fir datt d'Clusternoden wësse wéi se matenee verbannen. Et ass eng schlecht Iddi fir 0.0.0.0 als Annonce_uri Adress ze benotzen; et soll eng extern IP Adress sinn, net e Socket Bind. Ouni et wäert näischt funktionnéieren, sou datt Cartridge einfach net erlaabt Iech en Node mat der falscher advertise_uri ze starten.

Elo datt d'Konfiguratioun fäerdeg ass, kënnt Dir d'Prozesser starten. Zënter enger regulärer Systemd Eenheet erlaabt net méi wéi ee Prozess unzefänken, ginn Uwendungen op der Cartouche vun der sougenannter installéiert. instantiéiert Eenheeten déi esou funktionnéieren:

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

An der Konfiguratioun hu mir den HTTP-Port uginn, op deem d'Cartridge d'Web-Interface servéiert - 8080. Loosst eis dohinner goen a kucken:

Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

Mir gesinn datt obwuel d'Prozesser lafen, se nach net konfiguréiert sinn. D'Patroun weess nach net wien mat wiem replizéiere soll a kann net eleng eng Entscheedung treffen, also waart et op eis Handlungen. Awer mir hunn net vill Wiel: d'Liewen vun engem neie Stärekoup fänkt mat der Konfiguratioun vum éischte Node un. Da fügen mir déi aner an de Cluster, ginn hinnen Rollen zou, an op dësem Punkt kann d'Deployment als erfollegräich ofgeschloss ugesi ginn.

Loosst eis e Glas vun Ärem Liiblingsdrénken schëppen an no enger laanger Aarbechtswoch relaxen. D'Applikatioun ka benotzt ginn.

Tarantool Cartridge: sharding engem Lua Backend an dräi Linnen

Resultater

Wat sinn d'Resultater? Probéiert et, benotzt et, verloosst Feedback, erstellt Ticketen op Github.

Referenze

[1] Tarantool » 2.2 » Referenz » Rocks Referenz » Modul vshard

[2] Wéi mir de Kär vum Alfa-Bank Investitiounsgeschäft ëmgesat hunn baséiert op Tarantool

[3] Nei Generatioun Rechnungsarchitektur: Transformatioun mam Iwwergank op Tarantool

[4] SWIM - Cluster Konstruktioun Protokoll

[5] GitHub - tarantool/cartridge-cli

[6] GitHub - tarantool / Cartouche

Source: will.com

Setzt e Commentaire