Ignite Service Grid - Reporniți

Pe 26 februarie, am ținut o întâlnire Apache Ignite GreenSource, la care au vorbit colaboratorii la proiectul open source. Apache Ignite. Un eveniment important în viața acestei comunități a fost restructurarea componentei Ignite Service Grid, care vă permite să implementați microservicii personalizate direct într-un cluster Ignite. El a vorbit despre acest proces dificil la întâlnire Viaceslav Daradur, inginer software și colaborator Apache Ignite de peste doi ani.

Ignite Service Grid - Reporniți

Să începem cu ce este Apache Ignite în general. Aceasta este o bază de date care este o stocare distribuită cheie/valoare cu suport pentru SQL, tranzacționalitate și stocare în cache. În plus, Ignite vă permite să implementați servicii personalizate direct într-un cluster Ignite. Dezvoltatorul are acces la toate instrumentele pe care Ignite le oferă - structuri de date distribuite, Mesaje, Streaming, Calcul și Grila de date. De exemplu, atunci când se utilizează Data Grid, dispare problema administrării unei infrastructuri separate pentru stocarea datelor și, în consecință, costurile generale rezultate.

Ignite Service Grid - Reporniți

Folosind API-ul Service Grid, puteți implementa un serviciu prin simpla specificare a schemei de implementare și, în consecință, a serviciului în sine în configurație.

De obicei, o schemă de implementare este o indicație a numărului de instanțe care ar trebui să fie implementate pe nodurile de cluster. Există două scheme tipice de implementare. Primul este Cluster Singleton: în orice moment, o instanță a unui serviciu de utilizator este garantată a fi disponibilă în cluster. Al doilea este Node Singleton: o instanță a serviciului este implementată pe fiecare nod de cluster.

Ignite Service Grid - Reporniți

Utilizatorul poate, de asemenea, specifica numărul de instanțe de serviciu din întregul cluster și poate defini un predicat pentru filtrarea nodurilor adecvate. În acest scenariu, Service Grid în sine va calcula distribuția optimă pentru implementarea serviciilor.

În plus, există o astfel de caracteristică precum Affinity Service. Afinitatea este o funcție care definește relația cheilor cu partițiile și relația părților cu nodurile din topologie. Folosind cheia, puteți determina nodul primar pe care sunt stocate datele. În acest fel, vă puteți asocia propriul serviciu cu un cache pentru funcții de cheie și afinitate. Dacă funcția de afinitate se modifică, va avea loc redistribuirea automată. În acest fel, serviciul va fi întotdeauna situat aproape de datele pe care trebuie să le manipuleze și, în consecință, va reduce costul general de accesare a informațiilor. Această schemă poate fi numită un fel de calcul colocat.

Acum că ne-am dat seama care este frumusețea Service Grid, să vorbim despre istoria dezvoltării sale.

Ce sa întâmplat înainte

Implementarea anterioară a Service Grid s-a bazat pe cache-ul de sistem replicat tranzacțional al Ignite. Cuvântul „cache” din Ignite se referă la stocare. Adică, acesta nu este ceva temporar, așa cum ați putea crede. În ciuda faptului că cache-ul este replicat și fiecare nod conține întregul set de date, în interiorul cache-ului are o reprezentare partiționată. Acest lucru se datorează optimizării stocării.

Ignite Service Grid - Reporniți

Ce s-a întâmplat când utilizatorul a dorit să implementeze serviciul?

  • Toate nodurile din cluster s-au abonat să actualizeze datele din stocare folosind mecanismul de interogare continuă încorporat.
  • Nodul de inițiere, sub o tranzacție read-committed, a făcut o înregistrare în baza de date care conținea configurația serviciului, inclusiv instanța serializată.
  • Când a fost notificat despre o nouă intrare, coordonatorul a calculat distribuția pe baza configurației. Obiectul rezultat a fost scris înapoi în baza de date.
  • Dacă un nod făcea parte din distribuție, coordonatorul trebuia să-l implementeze.

Ce nu ne convine

La un moment dat am ajuns la concluzia: nu acesta este modul de lucru cu serviciile. Au fost mai multe motive.

Dacă a apărut o eroare în timpul implementării, atunci ar putea fi aflată numai din jurnalele nodului unde s-a întâmplat totul. A existat doar implementare asincronă, așa că după ce a returnat controlul utilizatorului din metoda de implementare, a fost nevoie de ceva timp suplimentar pentru a porni serviciul - și în acest timp utilizatorul nu a putut controla nimic. Pentru a dezvolta grila de servicii în continuare, a crea noi funcții, a atrage noi utilizatori și a face viața tuturor mai ușoare, ceva trebuie să se schimbe.

La proiectarea noii Service Grid, am dorit în primul rând să oferim o garanție a implementării sincrone: de îndată ce utilizatorul a returnat controlul de la API, el ar putea folosi imediat serviciile. De asemenea, am vrut să ofer inițiatorului capacitatea de a gestiona erorile de implementare.

În plus, am vrut să simplific implementarea, și anume, să scap de tranzacții și reechilibrare. În ciuda faptului că memoria cache este replicată și nu există echilibrare, au apărut probleme în timpul unei implementări mari cu multe noduri. Când topologia se schimbă, nodurile trebuie să facă schimb de informații, iar cu o implementare mare, aceste date pot cântări mult.

Când topologia era instabilă, coordonatorul trebuia să recalculeze distribuția serviciilor. Și, în general, atunci când trebuie să lucrați cu tranzacții pe o topologie instabilă, acest lucru poate duce la erori greu de prezis.

Probleme

