Gestione dei cluster in Orleans

Orleans fornisce la gestione dei cluster tramite un protocollo di appartenenza predefinito, talvolta definito protocollo di appartenenza dei silos. L'obiettivo di questo protocollo è consentire a tutti i silos (server Orleans) di accettare il set di silos attualmente attivi, rilevare i silos in errore e consentire a nuovi silos di unirsi al cluster.

Il protocollo si basa su un servizio esterno per fornire un'astrazione di IMembershipTable. IMembershipTable è una tabella piatta durevole, simile alle tabelle No-SQL, che viene usata per due scopi. In primo luogo, viene usata come punto di incontro per consentire ai silos di trovarsi reciprocamente e ai client Orleans di trovare i silos. In secondo luogo, viene usata per archiviare la visualizzazione delle appartenenze corrente (elenco di silos attivi) e aiuta a coordinare l'accordo su tale visualizzazione. Attualmente sono disponibili sei implementazioni di IMembershipTable: basate su archiviazione tabelle di Azure, SQL Server, Apache ZooKeeper, Consul IO, AWS DynamoDB e sull'emulazione in memoria per lo sviluppo.

Oltre all'interfaccia IMembershipTable, ogni silo partecipa a un protocollo di appartenenza peer-to-peer completamente distribuito che rileva i silos in errore e raggiunge un accordo su un set di silos attivi. In questo articolo si inizierà descrivendo l'implementazione interna del protocollo di appartenenza di Orleans nella sezione seguente e si proseguirà con la descrizione dell'implementazione di IMembershipTable.

