Come implementare un'architettura cluster leggera per un'applicazione distribuita

5

Attualmente ho un'applicazione distribuita che funziona su più PC embedded. L'intera applicazione è composta da un server principale e diversi nodi. Ogni nodo è un PC incorporato che esegue Windows 7 Embedded e ha una CPU dual core con 2 GB di RAM.

L'applicazione (per definizione) funziona solo se il master è attivo e in esecuzione, controllando tutti i nodi. Il server principale ha un database SQL Express in cui conserva informazioni su ogni nodo che si suppone debba controllare e in che modo sono organizzati. I nodi non hanno uno stato persistente.

Una volta che il master e i nodi sono attivi e funzionanti, saranno manipolati e messi in un certo stato che viene mantenuto solo in memoria a questo punto. Il master può essere controllato da un'interfaccia utente del client WinForm che si connette ad esso e può leggere il suo stato e inviare comandi che cambieranno il suo stato (sono fondamentalmente un gruppo di servizi Web esposti utilizzando .NET WCF).

Lo stato tenuto all'interno del master (in memoria) è ciò che conta. Lo stato all'interno di ciascun nodo può essere rigenerato se un nodo viene riavviato ad esempio. Se il master viene riavviato, perde il suo stato corrente (e il nodo dichiara di conseguenza). Ciò significa che dopo un riavvio del server master la configurazione verrà ricaricata e verrà impostato uno stato "fresco".

Tipicamente una configurazione di questa applicazione è composta da un master e 9 nodi (questa è una configurazione 3x3). In qualsiasi momento un nodo può fallire e l'applicazione continuerà senza di essa (a condizione che il master sia attivo). Se il nodo che ha fallito ritorna, il master lo rileva e lo riporta allo stato desiderato.

Mi è stato chiesto di migliorare l'architettura di questa applicazione in modo che il server master possa essere eseguito all'interno di uno dei nodi. Quindi, invece di una configurazione 9 + 1 avremo solo 9 PC embedded con uno scelto come master. Secondo i nostri test l'hardware del nodo ha abbastanza potenza per supportare insieme sia il nodo che il pezzo principale. Tuttavia, il PC integrato non può essere considerato affidabile e fallirà molto più spesso di un normale server che abbiamo usato per ospitare il master fino ad ora.

Per questo motivo mi è stato chiesto di trovare una soluzione di ridondanza. A mio avviso, la soluzione corretta sarebbe quella di inserire due o più embedded in esecuzione nei cluster, quindi se il nodo che esegue il master non funziona, un altro ne assumerà il posto.

Ora, la domanda è: come implementare un cluster leggero che può essere eseguito in quelle condizioni?

