Despre coerența oracolului în limba rusă, ce este necesar

Deci, să presupunem că avem sarcina de a calcula rapid o sarcină pentru o cantitate mare de date. Ce înseamnă "cantitate mare" de date? Acesta este un astfel de volum care nu are sens să se încarce la client datorită faptului că clientul nu poate să se potrivească tuturor datelor necesare de partea lui. Dilema este cum se obține rezultatul, fără a se descărca întreaga cantitate de date clientului. O posibilă soluție ar fi să se facă subseturi ale unui set mare de date și să se colecteze rezultate intermediare într-un ciclu pe client. O astfel de soluție este bun pentru toți, cu excepția faptului că punerea în aplicare consecventă va fi mult mai mare decât performanța întregului set la un moment dat (timpul va fi cheltuită pe formare subsetul cerere / răspuns al datelor și transmiterea subseturi de date ale clientului pentru numărare). De asemenea, în timpul executării acestei acțiuni secvențiale, datele pot deveni caduce. Aceasta este, intuitiv, înțelegem că datele trebuie prelucrate acolo unde se află (fără a le trimite prin rețea) și simultan de-a lungul întregului set.






Aici, soluții cum ar fi Oracle Coherence, Hadoop, Gemfire etc. ajung la salvare.

Să aruncăm o privire la elementele de bază ale coerenței Oracle.
Am citit documentația și am văzut următoarele: "Coerența Oracle este o soluție de rețea în memorie care permite ...".
"În memorie" - aceasta înseamnă că datele sunt stocate în memoria calculatorului (puteți, de asemenea, pe disc, dar despre asta mai târziu).
"Soluție de rețea de date" - aceasta înseamnă că datele sunt distribuite în grup și nu sunt concentrate într-un singur loc.

Dar despre totul în ordine. Să înțelegem mai întâi ce "blocuri" sunt disponibile pentru punerea în aplicare a sarcinilor.

NOD este doar un proces java (rularea com.tangosol.net.DefaultCacheServer de clasă) cu coherence.jar classpath și fișierele de configurare. Puteți rula mai multe noduri pe aceleași / diferite mașini, sub unul sau mai mulți utilizatori, fără restricții. Adică este important să înțelegeți că acesta este doar un proces java și că aveți nevoie să îl depanați la fel ca orice aplicație server pe care o scrieți.

Un cluster este un set de mai multe noduri. Nodurile din configurația implicită se vor găsi reciproc în mod automat prin multicast. Dacă este necesar, puteți configura WKA (adresele bine cunoscute), dacă administratorii de sistem sunt nemulțumiți că ați "ciocnit întreaga rețea cu multicastul". Într-un cluster, există întotdeauna nodul principal (membru senior), care se uită la ce se întâmplă cu clusterul (câte noduri sunt, ce date Ones magazin din care copia date în cazul în care unul dintre nodurile „cădere“, etc.). Nodul principal este primul nod care a început. Dacă nodul principal este "abandonat" din anumite motive, următorul nod principal este atribuit automat. Trebuie remarcat faptul că nodul principal nu este utilizat în timpul procesării datelor. Calculele sunt efectuate pe nodurile unde se află datele necesare. De regulă, nodurile sunt împărțite după scop: proxy, computational și noduri pentru stocarea datelor. Dacă, în general, toate nodurile sunt "abandonate", atunci nu aveți date. Adică este necesar să se gândească în prealabil cum vor fi stocate datele și schimbările și cum să se încarce după ce sistemul este pornit.
În procesul de dezvoltare, se recomandă să configurați un mediu de dezvoltare similar producției. Acest lucru vă va permite să găsiți multe erori de serializare și de comunicare între noduri înainte de a lansa versiunea în producție.

Configurarea nodurilor

În mod implicit, fișierele de configurare nu sunt necesare, în acest caz vor fi utilizate fișierele din coerența.jar. Fișierele de configurare furnizate în mod prestabilit nu sunt potrivite pentru sistemul de producție, acestea trebuie să fie modificate la o anumită sarcină. Unii vă recomandăm chiar să eliminați aceste fișiere din fișierul coherence.jar.
Există 3 fișiere de configurare principale cu care va trebui să lucrați:
tangosol-coerență.xml - acest fișier este responsabil pentru configurația clusterului ca întreg. De exemplu, numele clusterului este configurat în acest fișier.
coherence-cache-config.xml - acest fișier este responsabil pentru configurarea diferitelor cache-uri pe care cluster-ul le va servi.
coerența-pof-config.xml - acest fișier este destinat să determine care vor fi datele procesate de cluster. De asemenea, acest fișier definește modul în care datele vor fi serializate pentru transmisie și stocare în cluster.

