Më 26 shkurt, organizuam një mitap për Apache Ignite GreenSource, ku folës ishin kontribues të projektit open source. . Një ngjarje e rëndësishme në jetën e këtij komuniteti ishte ripërtëritja e komponentit , i cili lejon implementimin e mikroshërbimeve të personalizuara direkt në klasterin Ignite. Rreth këtij procesi të ndërlikuar, gjatë mitapit, foli , inxhinier programimi dhe kontribues për më shumë se dy vjet në Apache Ignite.

Le të fillojmë me atë se çfarë është realmente Apache Ignite. Ky është një bazë të dhënash që paraqet një ruajtje të shpërndarë Key/Value me mbështetje për SQL, transaksionet dhe caching. Për më tepër, Ignite lejon implementimin e shërbimeve të personalizuara direkt në klasterin Ignite. Zhvilluesi ka në dispozicion të gjitha mjetet që ofron Ignite - strukturat e dhënash të shpërndara, Messaging, Streaming, Compute dhe Data Grid. Për shembull, me përdorimin e Data Grid, zhduket problemi i administrimit të një infrastrukture të veçantë për ruajtjen e të dhënave dhe, si pasojë, kostot që rrjedhin prej saj.

Duke përdorur API-në e Service Grid, mund të implementoni një shërbim, thjesht duke përcaktuar në konfigurim skemën e implementimit dhe, përkatësisht, shërbimin e vet.
Zakonisht skema e implementimit përfshin sasinë e instancave që duhet të implementohen në nodet e klasterit. Ekzistojnë dy skema të zakonshme të implementimit. E para është Cluster Singleton: në çdo moment në klaster, do të jetë garantuar një shembull i vetëm i shërbimit të personalizuar. E dyta është Node Singleton: në çdo nodë të klasterit është implementuar një shembull i vetëm i shërbimit.

Po ashtu, përdoruesi mund të përcaktojë sasinë e instancave të shërbimit në të gjithë klasterin dhe të përcaktojë një predikat për filtrimin e nodeve përkatëse. Në një skenar të tillë, Service Grid do të llogarisë automatikisht shpërndarjen optimale për implementimin e shërbimeve.
Përveç kësaj, ekziston edhe një funksion i tillë si Affinity Service. Affinity është një funksion që përcakton lidhjen e çelësave me partitë dhe lidhjen e partive me nodet në topologji. Nëpërmjet çelësit, mund të përcaktoni nodin kryesor, në të cilin ruhen të dhënat. Kështu, mund të asocioheni shërbimin tuaj me çelësin dhe me funksionin e keshit të affinitetit. Në rastin e ndryshimit të funksionit të affinitetit, ndodh një riciklim automatik. Kështu, shërbimi do të jetë gjithmonë pranë të dhënave me të cilat duhet të manipulojë dhe, për pasojë, do të ulen kostot e aksesit në informacion. Një skemë e tillë mund të quhet si një lloj llogaritjesh të kolokuar.
Tani, pasi kemi shqyrtuar se çfarë e bën të veçantë Service Grid, do të flasim për historinë e tij të zhvillimit.
ĂfarĂ« kishte mĂ« parĂ«
Implementimi i mëparshëm i Service Grid ishte i bazuar në një sistem transaksional të replikuar të keqit të Ignite. Me fjalën "kësh" në Ignite nënkuptohet ruajtje. Kështu që kjo nuk është diçka e përkohshme, siç mund të mendohet. Megjithëse këshi është i replikueshëm dhe çdo nodë përmban të gjithë setin e të dhënave, brenda keshit ka një pamje të ndarë. Kjo lidhet me optimizimin e ruajtjes.