Ci sono due problemi principali che devono essere risolti:

  1. Persistenza dei dati: non solo la configurazione deve essere salvata ma anche lo stato principale. In questo modo quando il nodo master scende un altro nodo può assumere la funzione di master senza reimpostare l'intero stato dell'applicazione.
  2. Cluster di WCF: in qualsiasi momento, se il nodo master fallisce, un altro deve assumere e tutti i client connessi (l'interfaccia utente del client WinForm) devono essere in grado di riconnettersi automaticamente al nuovo nodo master rieletto. Questo non deve essere veramente trasparente per l'utente, ma i client devono essere in grado di riconnettersi automaticamente (non importa se il nuovo indirizzo IP sarà lo stesso o no).

Ci sono diversi fattori limitanti per una possibile soluzione:

  • Non c'è modo di avere una memoria dati condivisa tra i nodi (ogni nodo ha il proprio HD e una rete gigabit privata tra di loro)
  • Gli aggiornamenti hardware sono fuori questione
  • La soluzione deve essere abbastanza leggera da poter essere eseguita su un PC integrato. Quindi installare un server cloud o un DB cluster probabilmente non sarà abbastanza veloce (se pensi che MySQL cluster funzionerà per risolvere il livello dati, sarò interessato a sentire i tuoi pensieri)
  • La soluzione non può implicare l'acquisto di un costoso software
  • La piattaforma generale di questa applicazione deve essere basata su Windows

La soluzione migliore che ho pensato finora è stata quella di utilizzare qualcosa come Prevayler per mantenere lo stato master persistente e quindi implementare una sincronizzazione di ogni comando il master ricevuto negli altri nodi. Questo risolverà il problema della persistenza su tutti i nodi (forse qualcosa di simile può essere implementato usando memcache, non ne sono sicuro). Non ho ancora una soluzione per risolvere il problema del servizio WCF.

Poiché ciò comporterà un enorme sviluppo e test adeguati, ho pensato che avrei dovuto ascoltarti prima di implementare qualsiasi cosa.

Penso che una soluzione potrebbe essere messa insieme usando un framework o una sorta di software open source che risolva parte del problema.

Non esitare a chiedere informazioni per migliorare il testo di questa domanda per renderlo più chiaro.

    
posta Alex 22.09.2011 - 08:06
fonte

2 risposte

2

Dato che ti stai allontanando da un singolo nodo principale (che è appropriato) dovrai cambiare alcune cose. Dovrai configurare un quorum . Dato che hai già 9 nodi, sei in buona forma. Perché un quorum funzioni è necessario 2n + 1 nodi dove (n) è il numero di nodi che possono andare giù e il sistema funzionerà ancora. All'interno del Quorum si svolgerà una votazione su chi è il leader e su quali transazioni hanno successo. Questo può essere usato per passare informazioni di configurazione e assicurare che tutti siano sincronizzati senza un database.

Ci sono tecnologie esistenti là fuori che possono aiutarti in questo. Uno di questi è ZooKeeper . È un prodotto Apache v2 open source per Distributed Coordination. Avrai bisogno di qualcosa in questo senso. Sia che stia utilizzando ZooKeeper o che tu stia utilizzando i tuoi white paper, sarà inestimabile. Può anche essere utilizzato per mantenere le informazioni di configurazione su ciascun nodo.

ZooKeeper è scritto in Java, ma ho creato un progetto ( ZooKeeperNet che permetterà di integrarlo all'interno dell'applicazione .NET usando IKVM. Se ciò non è accettabile, ti consigliamo di leggere Elezioni leader quando determini chi sarà l'attuale nodo Master, ti suggerisco di leggere tutte le loro pagine Wiki e le tue ricette per avere un'idea di ciò che devi rendere conto in un sistema distribuito corretto.

Solo così hai una buona comprensione. ZooKeeper è il sistema di coordinamento di supporto di Hadoop e HBase. Hadoop è un framework distribuito di Map / Reduce.

Se non lo è già, è possibile utilizzare WCF adhoc o informazioni di individuazione del registro quando si tenta di trovare il nodo master corrente nel sistema. Se solo un singolo nodo Master è attivo, sarà l'unico registrato per supportare le funzioni di IMaster. Quindi i tuoi nodi slave ascolteranno l'uno sull'altro gli znodi l'uno per l'altro per andare via, prendendo quasi subito il Master.

Tenere presente che per essere efficienti, i dati su cui ogni nodo deve lavorare devono essere vicini (cioè sul nodo stesso) al nodo. Se un nodo funge da intermediario dei dati, non sarà il più efficiente possibile se i nodi potrebbero estrarre i dati in modo distribuito.

    
risposta data 22.09.2011 - 13:11
fonte
0

AMQP

Utilizza un'implementazione AMQP per garantire gli aggiornamenti dei nodi ai tutti master. Questo si prenderà cura di avere i dati su tutti i master sincronizzati. Esistono implementazioni AMPQ gratuite (oltre che non gratuite). Probabilmente vorrai eseguire qualche test per capire le tolleranze appropriate, ecc. Le interconnessioni Gigabit supporteranno un bel po 'di comunicazione in coda, supponendo che il tasso di aggiornamento non sia estremamente elevato e l'aggiornamento medio non sia enorme. YYMV, quindi sicuramente vorrai eseguire alcuni numeri e fare alcuni test per eseguirne il backup.

Bilanciamento del carico di rete con un IP del cluster

Un modo tipico per gestire il bilanciamento del carico è l'indirizzamento di un singolo IP del cluster. Non conosco molto su questa soluzione se non su Windows. (è abbastanza usato nel mio lavoro)

    
risposta data 22.09.2011 - 09:57
fonte