Ignite Service Grid - Riavvia

Il 26 febbraio abbiamo tenuto un incontro Apache Ignite GreenSource, in cui hanno parlato i contributori del progetto open source Apache si accende. Un evento importante nella vita di questa comunità è stata la ristrutturazione del componente Accendi la griglia di servizio, che consente di distribuire microservizi personalizzati direttamente in un cluster Ignite. Ha parlato di questo difficile processo durante l'incontro Vyacheslav Daradur, ingegnere del software e collaboratore di Apache Ignite da oltre due anni.

Ignite Service Grid - Riavvia

Cominciamo con cos'è Apache Ignite in generale. Si tratta di un database che è un archivio chiave/valore distribuito con supporto per SQL, transazionalità e memorizzazione nella cache. Inoltre, Ignite ti consente di distribuire servizi personalizzati direttamente in un cluster Ignite. Lo sviluppatore ha accesso a tutti gli strumenti forniti da Ignite: strutture dati distribuite, messaggistica, streaming, elaborazione e griglia dati. Ad esempio, quando si utilizza Data Grid, il problema di amministrare un'infrastruttura separata per l'archiviazione dei dati e, di conseguenza, i costi generali che ne derivano, scompaiono.

Ignite Service Grid - Riavvia

Utilizzando l'API Service Grid, è possibile distribuire un servizio semplicemente specificando lo schema di distribuzione e, di conseguenza, il servizio stesso nella configurazione.

In genere, uno schema di distribuzione è un'indicazione del numero di istanze che dovrebbero essere distribuite sui nodi del cluster. Esistono due schemi di distribuzione tipici. Il primo è Cluster Singleton: in ogni momento è garantita la disponibilità di un'istanza di un servizio utente nel cluster. Il secondo è Node Singleton: un'istanza del servizio viene distribuita su ciascun nodo del cluster.

Ignite Service Grid - Riavvia

L'utente può anche specificare il numero di istanze del servizio nell'intero cluster e definire un predicato per filtrare i nodi idonei. In questo scenario, Service Grid stessa calcolerà la distribuzione ottimale per la distribuzione dei servizi.

Inoltre, esiste una funzionalità come Affinity Service. L'affinità è una funzione che definisce la relazione tra le chiavi e le partizioni e la relazione tra le parti e i nodi nella topologia. Utilizzando la chiave è possibile determinare il nodo primario su cui vengono archiviati i dati. In questo modo puoi associare il tuo servizio a una cache di chiavi e funzioni di affinità. Se la funzione di affinità cambia, verrà eseguita la ridistribuzione automatica. In questo modo, il servizio sarà sempre situato vicino ai dati che deve manipolare e, di conseguenza, ridurrà il sovraccarico di accesso alle informazioni. Questo schema può essere definito una sorta di calcolo collocato.

Ora che abbiamo capito qual è la bellezza di Service Grid, parliamo della sua storia di sviluppo.

Cosa c'era prima

La precedente implementazione di Service Grid era basata sulla cache di sistema replicata transazionale di Ignite. La parola "cache" in Ignite si riferisce allo storage. Cioè, questo non è qualcosa di temporaneo, come potresti pensare. Nonostante la cache sia replicata e ogni nodo contenga l'intero set di dati, all'interno della cache esso ha una rappresentazione partizionata. Ciò è dovuto all'ottimizzazione dello spazio di archiviazione.

Ignite Service Grid - Riavvia

Cosa è successo quando l'utente ha voluto distribuire il servizio?

  • Tutti i nodi nel cluster si sono iscritti per aggiornare i dati nello spazio di archiviazione utilizzando il meccanismo di query continua integrato.
  • Il nodo di avvio, nell'ambito di una transazione read-commit, ha creato un record nel database che conteneva la configurazione del servizio, inclusa l'istanza serializzata.
  • Quando viene notificato un nuovo inserimento, il coordinatore calcola la distribuzione in base alla configurazione. L'oggetto risultante è stato riscritto nel database.
  • Se un nodo faceva parte della distribuzione, il coordinatore doveva distribuirlo.