ĂfarĂ« ndodhte kur pĂ«rdoruesi donte tĂ« implementonte njĂ« shĂ«rbim?
- Të gjitha nodet në klaster regjistroheshin për përditësimin e të dhënave në ruajtje përmes mekanizmit të integruar Continuous Query.
- Noda-initiator nën një transaksion read-committed bënte një shënim në bazë, i cili përmbante konfigurimin e shërbimit, përfshirë instancën e serializuar.
- Pasi merrte njoftimin për një shënim të ri, koordinatori llogariste shpërndarjen sipas konfiguracionit. Objekti i marrë regjistrohej përsëri në bazë.
- Nëse ndonjë nodë hynte në shpërndarje, koordinatori duhej ta implementonte.
ĂfarĂ« na shqetĂ«sonte
Në një moment, arritëm në përfundimin se nuk mund të punonim me shërbimet në këtë mënyrë. Shkaqet ishin disa.
Nëse ndodhte ndonjë gabim gjatë implementimit, mund të merreshit vetëm nga loget e nodës ku ndodhi gjithçka. Ekzistonte vetëm një implementim asinkron, kështu që pas kthimit të kontrollit te përdoruesi nga metoda e implementimit, duhej një kohë e përditshme për të filluar shërbimin - dhe gjatë kësaj kohe, përdoruesi nuk mund të menaxhonte asgjë. Për të zhvilluar më tej Service Grid, për të krijuar funksione të reja, për të tërhequr përdorues të rinj dhe për të bërë jetën më të thjeshtë për të gjithë, është e nevojshme të bëhen disa ndryshime.
Gjatë projektimit të Service Grid të ri, ne së pari dëshironim të ofronim garancinë e implementimit sinkron: sa herë që përdoruesi kthehej kontrollit nga API, ai menjëherë mund të përdorte shërbimet. Po ashtu dëshironim të ofronim iniciatorit mundësinë për të trajtuar gabimet e implementimit.
Përveç kësaj, donim ta lehtësojmë implementimin, domethënë të shmangim transaksionet dhe ribalancimin. Megjithëse cache është i replikueshëm dhe nuk ka ribalancim, gjatë një shpërndarjeje të madhe me shumë nodë ishin probleme. Kur ndryshon topologjia, nodet duhet të shkëmbejnë informacion dhe gjatë një shpërndarjeje të madhe, këto të dhëna mund të peshojnë shumë.
Kur topologjia ishte e paqëndrueshme, koordinatori duhej të rifreskonte shpërndarjen e shërbimeve. Po ashtu, kur përballesh me transaksionet në një topologji të paqëndrueshme, kjo mund të çojë në gabime të vështira për t'u parashikuar.
Problemet
Cila është ajo ndryshim global pa probleme shoqëruese? E para ishte ndryshimi i topologjisë. Duhet të kuptojmë se në çdo moment, madje edhe gjatë shpërndarjes së shërbimit, një nod mund të hyjë në grumbull apo të dalë prej tij. Më shumë se kaq, nëse një nod hyn në grumbull në momentin e shpërndarjes, do të kërkohet që e gjithë informacioni mbi shërbimet të transferohet në nodin e ri në mënyrë koherente. Dhe kjo ka të bëjë jo vetëm me ato që tashmë janë shpërndarë, por edhe me shpërndarjet aktuale dhe të ardhshme.
Kjo është vetëm një nga problemet që mund të renditen në një listë të veçantë:
- Si të shpërndahen shërbimet e konfiguruara statikisht gjatë fillimit të nodit?
- Dalja e nodit nga grumbulli â çfarĂ« tĂ« bĂ«jmĂ« nĂ«se nodi kishte vendosur shĂ«rbime?
- ĂfarĂ« tĂ« bĂ«jmĂ« nĂ«se ndryshon koordinatori?
- ĂfarĂ« tĂ« bĂ«jmĂ« nĂ«se klienti Ă«shtĂ« ri lidhur me grumbullin?
- Duhet të trajtojmë kërkesat për aktivizim / deaktivizim dhe si?
- Por çfarë ndodh nëse thirret shkatërrimi i cache-it, ndërsa kemi shërbime të lidhura me të?
Dhe kjo nuk është aspak e gjitha.
Zgjidhja
Si objektiv, ne zgjodhĂ«m qasjen Event Driven me implementimin e komunikimit tĂ« proceseve pĂ«rmes mesazheve. NĂ« Ignite, janĂ« implementuar dy komponente qĂ« lejojnĂ« nodet tĂ« dĂ«rgojnĂ« mesazhe midis tyre, â communication-spi dhe discovery-spi.