Ce sunt schimbările globale fără probleme însoțitoare? Prima dintre acestea a fost o schimbare a topologiei. Trebuie să înțelegeți că în orice moment, chiar și în momentul implementării serviciului, un nod poate intra sau părăsi clusterul. Mai mult, dacă în momentul implementării nodul se alătură clusterului, va fi necesar să se transfere în mod constant toate informațiile despre servicii către noul nod. Și vorbim nu numai despre ceea ce a fost deja implementat, ci și despre implementările actuale și viitoare.

Aceasta este doar una dintre problemele care pot fi colectate într-o listă separată:

  • Cum se implementează servicii configurate static la pornirea nodului?
  • Părăsirea unui nod din cluster - ce să faci dacă nodul a găzduit servicii?
  • Ce să faci dacă coordonatorul s-a schimbat?
  • Ce să faci dacă clientul se reconecta la cluster?
  • Cererile de activare/dezactivare trebuie procesate și cum?
  • Ce se întâmplă dacă au cerut distrugerea memoriei cache și avem servicii de afinitate legate de aceasta?

Și asta nu este tot.

decizie

Ca țintă, am ales abordarea Event Driven cu implementarea procesului de comunicare prin intermediul mesajelor. Ignite implementează deja două componente care permit nodurilor să trimită mesaje între ele - communication-spi și discovery-spi.

Ignite Service Grid - Reporniți

Communication-spi permite nodurilor să comunice direct și să transmită mesaje. Este foarte potrivit pentru a trimite cantități mari de date. Discovery-spi vă permite să trimiteți un mesaj către toate nodurile din cluster. În implementarea standard, acest lucru se face folosind o topologie inelă. Există și integrare cu Zookeeper, în acest caz se folosește o topologie în stea. Un alt punct important de remarcat este faptul că discovery-spi oferă garanții că mesajul va fi cu siguranță livrat în ordinea corectă către toate nodurile.

Să ne uităm la protocolul de implementare. Toate solicitările utilizatorilor pentru implementare și anulare sunt trimise prin discovery-spi. Acest lucru dă următoarele garanții:

  • Solicitarea va fi primită de toate nodurile din cluster. Acest lucru va permite cererii să continue procesarea atunci când coordonatorul se schimbă. Aceasta înseamnă, de asemenea, că într-un singur mesaj, fiecare nod va avea toate metadatele necesare, cum ar fi configurația serviciului și instanța sa serializată.
  • Ordinea strictă a livrării mesajelor ajută la rezolvarea conflictelor de configurare și a solicitărilor concurente.
  • Deoarece intrarea nodului în topologie este procesată și prin discovery-spi, noul nod va primi toate datele necesare pentru a lucra cu serviciile.

Când o solicitare este primită, nodurile din cluster o validează și creează sarcini de procesare. Aceste sarcini sunt puse în coadă și apoi procesate într-un alt thread de către un lucrător separat. Este implementat în acest fel, deoarece implementarea poate dura o perioadă semnificativă de timp și poate întârzia în mod intolerabil fluxul scump de descoperiri.

Toate cererile din coadă sunt procesate de managerul de implementare. Are un lucrător special care extrage o sarcină din această coadă și o inițializează pentru a începe implementarea. După aceasta, au loc următoarele acțiuni:

  1. Fiecare nod calculează independent distribuția datorită unei noi funcții de atribuire deterministă.
  2. Nodurile generează un mesaj cu rezultatele implementării și îl trimit coordonatorului.
  3. Coordonatorul agregează toate mesajele și generează rezultatul întregului proces de implementare, care este trimis prin discovery-spi către toate nodurile din cluster.
  4. Când rezultatul este primit, procesul de implementare se încheie, după care sarcina este eliminată din coadă.

Ignite Service Grid - Reporniți
Nou design bazat pe evenimente: org.apache.ignite.internal.processors.service.IgniteServiceProcessor.java

Dacă apare o eroare în timpul implementării, nodul include imediat această eroare într-un mesaj pe care îl trimite coordonatorului. După agregarea mesajelor, coordonatorul va avea informații despre toate erorile din timpul implementării și va trimite acest mesaj prin discovery-spi. Informațiile despre eroare vor fi disponibile pe orice nod din cluster.

Toate evenimentele importante din Grila de servicii sunt procesate folosind acest algoritm de operare. De exemplu, schimbarea topologiei este, de asemenea, un mesaj prin discovery-spi. Și, în general, în comparație cu ceea ce a fost înainte, protocolul s-a dovedit a fi destul de ușor și de încredere. Suficient pentru a face față oricărei situații în timpul implementării.

Ce se va întâmpla în continuare

Acum despre planuri. Orice modificare majoră a proiectului Ignite este finalizată ca o inițiativă de îmbunătățire a Ignite, numită IEP. Reproiectarea rețelei de servicii are și un IEP - IEP #17 cu titlul batjocoritor „Schimbarea uleiului în rețeaua de service”. Dar, de fapt, nu am schimbat uleiul de motor, ci întregul motor.

Am împărțit sarcinile din IEP în 2 faze. Prima este o fază majoră, care constă în reelaborarea protocolului de implementare. Este deja inclus în master, puteți încerca noul Service Grid, care va apărea în versiunea 2.8. A doua fază include multe alte sarcini:

  • Redistribuire la cald
  • Versiune serviciu
  • Toleranță crescută la erori
  • Client slab
  • Instrumente pentru monitorizarea și calcularea diferitelor metrici

În cele din urmă, vă putem sfătui cu privire la Service Grid pentru construirea de sisteme tolerante la erori și de înaltă disponibilitate. De asemenea, vă invităm să ne vizitați la dev-list и lista de utilizatori împărtășește-ți experiența. Experiența ta este cu adevărat importantă pentru comunitate; te va ajuta să înțelegi unde să te miști în continuare, cum să dezvolți componenta în viitor.

Sursa: www.habr.com

Adauga un comentariu