Cosa non ci andava bene

Ad un certo punto siamo giunti alla conclusione: non è questo il modo di lavorare con i servizi. C'erano diverse ragioni.

Se si è verificato qualche errore durante la distribuzione, è stato possibile scoprirlo solo dai log del nodo in cui è accaduto tutto. Esisteva solo la distribuzione asincrona, quindi dopo aver restituito il controllo all'utente dal metodo di distribuzione, era necessario del tempo aggiuntivo per avviare il servizio e durante questo periodo l'utente non poteva controllare nulla. Per sviluppare ulteriormente la Service Grid, creare nuove funzionalità, attirare nuovi utenti e rendere la vita più semplice a tutti, qualcosa deve cambiare.

Nel progettare la nuova Service Grid abbiamo voluto innanzitutto fornire una garanzia di implementazione sincrona: non appena l'utente avesse restituito il controllo dall'API, avrebbe potuto immediatamente utilizzare i servizi. Volevo anche dare all'iniziatore la possibilità di gestire gli errori di distribuzione.

Inoltre, volevo semplificare l'implementazione, ovvero allontanarmi dalle transazioni e dal riequilibrio. Nonostante il fatto che la cache sia replicata e non vi sia alcun bilanciamento, sono sorti problemi durante una distribuzione su larga scala con molti nodi. Quando la topologia cambia, i nodi devono scambiarsi informazioni e, con una distribuzione di grandi dimensioni, questi dati possono pesare molto.

Quando la topologia era instabile, il coordinatore doveva ricalcolare la distribuzione dei servizi. E in generale, quando si deve lavorare con transazioni su una topologia instabile, ciò può portare a errori difficili da prevedere.

Problematica

Quali sono i cambiamenti globali senza problemi associati? Il primo di questi è stato un cambiamento nella topologia. Devi capire che in qualsiasi momento, anche al momento della distribuzione del servizio, un nodo può entrare o uscire dal cluster. Inoltre, se al momento del deploy il nodo si unisce al cluster, sarà necessario trasferire in modo coerente tutte le informazioni sui servizi al nuovo nodo. E non stiamo parlando solo di ciò che è già stato implementato, ma anche di implementazioni attuali e future.

Questo è solo uno dei problemi che possono essere raccolti in un elenco separato:

  • Come distribuire i servizi configurati staticamente all'avvio del nodo?
  • Uscire da un nodo dal cluster: cosa fare se il nodo ospita servizi?
  • Cosa fare se è cambiato il coordinatore?
  • Cosa fare se il client si riconnette al cluster?
  • Le richieste di attivazione/disattivazione devono essere elaborate e come?
  • E se richiedessero la distruzione della cache e avessimo dei servizi di affinità collegati ad essa?

E questo è tutt'altro che tutto.

Soluzione

Come obiettivo abbiamo scelto l'approccio Event Driven con l'implementazione della comunicazione di processo tramite messaggi. Ignite implementa già due componenti che consentono ai nodi di inoltrare messaggi tra loro: communications-spi e discovery-spi.

Ignite Service Grid - Riavvia

Communication-spi consente ai nodi di comunicare direttamente e inoltrare messaggi. È adatto per l'invio di grandi quantità di dati. Discovery-spi ti consente di inviare un messaggio a tutti i nodi del cluster. Nell'implementazione standard ciò avviene tramite una topologia ad anello. C'è anche l'integrazione con Zookeeper, in questo caso viene utilizzata una topologia a stella. Un altro punto importante da notare è che discovery-spi garantisce che il messaggio verrà sicuramente consegnato nell'ordine corretto a tutti i nodi.