Există așa-numitele fișiere overrirde (de exemplu, tangosol-coerență-override.xml). Setările din acest fișier suprascriu setările fișierelor de bază. Asta este, dacă aveți Tangosol-coherence.xml și Tangosol-coerență-override.xml în classpath, atunci toate setările sunt încărcate din primul fișier și rescris peste unitățile de al doilea.
Puteți avea mai multe fișiere identice în calea de clasă, însă va fi utilizat numai primul fișier găsit. De asemenea, puteți instala fișierele de configurare necesare utilizând setările sistemului (-D).
Când începe clusterul, se scrie ce fișiere au fost folosite pentru a configura sistemul. În jurnalele va apărea ceva asemănător cu următorul:
Configurația operațională încărcată din resurse ...
Înlocuiri operaționale încărcate de la resurse ...
Înlocuiri operaționale încărcate de la resurse ...

Proxies (extend) noduri

Noduri pentru stocarea datelor (noduri de stocare)

Acestea sunt noduri care au setat variabila de mediu - Dtangosol.coherence.distributed.localstorage = true. În mod implicit, nodul stochează datele în java, dar puteți, de asemenea, să-l "aruncați" pe disc și să îl încărcați după cum este necesar. În aceste nodah pot efectua calcule, dar noi trebuie să înțelegem că este necesar să se producă cât mai puțin deșeuri în procesul de calcul a nodului nu este „căzut“ din cauza lipsei de memorie (OutOfMemory). În cazul în care nodul "cade" din anumite motive, datele din acesta vor fi copiate în alte noduri, astfel încât capacitatea totală a cluster-ului va scădea. Acest lucru poate da naștere unui efect cascadă dacă nu există suficient spațiu liber în cluster, iar întregul cluster, nodul din spatele nodului, poate cădea. De regulă, datele importante au oa doua copie (care este prescrisă în setările de configurare), astfel încât pierderea unui nod individual nu este critică.
Datele, care reprezintă un rezultat intermediar și sunt ușor de calculat din datele principale, nu necesită oa doua copie. Stocarea datelor poate fi configurată pentru a avea copii pe un alt nod, pe o altă mașină fizică sau chiar pe un alt suport în alt oraș. Este vorba de toți parametrii de configurare și nu există nimic de programat aici. Parametrii de stocare a datelor sunt suficient de flexibili pentru a vă permite să configurați sistemul pentru o anumită sarcină.

Nodurile de calcul (noduri cu niveluri de aplicație / stocare dezactivate)

Acestea sunt nodurile care au setat variabila de mediu - Dtangosol.coherence.distributed.localstorage = false. Aceste noduri sunt folosite pentru distribuirea uniformă a calculelor unui cluster. Pe aceste noduri, puteți, de asemenea, să memorați calcule intermediare. Toată logica de afaceri pe care doriți să o implementați pentru această aplicație trebuie să fie executată într-un cluster pe aceste noduri.

Să analizăm modul în care este implementat procesul pentru a lansa un apel prin ierarhia nodurilor. Aveți noduri pentru stocarea datelor, nodurile de calcul și nodurile proxy. În nodurile proxy, datele nu sunt stocate și cache-urile nu sunt configurate. Pe nodurile de calcul, configurați cache-urile, dar fără capacitatea de a salva date în cache-uri. Pe nodurile de stocare a datelor aveți date. Pe partea clientului, nu ar trebui să utilizați cache-urile pe care sunt stocate datele. Aceasta înseamnă că nu efectuați calcule pe datele în sine direct de la client, dar folosiți întotdeauna noduri de calcul pentru a efectua operații asupra datelor. Astfel, puteți izola datele de la aplicațiile client, ceea ce vă oferă posibilitatea de a modifica arhitectura de stocare în viitor fără a schimba clientul. Toate nodurile din cluster "știu" unde și ce cache se află. Se pare că dacă trimiteți o sarcină la execuție într-un cache configurat pentru calcule, acesta va fi executat într-un grup de noduri de calcul utilizând datele din nodurile pe care sunt stocate datele. Poate că acest lucru nu pare clar, dar acesta este un subiect separat pentru articol.







Afinitatea datelor

În unele cazuri, este util ca datele să fie grupate împreună conform unui principiu. De exemplu, puteți grupa datele astfel încât nodurile de pe aceeași mașină fizică să aibă date dependente. În acest caz, nu veți avea latență de rețea și calculele vor avea loc mai repede.

Mecanismele de trimitere a sarcinii la execuție sunt următoarele: EntryAggregator, EntryProcessor, InvocationService, MapListener, EventInterceptor