Protocollo di appartenenza di base

  1. All'avvio, ogni silo aggiunge una voce per se stesso in una tabella condivisa nota, usando un'implementazione di IMembershipTable. Nella tabella viene usata una combinazione di identità di silo (ip:port:epoch) e ID distribuzione del servizio come chiavi univoche. Per epoch si intende semplicemente il tempo in tick in cui viene avviato il silo ed è pertanto garantito che il valore di ip:port:epoch sia univoco in una determinata distribuzione di Orleans.

  2. I silos si monitorano reciprocamente in maniera diretta, tramite ping di applicazione, ovvero heartbeats "are you alive" di verifica dello stato attivo. I ping vengono inviati come messaggi diretti da silo a silo, sugli stessi socket TCP con cui comunicano i silos. In questo modo, i ping sono totalmente correlati agli effettivi problemi di rete e all'integrità dei server. Ogni silo invia ping a un set configurabile di altri silos. Un silo seleziona i destinatari dei ping calcolando hash coerenti sull'identità di altri silos, formando un anello virtuale di tutte le identità e selezionando X silos successivi sull'anello. Questa è una tecnica distribuita ben nota, detta hashing coerente, ampiamente usata in molte tabelle hash distribuite, come Chord DHT.

  3. Se un silo S non riceve Y risposte ping da un server P monitorato, esprime il sospetto che non sia attivo scrivendo il sospetto con timestamp nella riga di P in IMembershipTable.

  4. Se P ha più di Z sospetti entro K secondi, S scrive che P è inattivo nella riga di P e trasmette a tutti i silos una richiesta di rileggere la tabella delle appartenenze, cosa che faranno comunque periodicamente.

  5. Più in dettaglio:

    1. Il sospetto viene scritto in IMembershipTable, in una colonna speciale nella riga corrispondente a P. Quando S sospetta che P non sia attivo, scrive che all'ora TTT S ha sospettato P.

    2. Un solo sospetto non è sufficiente a dichiarare inattivo P. A tale scopo, sono necessari Z sospetti espressi da diversi silos in un intervallo di tempo configurabile T, che corrisponde in genere a tre minuti. Il sospetto viene scritto usando il controllo di concorrenza ottimistica fornito da IMembershipTable.

    3. Il silo S che ha espresso il sospetto legge la riga di P.

    4. Se S è l'ultimo ad avere avuto un sospetto (ne sono già stati espressi Z-1 entro un periodo T, come indicato nella colonna dei sospetti), S decide di dichiarare inattivo P. In questo caso, S si aggiunge all'elenco dei silos che hanno espresso un sospetto e nella colonna relativa allo stato di P scrive che P è inattivo.

    5. Se invece S non è l'ultimo ad avere avuto un sospetto, si aggiunge semplicemente alla colonna dei silos che hanno espresso un sospetto.

    6. In entrambi i casi, il writeback usa il numero di versione o l'ETag che è stato letto e quindi gli aggiornamenti di questa riga vengono serializzati. Nel caso in cui la scrittura non sia riuscita a causa della mancata corrispondenza di versione o ETag, S ripete il tentativo (legge di nuovo e prova a scrivere, a meno che P non sia già stato contrassegnato come inattivo).

    7. A livello generale, questa sequenza di "lettura, modifica locale, writeback" è una transazione. Tuttavia, per fare questo non vengono usate transazioni di archiviazione. Il codice della "transazione" viene eseguito in locale su un server e viene usata la concorrenza ottimistica fornita da IMembershipTable per garantire l'isolamento e l'atomicità.

  6. Ogni silo legge periodicamente l'intera tabella delle appartenenze per la distribuzione. In questo modo, i silos apprendono che si sono uniti nuovi silos e che altri silos sono stati dichiarati inattivi.

  7. Configurazione: viene fornita una configurazione predefinita, ottimizzata durante l'utilizzo in produzione in Azure. Attualmente, la configurazione predefinita è la seguente: ogni silo è monitorato da altri tre silos e per dichiarare inattivo un silo sono sufficienti due sospetti, purché espressi negli ultimi tre minuti (altrimenti risulteranno obsoleti). I ping vengono inviati ogni dieci secondi e sono necessari tre ping mancati per sospettare un silo.

  8. Applicazione del rilevamento perfetto degli errori: è teoricamente possibile che un silo venga dichiarato inattivo perché ha perso la comunicazione con altri silos, ma che il processo stesso del silo rimanga in esecuzione. Per risolvere questo problema, una volta dichiarato inattivo nella tabella, il silo viene considerato inattivo da tutti, anche se non lo è (sono stati persi solo i messaggi di heartbeat o temporaneamente partizionati). Tutti smettono di comunicare con tale silo e, non appena quest'ultimo apprende di essere inattivo (leggendo il suo nuovo stato dalla tabella), arresta il processo. Deve pertanto essere presente un'infrastruttura che riavvia il silo come nuovo processo (all'avvio viene generato un nuovo numero di epoch). Quando il silo è ospitato in Azure, questo avviene automaticamente. Quando invece non lo è, è necessaria un'altra infrastruttura. Ad esempio, un servizio Windows configurato per il riavvio automatico in caso di errore o una distribuzione Kubernetes.

  9. Ottimizzazione per ridurre la frequenza delle letture periodiche di tabella e per velocizzare l'apprendimento di nuove unioni e dello stato di inattività dei silos. Ogni volta che un silo scrive qualcosa nella tabella (riguardo a un sospetto, a una nuova unione e così via), comunica anche a tutti gli altri silos di andare a rileggere la tabella. Il silo NON comunica agli altri le informazioni che ha scritto nella tabella (poiché potrebbero essere già obsolete o errate), ma indica solo di rileggere la tabella. In questo modo, gli altri apprendono molto rapidamente le modifiche di appartenenza senza dover attendere il ciclo di lettura periodico completo. La lettura periodica è comunque necessaria, nel caso in cui il messaggio di rilettura della tabella venga perso.

Proprietà del protocollo di appartenenza di base

  1. Può gestire un numero qualsiasi di errori:

    L'algoritmo può gestire un numero qualsiasi di errori, ovvero f<=n, incluso il riavvio completo del cluster. Ciò è in contrasto con le tradizionali soluzioni basate su Paxos, per cui è richiesto un quorum, che corrisponde in genere a una maggioranza. Si è potuto osservare questo comportamento in situazioni di produzione, in cui più della metà dei silos era inattiva. Questo sistema di appartenenza ha continuato a funzionare, mentre quello basato su Paxos è rimasto bloccato.

  2. Il traffico verso la tabella è molto leggero:

    I ping effettivi passano direttamente da un server all'altro senza andare alla tabella. Il passaggio dalla tabella genererebbe molto traffico e sarebbe meno accurato dal punto di vista del rilevamento degli errori. Se un silo non riuscisse a raggiungere la tabella, perderebbe la scrittura del suo heartbeat di comunicazione dello stato attivo (I am alive) e altri potrebbero dichiararlo inattivo.

  3. Accuratezza ottimizzabile e completezza a confronto:

    Anche se non è possibile ottenere un rilevamento degli errori completo e accurato al tempo stesso, in genere si cerca un compromesso tra accuratezza (non si vuole dichiarare inattivo un silo che in realtà non lo è) e completezza (si vuole dichiarare inattivo un silo che è effettivamente tale il prima possibile). I voti configurabili per dichiarare ping mancati e silos inattivi consentono di raggiungere un compromesso tra queste due caratteristiche. Per altre informazioni, vedere Yale University: Computer Science Failure Detectors.

  4. Scale (Scala):

    Il protocollo di base può gestire migliaia e probabilmente persino decine di migliaia di server. Ciò è in contrasto con le tradizionali soluzioni basate su Paxos, ad esempio i protocolli di comunicazione di gruppo, che sono noti per non raggiungere una scalabilità superiore alle decine.

  5. Diagnostica:

    La tabella offre una soluzione pratica anche per la diagnostica e la risoluzione dei problemi. Gli amministratori di sistema possono trovare istantaneamente nella tabella l'elenco corrente di silos attivi e vedere la cronologia di tutti i silos dichiarati inattivi e sospetti. Ciò è particolarmente utile per la diagnosi dei problemi.

  6. Perché è necessaria una risorsa di archiviazione permanente affidabile per l'implementazione di IMembershipTable:

    Per l'oggetto IMembershipTable viene usata una risorsa di archiviazione permanente (archiviazione tabelle di Azure, SQL Server, AWS DynamoDB, Apache ZooKeeper o Consul IO KV) per due finalità. In primo luogo, viene usata come punto di incontro per consentire ai silos di trovarsi reciprocamente e ai client Orleans di trovare i silos. In secondo luogo, viene usata per coordinare l'accordo sulla visualizzazione delle appartenenze. Anche se il rilevamento degli errori viene eseguito direttamente in modalità peer-to-peer tra i silos, la visualizzazione delle appartenenze viene archiviata in una risorsa affidabile e per raggiungere un accordo sullo stato attivo o inattivo dei vari silos viene usato il meccanismo di controllo della concorrenza fornito da tale risorsa di archiviazione. In questo modo, in un certo senso, il protocollo esternalizza il difficile problema del consenso distribuito al cloud. Viene infatti sfruttata completamente la potenza della piattaforma cloud sottostante, usandola realmente come piattaforma distribuita come servizio (PaaS).

  7. Cosa accade se la tabella non è accessibile per un certo tempo:

    Quando il servizio di archiviazione è inattivo o non disponibile oppure quando si verificano problemi di comunicazione con tale servizio, il protocollo Orleans NON commette l'errore di dichiarare inattivi i silos. I silos operativi continueranno a funzionare senza problemi. Tuttavia, Orleans non sarà in grado di dichiarare inattivo un silo (se rileva che un silo è inattivo tramite ping mancati, non sarà in grado di scrivere questo fatto nella tabella) e nemmeno riuscirà a consentire a nuovi silos di unirsi al cluster. Di conseguenza, la completezza ne risentirà, ma l'accuratezza no: il partizionamento dalla tabella non farà mai in modo che Orleans dichiari inattivo un silo per errore. Inoltre, nel caso di una partizione di rete parziale (con alcuni silo che possono accedere alla tabella e altri no), potrebbe accadere che Orleans dichiari inattivo un silo effettivamente inattivo, ma ci vorrà del tempo prima che il suo stato risulti noto a tutti gli altri silos. Il rilevamento potrebbe quindi essere ritardato, ma Orleans non commetterà mai l'errore di dichiarare inattivo un silo a causa dell'indisponibilità della tabella.

  8. Scritture dirette di "I am alive" nella tabella solo a scopo di diagnostica:

    Oltre agli heartbeat inviati tra i silos, ogni silo aggiorna periodicamente una colonna "I Am Alive" nella riga della tabella. La colonna "I Am Alive" viene usata solo per la risoluzione dei problemi e la diagnostica manuali e non dal protocollo di appartenenza stesso. In genere le scritture in questa colonna vengono eseguite con una frequenza molto più bassa (ogni cinque minuti) e sono uno strumento molto utile che consente agli amministratori di sistema di controllare lo stato di attività del cluster o di scoprire facilmente quando il silo è stato attivo per l'ultima volta.

Estensione per ordinare le visualizzazioni delle appartenenze

Il protocollo di appartenenza di base descritto nella sezione precedente è stato successivamente esteso in modo da supportare visualizzazioni delle appartenenze ordinate. Di seguito verranno brevemente descritti i motivi di questa estensione e il modo in cui viene implementata. L'estensione non apporta alcuna modifica alla progettazione precedente. Aggiunge soltanto la proprietà secondo cui tutte le configurazioni di appartenenza sono completamente ordinate a livello globale.

Perché è utile ordinare le visualizzazioni delle appartenenze?

  • L'ordinamento consente di serializzare l'unione di nuovi silos al cluster. In questo modo, quando un nuovo silo si unisce al cluster, può convalidare la connettività bidirezionale a tutti gli altri silos già avviati. Se alcuni dei silos già presenti non rispondono (indicando un possibile problema di connettività di rete con il nuovo silo), il nuovo silo non è autorizzato a unirsi. In questo modo si garantisce che almeno all'avvio di un silo sia presente una connettività completa tra tutti i silos nel cluster (questa funzionalità è implementata).

  • I protocolli di livello superiore nel silo, ad esempio la directory dei grani distribuita, possono sfruttare il fatto che le visualizzazioni delle appartenenze sono ordinate e usare queste informazioni per risolvere in modo più intelligente le attivazioni duplicate. In particolare, quando la directory rileva che sono state create due attivazioni quando la definizione dell'appartenenza era in corso, può decidere di disattivare l'attivazione meno recente, creata in base alle informazioni di appartenenza ormai obsolete.

Protocollo di appartenenza esteso:

  1. Per l'implementazione di questa funzionalità viene utilizzato il supporto per le transazioni su più righe fornite dall'oggetto MembershipTable.

  2. Alla tabella viene aggiunta una riga membership-version che tiene traccia delle modifiche apportate alla tabella.

  3. Quando il silo S vuole scrivere la dichiarazione di sospetto o inattività per il silo P:

    1. S legge il contenuto della tabella più recente. Se P è già inattivo, non viene eseguita alcuna operazione. Altrimenti,
    2. Nella stessa transazione vengono scritte le modifiche apportate alla riga di P e il numero di versione viene incrementato e scritto nuovamente nella tabella.
    3. Entrambe le scritture sono condizionate con ETag.
    4. Se la transazione viene interrotta a causa della mancata corrispondenza di ETag nella riga P o nella riga della versione, il tentativo viene ripetuto.
  4. Tutte le scritture nella tabella modificano e incrementano il valore della riga della versione. In questo modo, tutte le scritture nella tabella vengono serializzate (tramite la serializzazione degli aggiornamenti alla riga della versione) e, poiché i silos incrementano solo il numero di versione, anche tutte le scritture vengono ordinate in ordine crescente.

Scalabilità del protocollo di appartenenza esteso:

Nella versione estesa del protocollo, tutte le scritture vengono serializzate tramite una sola riga. Ciò può potenzialmente compromettere la scalabilità del protocollo di gestione del cluster perché aumenta il rischio di conflitti tra scritture su tabella simultanee. Per attenuare parzialmente questo problema, ritentare tutte le operazioni di scrittura nella tabella usando il backoff esponenziale. È stato osservato che i protocolli estesi funzionano senza problemi in un ambiente di produzione in Azure con un massimo di 200 silos. È tuttavia possibile che il protocollo abbia problemi di ridimensionamento quando viene superato un migliaio di silos. In configurazioni di dimensioni così grandi, gli aggiornamenti alla riga della versione possono essere facilmente disabilitati, mantenendo essenzialmente il resto del protocollo di gestione del cluster e rinunciando alla proprietà di ordinamento totale. Si noti anche che qui si fa riferimento alla scalabilità del protocollo di gestione del cluster e non al resto di Orleans. Altre parti del runtime di Orleans (messaggistica, directory distribuita, hosting dei grani, connettività da client a gateway) sono scalabili ben oltre le centinaia di silos.

Tabella delle appartenenze

Come già accennato, l'oggetto IMembershipTable viene usato come punto di incontro per consentire ai silos per trovarsi reciprocamente e ai client Orleans di trovare i silos ed è utile anche a coordinare l'accordo sulla visualizzazione delle appartenenze. Attualmente sono disponibili sei implementazioni di IMembershipTable: basate su archiviazione tabelle di Azure, SQL Server, Apache ZooKeeper, Consul IO, AWS DynamoDB e sull'emulazione in memoria per lo sviluppo.

  1. Archiviazione tabelle di Azure: in questa implementazione, l'ID distribuzione di Azure viene usato come chiave di partizione e l'identità del silo (ip:port:epoch) viene usata come chiave di riga. Insieme garantiscono una chiave univoca per ogni silo. Per controllare la concorrenza, viene usato il controllo della concorrenza ottimistica basato su ETag di archiviazione tabelle di Azure. Ogni volta che si legge dalla tabella, si archivia l'ETag per ogni riga letta e si usa tale ETag quando si tenta di eseguire il writeback. Gli ETag vengono assegnati automaticamente e controllati da archiviazione tabelle di Azure in ogni scrittura. Per le transazioni su più righe, viene usato il supporto per le transazioni batch fornito da archiviazione tabelle di Azure, che garantisce transazioni serializzabili su righe con la stessa chiave di partizione.

  2. SQL Server: in questa implementazione, l'ID distribuzione configurato viene usato per distinguere tra le distribuzioni e i silos appartenenti alle distribuzioni. L'identità dei silos è definita come una combinazione di deploymentID, ip, port, epoch nelle tabelle e nelle colonne appropriate. Il back-end relazionale usa il controllo della concorrenza ottimistica e le transazioni, analogamente alla procedura che prevede l'uso di ETag nell'implementazione di archiviazione tabelle di Azure. L'implementazione relazionale prevede che il motore di database generi l'ETag usato. Nel caso di SQL Server, l'ETag generato in SQL Server 2000 viene acquisito da una chiamata a NEWID(). In SQL Server 2005 e versioni successive viene usato ROWVERSION. Orleans legge e scrive gli ETag relazionali come tag VARBINARY(16) opachi e li archivia in memoria come stringhe codificate in base64. Orleans supporta inserimenti su più righe tramite UNION ALL (per Oracle incluso DUAL), attualmente usato per inserire i dati delle statistiche. L'implementazione esatta e la logica per SQL Server possono essere viste in CreateOrleansTables_SqlServer.sql.

  3. Apache ZooKeeper: in questa implementazione, l'ID distribuzione configurato viene usato come nodo radice e l'identità del silo (ip:port@epoch) viene usata come nodo figlio. Insieme garantiscono un percorso univoco per ogni silo. Per controllare la concorrenza, viene usato il controllo della concorrenza ottimistica basato sulla versione del nodo. Ogni volta che si legge dal nodo radice della distribuzione, la versione viene archiviata per ogni nodo di silo figlio letto e quindi usata quando si tenta di eseguire il writeback. Ogni volta che i dati di un nodo cambiano, il numero di versione viene aumento in modo atomico dal servizio ZooKeeper. Per le transazioni a più righe, viene usato il metodo multi, che garantisce transazioni serializzabili su nodi di silo con lo stesso nodo di ID distribuzione padre.

  4. Consul IO: per implementare la tabella delle appartenenze è stato usato l'archivio chiave/valore di Consul. Per altri dettagli, vedere Consul-Deployment.

  5. AWS DynamoDB: in questa implementazione, l'ID distribuzione del cluster viene usato come chiave di partizione e l'identità del silo (ip-port-generation) viene usata come RangeKey che crea l'unità dei record. La concorrenza ottimistica viene realizzata dall'attributo ETag tramite scritture condizionali in DynamoDB. La logica di implementazione è molto simile a quella di archiviazione tabelle di Azure.

  6. Emulazione in memoria per la configurazione di sviluppo. Per questa implementazione viene usato uno specifico grano di sistema denominato MembershipTableGrain. Il grano risiede in un silo primario designato, che viene usato solo per una configurazione di sviluppo. In qualsiasi utilizzo reale in produzione, il silo primario non è necessario.

Impostazione

Il protocollo di appartenenza viene configurato tramite l'elemento Liveness nella sezione Globals del file OrleansConfiguration.xml. I valori predefiniti sono stati ottimizzati in anni di utilizzo in un ambiente di produzione di Azure e si ritiene che rappresentino impostazioni predefinite valide. In generale non è necessario modificarle.

Elemento di configurazione di esempio:

<Liveness ProbeTimeout="5s"
    TableRefreshTimeout="10s"
    DeathVoteExpirationTimeout="80s"
    NumMissedProbesLimit="3"
    NumProbedSilos="3"
    NumVotesForDeathDeclaration="2" />

Sono stati implementati quattro tipi di stato di attività. Il tipo del protocollo di attività viene configurato tramite l'attributo SystemStoreType dell'elemento SystemStore nella sezione Globals del file OrleansConfiguration.xml.

  1. MembershipTableGrain: la tabella delle appartenenze viene archiviata in un grano sul silo primario. Si tratta solo di una configurazione di sviluppo.
  2. AzureTable: la tabella delle appartenenze viene archiviata in archiviazione tabelle di Azure.
  3. SqlServer: la tabella delle appartenenze viene archiviata in un database relazionale.
  4. ZooKeeper: la tabella delle appartenenze viene archiviata in un insieme di ZooKeeper.
  5. Consul: configurato come archivio di sistema personalizzato con MembershipTableAssembly = "OrleansConsulUtils". Per altri dettagli, vedere Consul-Deployment.
  6. DynamoDB: configurato come archivio di sistema personalizzato con MembershipTableAssembly = "OrleansAWSUtils".

Per tutti i tipi di stato di attività, le variabili di configurazione comuni sono definite nell'elemento Globals.Liveness:

  1. ProbeTimeout: il numero di secondi per sondare lo stato di attività di altri silos o per l'invio di messaggi di heartbeat "I am alive" su di sé. Il valore predefinito è 10 secondi.
  2. TableRefreshTimeout: il numero di secondi per recuperare gli aggiornamenti dalla tabella delle appartenenze. Il valore predefinito è 60 secondi.
  3. DeathVoteExpirationTimeout: il tempo di scadenza in secondi per il voto di inattività nella tabella delle appartenenze. Il valore predefinito è 120 secondi.
  4. NumMissedProbesLimit: il numero di messaggi heartbeat "I am alive" mancati da un silo o il numero di probe senza risposta che fanno sospettare dello stato di inattività del silo. Il valore predefinito è 3.
  5. NumProbedSilos: il numero di silos di cui un silo sonda lo stato di attività. Il valore predefinito è 3.
  6. NumVotesForDeathDeclaration: il numero di voti non scaduti necessari per dichiarare inattivo un silo (non deve superare il valore di NumMissedProbesLimit). Il valore predefinito è 2.
  7. UseLivenessGossip: indica se usare l'ottimizzazione gossip per rendere più veloce la diffusione delle informazioni sullo stato di attività. Il valore predefinito è true.
  8. IAmAliveTablePublishTimeout: il numero di secondi per scrivere periodicamente che il silo è attivo nella tabella delle appartenenze. Usato solo per la diagnostica. Il valore predefinito è 5 minuti.
  9. NumMissedTableIAmAliveLimit: il numero di aggiornamenti "I am alive" mancati nella tabella da un silo che causa la registrazione di un avviso. Non influisce sul protocollo di attività. Il valore predefinito è 2.
  10. MaxJoinAttemptTime: il numero di secondi per tentare di unirsi a un cluster di silos prima di rinunciare. Il valore predefinito è 5 minuti.
  11. ExpectedClusterSize: la dimensione prevista di un cluster. Questo valore non deve essere necessariamente molto accurato. Può essere sovrastimato. Viene usato per ottimizzare l'algoritmo di backoff esponenziale dei tentativi ripetuti di scrittura in archiviazione tabelle di Azure. Il valore predefinito è 20.

Logica di progettazione

Una domanda naturale che potrebbe sorgere è la seguente: perché non ci si affida completamente ad Apache ZooKeeper per implementare l'appartenenza al cluster, eventualmente usando il supporto predefinito per l'appartenenza a gruppi con nodi temporanei? Perché si è ritenuto opportuno implementare uno specifico protocollo di appartenenza? I motivi sono principalmente tre:

  1. Distribuzione/hosting nel cloud:

    Zookeeper non è un servizio ospitato (almeno al momento della stesura di questo articolo nel luglio 2015 e, quando questo protocollo è stato implementato nell'estate del 2011, sicuramente non esisteva alcuna versione di Zookeeper in esecuzione come servizio ospitato da alcun principale provider di servizi cloud). Ciò significa che nell'ambiente cloud Orleans i clienti avrebbero dovuto distribuire/eseguire/gestire la propria istanza di un cluster ZK. Questo sarebbe stato solo un altro peso inutile, che si voleva evitare ai clienti. Usando archiviazione tabelle di Azure è possibile basarsi su un servizio gestito ospitato, in grado di rendere molto più semplice la vita dei clienti. In pratica, il cloud viene usato come piattaforma, non come infrastruttura. D'altro canto, quando si usa un ambiente locale e si gestiscono direttamente i propri server, un'opzione praticabile è quella di affidarsi a ZK come implementazione di IMembershipTable.

  2. Rilevamento diretto degli errori:

    Quando si usa l'appartenenza a gruppi di ZK con nodi temporanei, il rilevamento degli errori viene eseguito tra i server Orleans (client ZK) e i server ZK. Questo potrebbe non essere necessariamente correlato a problemi di rete effettivi tra i server Orleans. L'intenzione era di fare in modo che il rilevamento degli errori riflettesse accuratamente lo stato delle comunicazioni all'interno del cluster. In particolare, in base al criterio di progettazione adottato, se un silo Orleans non può comunicare con IMembershipTable non è considerato inattivo e può continuare a funzionare. Questo non è stato possibile usando l'appartenenza al gruppo ZK con nodi temporanei. In tal caso, infatti, una disconnessione da un server ZK può comportare la dichiarazione di inattività di un silo Orleans (client ZK), quando invece questo potrebbe essere attivo e completamente funzionante.

  3. Portabilità e flessibilità:

    Come parte della filosofia di Orleans, non si intende imporre una forte dipendenza da una determinata tecnologia, ma piuttosto offrire una progettazione flessibile in cui i diversi componenti possono essere facilmente scambiati con diverse implementazioni. L'astrazione IMembershipTable serve proprio a questo.

Riconoscimenti

Si desidera esprimere apprezzamento per il contributo di Alex Kogan alla progettazione e all'implementazione della prima versione di questo protocollo. Questo lavoro è stato svolto nell'ambito di uno stage estivo presso la divisione Microsoft Research nell'estate del 2011. L'implementazione di ZooKeeper basata su IMembershipTable è stata eseguita da Shay Hazor, l'implementazione IMembershipTable in SQL è stata eseguita da Veikko Eeva, l'implementazione di IMembershipTable in AWS DynamoDB è stata eseguita da Gutemberg Ribeiro e l'implementazione di Consul basata su IMembershipTable stata eseguita da Paul North.