Diamo un'occhiata al protocollo di distribuzione. Tutte le richieste degli utenti per la distribuzione e l'annullamento della distribuzione vengono inviate tramite discovery-spi. Ciò dà quanto segue garanzia:

  • La richiesta verrà ricevuta da tutti i nodi del cluster. Ciò consentirà alla richiesta di continuare l'elaborazione quando cambia il coordinatore. Ciò significa anche che in un messaggio ogni nodo avrà tutti i metadati necessari, come la configurazione del servizio e la sua istanza serializzata.
  • L'ordine rigoroso della consegna dei messaggi aiuta a risolvere i conflitti di configurazione e le richieste concorrenti.
  • Poiché anche l’ingresso del nodo nella topologia avviene tramite discovery-spi, il nuovo nodo riceverà tutti i dati necessari per lavorare con i servizi.

Quando viene ricevuta una richiesta, i nodi nel cluster la convalidano e creano attività di elaborazione. Queste attività vengono accodate e quindi elaborate in un altro thread da un lavoratore separato. Viene implementato in questo modo perché la distribuzione può richiedere molto tempo e ritardare in modo intollerabile il costoso flusso di rilevamento.

Tutte le richieste dalla coda vengono elaborate dal gestore distribuzione. Ha un lavoratore speciale che estrae un'attività da questa coda e la inizializza per iniziare la distribuzione. Successivamente, si verificano le seguenti azioni:

  1. Ogni nodo calcola in modo indipendente la distribuzione grazie a una nuova funzione di assegnazione deterministica.
  2. I nodi generano un messaggio con i risultati della distribuzione e lo inviano al coordinatore.
  3. Il coordinatore aggrega tutti i messaggi e genera il risultato dell'intero processo di distribuzione, che viene inviato tramite discovery-spi a tutti i nodi del cluster.
  4. Una volta ricevuto il risultato, il processo di distribuzione termina, dopodiché l'attività viene rimossa dalla coda.

Ignite Service Grid - Riavvia
Nuovo design basato sugli eventi: org.apache.ignite.internal.processors.service.IgniteServiceProcessor.java

Se si verifica un errore durante la distribuzione, il nodo include immediatamente questo errore in un messaggio che invia al coordinatore. Dopo l'aggregazione dei messaggi, il coordinatore avrà informazioni su tutti gli errori durante la distribuzione e invierà questo messaggio tramite discovery-spi. Le informazioni sull'errore saranno disponibili su qualsiasi nodo del cluster.

Tutti gli eventi importanti nella Service Grid vengono elaborati utilizzando questo algoritmo operativo. Ad esempio, anche la modifica della topologia viene inviata tramite discovery-spi. E in generale, rispetto a prima, il protocollo si è rivelato abbastanza leggero e affidabile. Abbastanza per gestire qualsiasi situazione durante la distribuzione.

Cosa succederà dopo?

Ora riguardo ai piani. Qualsiasi modifica importante al progetto Ignite viene completata come iniziativa di miglioramento di Ignite, chiamata IEP. La riprogettazione della Service Grid ha anche un IEP - IEP n. 17 con il titolo beffardo “Cambio dell'olio nella rete di servizio”. Ma in realtà non abbiamo cambiato l’olio motore, ma l’intero motore.

Abbiamo diviso i compiti del IEP in 2 fasi. La prima è una fase importante, che consiste nella rielaborazione del protocollo di distribuzione. È già incluso nel master, puoi provare il nuovo Service Grid, che apparirà nella versione 2.8. La seconda fase comprende molti altri compiti:

  • Ridistribuzione a caldo
  • Versionamento del servizio
  • Maggiore tolleranza agli errori
  • Cliente sottile
  • Strumenti per il monitoraggio e il calcolo di varie metriche

Infine, possiamo consigliarvi su Service Grid per la realizzazione di sistemi tolleranti ai guasti e ad alta disponibilità. Vi invitiamo inoltre a venirci a trovare elenco-dev и lista degli utenti condividi la tua esperienza La tua esperienza è davvero importante per la community; ti aiuterà a capire dove muoverti dopo, come sviluppare il componente in futuro.

Fonte: habr.com

Aggiungi un commento