Un agregator (EntryAggregator) este o sarcină care va fi efectuată pe copii ale datelor. Asta înseamnă că nu veți putea schimba datele din memoria cache din agregator. Lucrarea are loc în cazul datelor read-only. Sarcinile tipice sunt suma minimă, maximă.
Procesorul (EntryProcessor) - această sarcină, care implică schimbarea datelor din memoria cache. Adică dacă doriți să schimbați datele din memoria cache, unde datele sunt localizate fizic, trebuie să utilizați procesorul pentru aceasta. O caracteristică frumoasă a procesorului este blocarea datelor în timpul procesării. Adică dacă aveți mai multe operații care trebuie să fie numite secvențial, atunci trebuie să utilizați procesorul, deoarece un singur procesor va lucra la această piesă de date la un moment dat.
InvocationService este o sarcină la nivel de nod. În acest caz, lucrați aproximativ la procesele Java, nu la date. Sarcini de acest tip trebuie să implementeze Invocable, care la rândul său este Runnable.
MapListener - această sarcină va fi executată asincron, ca reacție la evenimentele de la nivelul cache-ului.
EventInterceptor - această sarcină este similar cu cel anterior, în sensul că acesta va fi executat ca un răspuns la un eveniment, dar diferența constă în faptul că ascultătorul va fi executat pe toate nodah, care este configurat cache și interceptor - numai nodah care conțin date pentru care evenimentul este executat. Interceptorul are, de asemenea, posibilitatea de a fi chemat înainte sau după eveniment.
O explicație detaliată a modului în care diferite tipuri de sarcini funcționează depășește domeniul de aplicare al acestui articol.

Formatul POF (format obiect portabil)

Toate datele din cluster sunt stocate într-o matrice octet. Câmpurile obiect serializat stocate consecutiv (fiecare câmp index) și exact așa cum scrie în metodele readExternal / clasa writeExternal care implementează interfața sau PortableObject serializarea / deserializati o clasa care implementeaza interfata PofSerializer. În interiorul matricei de octeți, câmpurile sunt stocate secvențial. Scanarea matricei are loc, de asemenea, succesiv. Din aceasta nu rezultă o concluzie evidentă: câmpurile cele mai utilizate ar trebui să fie mai aproape de începutul matricei de octeți. Datele obiectului scrise în matrice pot fi imbricate și au serializare proprie. Aceasta este, în punerea în aplicare și interfețele PofSerializer PortableObject, transferați structura ierarhică a obiectului Java într-o structură plană de matrice octet.
Coerența oferă serializare pentru obiectele standard de la jdk (java.lang). Toate obiectele care trebuie să fie stocate în cluster trebuie să fie descrise în fișierul coerență-pof-config.xml. Fiecare tip de date are propriul număr. Numerele tipurilor de date trebuie să înceapă cu 1000. Astfel, veți obține o structură care este bine portabilă de la o platformă la alta și de la un limbaj de programare la altul. Fiecare clasă care va fi serializată într-un cluster trebuie să aibă implementată corect hashCode și este egală cu metodele.

Extragerea datelor din cluster (ValueExtractor)

Din paragraful anterior, știm că datele sunt stocate într-o matrice de octeți. Pentru a extrage date, trebuie să scrieți o clasă care implementează interfața ValueExtractor. Coerența va folosi această clasă pentru a obține partea necesară a obiectului serializat și pentru ao prezenta ca o clasă cu care puteți lucra. Asta înseamnă că aveți abilitatea de a "scoate" din date nu întregul obiect, ci doar ceea ce aveți nevoie în acest moment pentru calcule. Astfel, aveți o cantitate redusă de date trimise prin rețea.

Partiție (partiție)

Coerența oferă posibilitatea de a stoca date sub formă de "cheie-valoare", dar cheia și valoarea sunt concepte logice ale sistemului. La nivel fizic, datele sunt grupate într-un partizan. Adică, mai multe chei și valori pot aparține unei partiții. Partiția este o unitate de stocare a datelor. Când nodurile cad și datele se regrupă între noduri, întreaga partiție este copiată. O clasă care atribuie partiții unui anumit obiect implementează interfața KeyPartitioningStrategy. În mod implicit, partiția este atribuită în funcție de hash-ul binar al obiectului cheie (com.tangosol.util.Binary obiect "wraps" matricea de octeți). Puteți influența modul în care este repartizată partiția oferind implementarea interfeței KeyPartitioningStrategy.