Communication-spi lejon nodet të komunikojnë drejtpërdrejt dhe të dërgojnë mesazhe. Ai është shumë i përshtatshëm për dërgimin e sasive të mëdha të të dhënave. Discovery-spi lejon dërgimin e një mesazhi të gjithë nodëve në grumbull. Në implementimin standard, kjo bëhet sipas topologjisë "unazë". Gjithashtu ka integrim me Zookeeper, në këtë rast përdoret topologjia "yll". Një moment i rëndësishëm është: discovery-spi ofron garantion që mesazhi do të dorëzohet me saktësi dhe në rendin e duhur për të gjithë nodët.
Le ta shqyrtojmë protokollin e shpërndarjes. Të gjitha kërkesat e përdoruesve për shpërndarje dhe shpërndarje prishen përmes discovery-spi. Kjo jep garanci të mëposhtme garancitë:
- Kërkesa do të pranohet nga të gjithë nodët në grumbull. Kjo do të lejojë të vazhdojë përpunimi i kërkesës gjatë ndryshimit të koordinatorit. Gjithashtu, kjo do të thotë se me një mesazh, çdo nod do të ketë të gjitha metadat e nevojshme, siç është konfigurimi i shërbimit dhe instanca e tij e serializuar.
- Rendi i rreptë i dërgesës së mesazheve lejon zgjidhjen e konflikteve të konfigurimeve dhe kërkesave konkurente.
- Duke qenë se hyrja e nodit në topologji përpunon gjithashtu përmes discovery-spi, nodi i ri do të marrë të gjitha të dhënat e nevojshme për të punuar me shërbimet.
Kur pranojnë kërkesën, nodet në grumbull e validitojnë atë dhe formojnë detyra për përpunim. Këto detyra grumbullohen në një radhë dhe më pas përpunohen në një fije tjetër nga një punëtor i veçantë. Kjo është realizuar kështu, sepse shpërndarja mund të marrë një kohë të konsiderueshme dhe të vonojë procesin e shtrirjes është e papranueshme.
Të gjitha kërkesat nga radhë përpunohen nga menaxheri i shpërndarjes. Ai ka një punëtor të veçantë që tërheq një detyrë nga kjo radhë dhe e inicializon për të filluar shpërndarjen. Pas kësaj ndodhin veprimet e mëposhtme:
- Ădo nod llogarit shpĂ«rndarjen e vet pĂ«rmes njĂ« funksioni tĂ« ri tĂ« assignimit determinoj.
- Nodet formojnë një mesazh me rezultatet e shpërndarjes dhe ia dërgojnë koordinatorit.
- Koordinatori agregon të gjitha mesazhet dhe formon rezultatin e gjithë procesit të shpërndarjes, i cili dërgohet përmes discovery-spi të gjithë nodëve në grumbull.
- Kur pranohet rezultati, procesi i shpërndarjes përfundon, pas së cilës detyra hiqet nga radha.

Dizajni i ri event-driven: org.apache.ignite.internal.processors.service.IgniteServiceProcessor.java
Nëse ndodhi një gabim në momentin e shpërndarjes, nodi menjëherë përfshin këtë gabim në mesazhin që i dërgon koordinatorit. Pas agregimit të mesazheve, koordinatori do të ketë informacion mbi të gjitha gabimet gjatë shpërndarjes dhe do të dërgojë këtë mesazh përmes discovery-spi. Informacioni mbi gabimet do të jetë i disponueshëm në çdo nod në grumbull.
Me këtij algoritmi, përpunohen të gjitha ngjarjet e rëndësishme në Service Grid. Për shembull, ndryshimi i topologjisë është gjithashtu një mesazh i discovery-spi. Në përgjithësi, krahasuar me atë që ishte më parë, protokolli është bërë mjaft i lehtë dhe i besueshëm. Mjaftueshëm, që të përballojë çdo situatë gjatë deploy-it.
ĂfarĂ« do tĂ« ndodhĂ« mĂ« pas
Tani pĂ«r planet. Ădo pĂ«rmirĂ«sim i madh nĂ« projektin Ignite realizohet si njĂ« iniciativĂ« pĂ«r pĂ«rmirĂ«simin e Ignite, e njohur si IEP. Redizajni i Service Grid gjithashtu ka njĂ« IEP â me emrin humoristik "ZĂ«vendĂ«simi i vajit nĂ« Service Grid". Por nĂ« fakt, ne nuk e zĂ«vendĂ«suam vajin nĂ« motor, por motorin e tĂ«rĂ«.
Detyrat nĂ« IEP i kemi ndarĂ« nĂ« 2 faza. Faza e parĂ« â njĂ« fazĂ« e madhe, e cila pĂ«rfshin ridizajnimin e protokollit tĂ« deploy-it. Kjo tashmĂ« Ă«shtĂ« integruar nĂ« master, mund tĂ« provoni Service Grid tĂ« ri, i cili do tĂ« paraqitet nĂ« versionin 2.8. Faza e dytĂ« pĂ«rfshin shumĂ« detyra tĂ« tjera:
- Rindezje e nxehtë
- Versionimi i shërbimeve
- Rritja e qëndrueshmërisë
- Klienti i hollë
- Mjetet për monitorimin dhe numërimin e metrikave të ndryshme
Në fund, mund t'ju rekomandojmë Service Grid për ndërtimin e sistemeve të qëndrueshme të disponueshmërisë së lartë. Gjithashtu, ju ftojmë në dhe për të ndarë përvojën tuaj. Përvoja juaj është me të vërtetë e rëndësishme për komunitetin, do të ndihmojë në kuptimin e drejtimit që duhet të ndjekim më tej, si të zhvillojmë përbërësin në të ardhmen.
Burimi: habr.com