Ca și în baza de date, indicele Coherence este folosit pentru a accelera recuperarea datelor. Pentru a crea un index, utilizat metoda QueryMap.addIndex (ValueExtractor extractor, boolean comandat, java.util.Comparator comparator).
ValueExtractor este folosit pentru a selecta din matricea octeților datele necesare pentru index. Când apelați metoda addIndex, aceasta nu înseamnă că grupul va începe indexarea datelor acum. Acest apel este o recomandare pentru crearea unui index atunci când resursele permit acest lucru. După creare, modificările de date vor fi afișate corect în index. Această metodă poate fi apelată de mai multe ori, iar dacă indexul există deja, nu va fi re-creat. Un index este o structură la nivel de nod. Adică, atunci când datele sunt copiate de la un nod la altul, indexul nu va fi copiat, ci va fi schimbat în conformitate cu datele din acest nod. Datele din index sunt stocate într-o formă deserializată, deci dacă aveți nevoie să obțineți date rapid și fără deserializare, creați un index. Firește, pentru confort și viteză trebuie să "plătiți" și să plătiți spațiu liber în resursele de cluster și de calcul. Indicele este alcătuit din doi sub-indici (direcți și inversați). Indicele direct stochează datele sub forma unei valori-cheie (pe care extractorul le-a furnizat), indicele invers stochează datele ca o valoare-> set de chei.

Cache-uri: replicate, distribuite, aproape

Replicată este o memorie cache în care toate datele sunt stocate într-o formă deserializată pe fiecare nod. Acesta este tipul de memorie cache care oferă cele mai rapide operații de citire, dar operații de scriere lentă. Problema este că, în cazul unei înregistrări, datele trebuie copiate la toate nodurile unde este configurată această memorie cache. Acest tip de cache, de regulă, este utilizat pentru date rare de modificare a volumului mic.
Distribuită este tipul principal de memorie cache utilizat pentru stocarea datelor. Vă permite să depășiți limitările privind dimensiunea memoriei RAM alocate unui nod separat, ca și cum s-ar "dărâma" datele din întregul cluster. Acest tip de memorie cache oferă de asemenea scalabilitate orizontală prin includerea nodurilor noi în cluster, precum și toleranța la erori prin stocarea unei copii a datelor pe alte noduri.
Aproape este un tip de cache hibrid care este configurat pe partea de apel (partea de apel poate fi fie un client, fie un alt nod din cache). De obicei, acest cache "costă" înainte de cache-ul distribuit și stochează cele mai utilizate date. Datele sunt stocate într-o formă deserializată. În cazul unei cache-uri aproape, există posibilitatea ca datele să devină caduce, așadar trebuie să configurați modul în care datele vor fi actualizate.

Acum, că avem conceptele de bază cărămizi, putem răspunde la întrebarea, de ce avem nevoie de coerență.
Răspunsul este simplu: aveți un depozit de date care poate fi scalabil pe orizontală scalabil, care oferă acces rapid la date pentru calculul paralel. Datorită prezenței de mai multe noduri, nu au restricții cu privire la dimensiunea de date pe care le puteți stoca într-un cluster (desigur, sunt limitate de dimensiunea memoriei disponibile pe o mașină fizică, dedicat acestei sarcini). Nu aveți o limită a mărimii unei perechi de cheie-valoare. De asemenea, puteți extrage din datele stocate doar ceea ce aveți nevoie pentru calcul, astfel încât informațiile minime să fie copiate în rețea. În general, întreaga ideologie a coerenței se bazează pe faptul că numai informațiile necesare sunt trimise prin rețea. De asemenea, puteți configura nivelurile de servicii și de calcul destul de flexibil pentru sarcina dvs. Ca urmare, sarcinile complexe vor fi rezolvate rapid.
Din punctul de vedere al managementului, cumpărați o soluție care să satisfacă multe cerințe. Odată ce descărcați datele în sistem, le puteți extrage în diverse moduri și le puteți utiliza în alte sisteme care folosesc Coerența ca un magazin de date. Astfel, prin punerea coerenței în fundație, puteți construi un ecosistem pentru extragerea și prelucrarea datelor.

Dacă sunteți interesat de acest subiect, pot continua o serie de articole despre Coerență. Scrieți ceea ce sunteți interesat și voi încerca să răspund.
Până în prezent, în ceea ce privește:

  • configurarea structurii de cluster de bază
  • lucrați cu EntryAggregator
  • lucrați cu EntryProcessor
  • apeluri asincrone în Coerență
  • priviți în interiorul obiectului Binar
  • lucrul cu indicii

În general, trebuie să se țină seama de faptul că coerență este ușor de a începe, dar foarte greu de a face bine și rapid, astfel încât scopul unei serii de articole pentru a umple golul dintre nivelul inițial de familiarizare cu sistemul, și la nivel de dezvoltator avansat.

Recent, colegul meu de muncă a scris o carte pentru dezvoltatorii avansați, pe care vă recomand să le citiți. În această carte, nu veți găsi cunoștințe de bază, dar veți găsi exemple de soluții (cu explicații) de sarcini destul de complexe.







Trimiteți-le prietenilor: