Gestion de cluster dans Orleans
Orleans fournit une gestion de cluster via un protocole d’appartenance intégré, que nous appelons parfois appartenance aux silos. L’objectif de ce protocole est que tous les silos (serveurs Orleans) s’accordent sur l’ensemble des silos actuellement actifs, détectent les silos ayant échoué et permettent à de nouveaux silos de rejoindre le cluster.
Le protocole s’appuie sur un service externe pour fournir une abstraction de IMembershipTable. IMembershipTable
est une table durable de type non-SQL que nous utilisons dans deux objectifs. Tout d’abord, il est utilisé comme point de rendez-vous pour que les silos puissent se trouver les uns les autres et que les clients Orleans puissent trouver les silos. Deuxièmement, elle permet de stocker la vue des appartenances actuelles (liste des silos actifs) et aide à coordonner l’accord sur la vue des appartenances. Nous avons actuellement 6 implémentations de IMembershipTable
: basées sur Stockage Table Azure, SQL Server, Apache ZooKeeper, Consul IO, AWS DynamoDB et l’émulation en mémoire pour le développement.
Outre IMembershipTable, chaque silo participe à un protocole d’appartenance d’égal à égal entièrement distribué qui détecte les silos ayant échoué et atteint un accord sur un ensemble de silos actifs. Nous commençons par décrire l’implémentation interne du protocole d’appartenance d’Orleans ci-dessous et nous décrirons ensuite l’implémentation de IMembershipTable
.
Protocole d’appartenance de base
Au démarrage, chaque silo ajoute une entrée pour elle-même dans une table partagée bien connue, à l’aide d’une implémentation de IMembershipTable. Une combinaison de l’identité du silo (
ip:port:epoch
) et de l’ID de déploiement de service est utilisée comme clé unique dans la table. L’époque correspond juste au temps exprimé en graduations quand ce silo a commencé et, en tant que telle,ip:port:epoch
est garantie comme étant unique dans un déploiement Orleans donné.Les silos se surveillent les uns les autres directement, via des pings d’application (
heartbeats
« êtes-vous actif »). Les pings sont envoyés en tant que messages directs d’un silo à un autre, via les sockets TCP que les silos utilisent pour communiquer. De cette façon, les pings sont entièrement corrélés avec l’intégrité du serveur et les problèmes de réseau réels. Chaque silo effectue un test ping sur un ensemble configurable d’autres silos. Un silo choisit à qui il enverra un ping en calculant les hachages cohérents sur l’identité des autres silos, en formant un anneau virtuel de toutes les identités et en choisissant X silos successeurs sur cet anneau (il s’agit d’une technique distribuée bien connue, appelée hachage cohérent, qui est largement utilisée dans de nombreuses tables de hachage distribuées, comme Chord DHT).Si un silo S n’obtient pas Y réponses de ping d’un serveur surveillé P, il le soupçonne en écrivant son soupçon horodaté dans la ligne de P dans
IMembershipTable
.Si P a plus de Z soupçons en K secondes, S écrit que P est mort dans la ligne de P et diffuse une demande pour tous les silos, indiquant de relire la table des appartenances (ce qu’il font de toute façon périodiquement).
Plus en détail :
Le soupçon est écrit dans
IMembershipTable
, dans une colonne spéciale, dans la ligne correspondant à P. Quand S soupçonne P, il écrit : « à l’instant TTT, S soupçonnait P ».Un soupçon n’est pas suffisant pour déclarer que P est mort. Vous avez besoin de Z soupçons provenant de différents silos dans une fenêtre de temps configurable T, généralement 3 minutes, pour déclarer que P est mort. Le soupçon est écrit à l’aide du contrôle d’accès concurrentiel optimiste fourni par
IMembershipTable
.Le silo S suspicieux lit la ligne de P.
Si
S
est le dernier silo suspicieux (il y a déjà eu Z-1 silos suspicieux dans une période T, comme écrit dans la colonne des soupçons), S décide de déclarer que P est mort. Dans ce cas, S s’ajoute à la liste des silos suspicieux et écrit également dans la colonne d’état de P que P est mort.Sinon, si S n’est pas le dernier silo suspicieux, S s’ajoute simplement à la colonne des silos suspicieux.
Dans les deux cas, l’écriture différée utilise le numéro de version ou l’ETag qui a été lu, de sorte que les mises à jour de cette ligne sont sérialisées. Si l’écriture a échoué en raison d’une non-correspondance entre la version et l’ETag, S réessaie (relecture et tentative d’écriture, sauf si P a déjà été marqué comme mort).
À un niveau élevé, cette séquence de « lecture, modification locale, écriture différée » est une transaction. Toutefois, nous n’utilisons pas les transactions de stockage pour ce faire. Le code de « transaction » s’exécute localement sur un serveur et nous utilisons l’accès concurrentiel optimiste fourni par
IMembershipTable
pour garantir l’isolement et l’atomicité.
Chaque silo lit régulièrement la table des appartenances entière pour son déploiement. De cette façon, les silos découvrent les nouveaux silos qui les rejoignent et les autres silos qui sont déclarés morts.
Configuration: nous fournissons une configuration par défaut, qui a été ajustée manuellement pendant notre utilisation en production dans Azure. Actuellement, le réglage par défaut est le suivant : chaque silo est surveillé par trois autres silos, deux soupçons suffisent pour déclarer un silo mort, soupçons datant uniquement des trois dernières minutes (sinon ils sont obsolètes). Des requêtes ping sont envoyées toutes les dix secondes et trois requêtes ping doivent manquer pour que vous soupçonniez un silo.
Application de la détection des défaillances parfaites: il est théoriquement possible qu’un silo soit déclaré mort s’il a perdu toute communication avec d’autres silos, tandis que le processus de silo lui-même continue à s’exécuter. Pour résoudre ce problème, une fois que le silo a été déclaré mort dans la table, il est considéré comme mort par tout le monde, même s’il n’est pas mort (s’il est juste partitionné temporairement ou en cas de perte des messages de pulsation). Tout le monde cesse de communiquer avec lui et une fois qu’il apprend qu’il est mort (en lisant son nouvel état dans la table), il se suicide et arrête son processus. Par conséquent, une infrastructure doit être en place pour redémarrer le silo en tant que nouveau processus (un nouveau nombre d’époque est généré au démarrage). Lorsqu’elle est hébergée dans Azure, cela se produit automatiquement. Quand ce n’est pas le cas, une autre infrastructure est requise. Par exemple, un service Windows configuré pour redémarrer automatiquement en cas d’échec ou de déploiement de Kubernetes.
Optimisation pour réduire la fréquence de lecture périodique de la table et accélérer la découverte par tous les silos des nouveaux silos qui les rejoignent et des silos morts. Chaque fois qu’un silo quelconque écrit quelque chose avec succès dans la table (soupçon, nouvelle jointure, etc.), il diffuse également pour tous les autres silos : « relire la table maintenant ». Le silo NE dit PAS aux autres ce qu’il a écrit dans la table (étant donné que ces informations pourraient déjà être obsolètes/erronées), il leur indique simplement de relire la table. De cette façon, nous découvrons très rapidement les changements d’appartenance sans avoir à attendre le cycle de lecture périodique complet. Nous avons toujours besoin de la lecture périodique, au cas où le message « relire la table » se perdrait.
Propriétés du protocole d’appartenance de base
Peut gérer n’importe quel nombre d’échecs :
Notre algorithme peut gérer n’importe quel nombre d’échecs (c’est-à-dire f<=n), y compris un redémarrage complet du cluster. Cela contraste avec les solutions « traditionnelles » basées sur Paxos, qui nécessitent un quorum, qui est généralement une majorité. Nous avons vu cela dans des situations de production, quand plus de la moitié des silos étaient en panne. Notre système est resté fonctionnel, tandis que l’appartenance basée sur Paxos n’aurait pas été en mesure de faire des progrès.
Le trafic vers la table est très léger :
Les requêtes ping réelles vont directement entre les serveurs et non à la table. Cela générerait beaucoup de trafic et serait moins précis du point de vue de la détection des échecs. Si un silo ne pouvait pas atteindre la table, il n’écrirait pas sa pulsation Je suis actif, et les autres le supprimeraient.
Précision ajustable ou exhaustivité :
Une détection des échecs parfaite et précise est impossible, mais il est généralement souhaitable de pouvoir compenser la précision (vous ne souhaitez pas déclarer un silo actif comme mort) par l’exhaustivité (vous voulez déclarer comme mort un silo qui est effectivement mort dès que possible). Les votes configurables à déclarer morts et les requêtes ping manquées autorisent l’échange des deux. Pour plus d’informations, consultez Université de Yale : Détecteurs d’échec en informatique.
Échelle :
Le protocole de base peut gérer des milliers et probablement des dizaines de milliers de serveurs. Cela contraste avec les solutions traditionnelles basées sur Paxos, telles que les protocoles de communication de groupe, qui sont connues pour ne pas permettre une mise à l’échelle au-delà de quelques dizaines.
Diagnostics :
La table est également très pratique pour les diagnostics et la résolution des problèmes. Les administrateurs système peuvent rechercher instantanément dans la table la liste actuelle des silos actifs, ainsi que consulter l’historique de tous les silos supprimés et des soupçons. Cela est particulièrement utile lors du diagnostic des problèmes.
Pourquoi avons-nous besoin d’un stockage persistant fiable pour l’implémentation de
IMembershipTable
:Nous utilisons le stockage persistant (table Azure, SQL Server, AWS DynamoDB, Apache ZooKeeper ou Consul IO KV) pour
IMembershipTable
pour deux raisons. Tout d’abord, il est utilisé comme point de rendez-vous pour que les silos puissent se trouver les uns les autres et que les clients Orleans puissent trouver les silos. Deuxièmement, nous utilisons un stockage fiable pour mieux coordonner l’accord sur la vue des appartenances. Nous effectuons la détection des défaillances directement dans un mode d’égal à égal entre les silos, nous stockons la vue des appartenances dans un stockage fiable et nous utilisons le mécanisme de contrôle d’accès concurrentiel fourni par ce stockage pour atteindre un accord concernant qui est actif et qui est mort. De cette façon, dans un sens, notre protocole externalise le problème difficile du consensus distribué dans le cloud. En cela, nous utilisons pleinement la puissance de la plateforme cloud sous-jacente, en l’utilisant réellement comme une plateforme en tant que service (PaaS).Que se passe-t-il si la table n’est pas accessible pendant un certain temps :
En cas de panne, d’indisponibilité ou de problème de communication du service de stockage, le protocole Orleans NE déclare PAS les silos comme morts par erreur. Les silos opérationnels continueront de fonctionner sans aucun problème. Toutefois, Orleans ne pourra pas déclarer un silo mort (s’il détecte que certains silos sont morts via des requêtes ping manquantes, il ne pourra pas écrire ce fait dans la table), pas plus qu’il ne pourra autoriser la jonction de nouveaux silos. Ainsi, l’exhaustivité sera mise à mal, mais pas la précision : le partitionnement de la table ne poussera jamais Orleans à déclarer le silo comme mort par erreur. De plus, en cas de partition partielle du réseau (si certains silos peuvent accéder à la table et d’autres non), il peut arriver que Orleans déclare un silo mort comme mort. Cependant, la communication de cette information à tous les autres silos peut prendra un certain temps. Ainsi, la détection pourrait être retardée, mais Orleans ne supprimera jamais un silo par erreur en raison de l’indisponibilité de la table.
Écriture directe de IAmAlive dans la table pour les diagnostics uniquement :
Outre les pulsations envoyées entre les silos, chaque silo met régulièrement à jour une colonne « I Am Alive » (Je suis actif) dans sa ligne, dans la table. Cette colonne « Je suis actif » est utilisée uniquement pour les diagnostics et la résolution manuelle des problèmes, et elle n’est pas utilisée par le protocole d’appartenance lui-même. Elle est généralement écrite à une fréquence beaucoup plus faible (une fois toutes les 5 minutes) et sert d’outil très utile pour les administrateurs système afin de vérifier l’activité du cluster et de découvrir facilement quand le silo était actif pour la dernière fois.
Extension pour ordonner les vues des appartenances
Le protocole d’appartenance de base décrit ci-dessus a été étendu ultérieurement pour prendre en charge les vues des appartenances ordonnées. Nous décrirons brièvement les raisons de cette extension et la façon dont elle est implémentée. L’extension ne change rien dans la conception ci-dessus, mais ajoute simplement la propriété indiquant que toutes les configurations d’appartenance sont totalement ordonnées globalement.
Pourquoi est-il utile d’ordonner les vues des appartenances ?
Cela permet de sérialiser la jointure de nouveaux silos au cluster. De cette façon, quand un nouveau silo rejoint le cluster, il peut valider la connectivité bidirectionnelle à chaque autre silo qui a déjà démarré. Si certains des silos qui ont déjà rejoint le cluster ne répondent pas (ce qui indique potentiellement un problème de connectivité réseau avec le nouveau silo), le nouveau silo n’est pas autorisé à rejoindre le cluster. Cela garantit au moins que quand un silo démarre, il existe une connectivité complète entre tous les silos dans le cluster (cela est implémenté).
Les protocoles de niveau supérieur dans le silo, tels que le répertoire de grain distribué, peuvent utiliser le fait que les vues des appartenances sont ordonnées et utiliser ces informations pour effectuer une résolution plus intelligente des activations en double. En particulier, quand le répertoire découvre que 2 activations ont été créées quand l’appartenance était dans un flux, il peut décider de désactiver l’ancienne activation qui a été créée en fonction des informations d’appartenance désormais obsolètes.
Protocole d’appartenance étendu :
Pour l’implémentation de cette fonctionnalité, nous utilisons la prise en charge des transactions sur plusieurs lignes fournies par
MembershipTable
.Nous ajoutons une ligne de version d’appartenance à la table pour suivre les modifications de la table.
Quand le silo S veut écrire une déclaration de soupçon ou de mort pour le silo P :
- S lit le contenu le plus récent de la table. Si P est déjà mort, ne rien faire. Sinon,
- Dans la même transaction, écrire les modifications apportées à la ligne de P, incrémenter le numéro de version et le réécrire dans la table.
- Les deux écritures sont conditionnées par des ETags.
- Si la transaction est annulée en raison d’une non-correspondance d’ETag sur la ligne de P ou la ligne de version, réessayez.
Toutes les écritures dans la table modifient et incrémentent la ligne de version. De cette façon, toutes les écritures dans la table sont sérialisées (via la sérialisation des mises à jour dans la ligne de version) et comme les silos incrémentent uniquement le numéro de version, les écritures sont également totalement ordonnées dans l’ordre croissant.
Scalabilité du protocole d’appartenance étendu :
Dans la version étendue de ce protocole, toutes les écritures sont sérialisées via une seule ligne. Cela peut potentiellement nuire à la scalabilité du protocole de gestion de cluster, car cela augmente le risque de conflits entre des écritures de table simultanées. Pour atténuer partiellement ce problème, les silos réessayent toutes leurs écritures dans la table à l’aide de l’interruption exponentielle. Nous avons observé que les protocoles étendus fonctionnent correctement dans un environnement de production dans Azure avec jusqu’à 200 silos. Toutefois, nous pensons que le protocole peut connaître des problèmes de mise à l’échelle au-delà de mille silos. Dans des configurations d’une telle taille, les mises à jour de la ligne de version peuvent être facilement désactivées, en conservant essentiellement le reste du protocole de gestion de cluster et en abandonnant la propriété de classement total. Notez également que nous faisons référence ici à la scalabilité du protocole de gestion de cluster, et non pas au reste d’Orleans. Nous pensons que d’autres parties du runtime Orleans (messagerie, répertoire distribué, hébergement de grain, connectivité du client à la passerelle) peuvent évoluer bien au-delà de quelques centaines de silos.
Table des appartenances
Comme cela a déjà été mentionné, la table IMembershipTable
est utilisée comme point de rendez-vous pour que les silos puissent se retrouver les uns les autres et que les clients Orleans puissent trouver les silos, et elle aide également à coordonner l’accord sur la vue des appartenances. Nous avons actuellement 6 implémentations de IMembershipTable
: basées sur Table Azure, SQL Server, Apache ZooKeeper, Consul IO, AWS DynamoDB et l’émulation en mémoire pour le développement.
Stockage Table Azure: dans cette implémentation, nous utilisons l’ID de déploiement Azure comme clé de partition et l’identité de silo (
ip:port:epoch
) comme clé de ligne. Ensemble, ils garantissent une clé unique par silo. Pour le contrôle d’accès concurrentiel, nous utilisons le contrôle d’accès concurrentiel optimiste basé sur les ETags de table Azure. Chaque fois que nous lisons à partir de la table, nous stockons l’ETag pour chaque ligne de lecture et utilisons cet ETag lorsque nous essayons d’écrire en différé. Les ETags sont automatiquement attribués et vérifiés par le service Table Azure à chaque écriture. Pour les transactions à plusieurs lignes, nous utilisons la prise en charge des transactions par lots fournies par la table Azure, qui garantit des transactions sérialisables sur des lignes avec la même clé de partition.SQL Server : dans cette implémentation, l’ID de déploiement configuré est utilisé pour établir la distinction entre les déploiements et les silos qui appartiennent aux déploiements. L’identité de silo est définie comme une combinaison de
deploymentID, ip, port, epoch
dans les tables et les colonnes appropriées. Le back-end relationnel utilise le contrôle d’accès concurrentiel optimiste et les transactions, comme dans la procédure d’utilisation des ETags dans l’implémentation de la table Azure. L’implémentation relationnelle s’attend à ce que le moteur de base de données génère l’ETag utilisé. Dans le cas de SQL Server, dans SQL Server 2000, l’ETag généré est un élément acquis à partir d’un appel àNEWID()
. Dans SQL Server 2005 et versions ultérieures, ROWVERSION est utilisé. Orleans lit et écrit des ETags relationnels sous forme d’étiquettesVARBINARY(16)
opaques et les stocke en mémoire sous forme de chaînes codées en base64. Orleans prend en charge les insertions à plusieurs lignes à l’aide deUNION ALL
(pour Oracle, y compris DUAL), ce qui est actuellement utilisé pour insérer des données statistiques. L’implémentation et la logique exactes de SQL Server sont visibles dans CreateOrleansTables_SqlServer.sql.Apache ZooKeeper : dans cette implémentation, nous utilisons l’ID de déploiement configuré comme nœud racine et l’identité de silo (
ip:port@epoch
) comme son nœud enfant. Ensemble, ils garantissent un chemin unique par silo. Pour le contrôle d’accès concurrentiel, nous utilisons le contrôle d’accès concurrentiel optimiste basé sur la version du nœud. Chaque fois que nous lisons à partir du nœud racine de déploiement, nous stockons la version pour chaque nœud de silo enfant lu et utilisons cette version lorsque nous essayons d’écrire en différé. Chaque fois que les données d’un nœud changent, le numéro de version augmente atomiquement via le service ZooKeeper. Pour les transactions à plusieurs lignes, nous utilisons la méthode multifacteur, qui garantit des transactions sérialisables sur les nœuds de silo avec le même nœud d’ID de déploiement parent.Consul IO : nous avons utilisé le magasin de clés/valeurs de Consul pour implémenter la table des appartenances. Pour plus d’informations, consultez Déploiement de Consul.
AWS DynamoDB : dans cette implémentation, nous utilisons l’ID de déploiement du cluster comme clé de partition et l’identité de silo (
ip-port-generation
) comme RangeKey qui fait l’unité de l’enregistrement. L’accès concurrentiel optimiste est réalisé par l’attributETag
en effectuant des écritures conditionnelles sur DynamoDB. La logique d’implémentation est assez similaire au Stockage Table Azure.Émulation en mémoire pour la configuration du développement. Nous utilisons un grain de système spécial, appelé MembershipTableGrain, pour cette implémentation. Ce grain réside sur un silo principal désigné, qui est utilisé uniquement pour une configuration de développement. Dans toute utilisation réelle en production le silo principal n’est pas obligatoire.
Configuration
Le protocole d’appartenance est configuré via l’élément Liveness
de la section Globals
du fichier OrleansConfiguration.xml. Les valeurs par défaut ont été ajustées au cours des années d’utilisation en production dans Azure et nous croyons qu’elles représentent de bons paramètres par défaut. Il n’est pas nécessaire de les modifier en général.
Exemple d’élément de configuration :
<Liveness ProbeTimeout="5s"
TableRefreshTimeout="10s"
DeathVoteExpirationTimeout="80s"
NumMissedProbesLimit="3"
NumProbedSilos="3"
NumVotesForDeathDeclaration="2" />
Il existe 4 types d’activité implémentés. Le type du protocole d’activité est configuré via l’attribut SystemStoreType
de l’élément SystemStore
dans la section Globals
du fichier OrleansConfiguration.xml.
MembershipTableGrain
: la table des appartenances est stockée dans un grain sur le silo principal. Il s’agit d’une configuration de développement uniquement.AzureTable
: la table des appartenances est stockée dans une table Azure.SqlServer
: la table des appartenances est stockée dans une base de données relationnelle.ZooKeeper
: la table des appartenances est stockée dans un ensemble ZooKeeper.Consul
: configuré en tant que magasin système personnalisé avecMembershipTableAssembly = "OrleansConsulUtils"
. Pour plus d’informations, consultez Déploiement de Consul.DynamoDB
: configuré en tant que magasin système personnalisé avecMembershipTableAssembly = "OrleansAWSUtils"
.
Pour tous les types d’activité, les variables de configuration courantes sont définies dans l’élément Globals.Liveness
:
ProbeTimeout
: nombre de secondes pour sonder l’activité des autres silos ou pour que le silo envoie des messages de pulsation « Je suis actif » sur lui-même. La valeur par défaut est de 10 secondes.TableRefreshTimeout
: nombre de secondes pour récupérer les mises à jour de la table des appartenances. La valeur par défaut est 60 secondes.DeathVoteExpirationTimeout
: délai d’expiration en secondes pour le vote de mort dans la table des appartenances. La valeur par défaut est de 120 secondes.NumMissedProbesLimit
: nombre de messages de pulsation « Je suis actif » manqués à partir d’un silo ou nombre de sondes non répondues qui conduisent à soupçonner ce silo d’être mort. La valeur par défaut est 3.NumProbedSilos
: nombre de silos dont chaque silo sonde l’activité. La valeur par défaut est 3.NumVotesForDeathDeclaration
: nombre de votes non expirés nécessaires pour déclarer un silo comme mort (doit être au maximum de NumMissedProbesLimit). La valeur par défaut est 2.UseLivenessGossip
: indique s’il faut utiliser l’optimisation Gossip pour accélérer la diffusion des informations d’activité. La valeur par défaut est true.IAmAliveTablePublishTimeout
: nombre de secondes à écrire périodiquement dans la table des appartenances que ce silo est actif. Utile uniquement pour les diagnostics. La valeur par défaut est de 5 minutes.NumMissedTableIAmAliveLimit
: nombre de mises à jour « Je suis actif » manquées dans la table à partir d’un silo qui provoque la journalisation d’un avertissement. N’a pas d’impact sur le protocole d’activité. La valeur par défaut est 2.MaxJoinAttemptTime
: nombre de secondes pour tenter de rejoindre un cluster de silos avant de renoncer. La valeur par défaut est de 5 minutes.ExpectedClusterSize
: taille attendue d’un cluster. Inutile d’être très précis, peut être une surestimation. Utilisé pour ajuster l’algorithme d’interruption exponentielle des nouvelles tentatives d’écriture dans la table Azure. La valeur par défaut est 20.
Logique de conception
Une question naturelle qui peut être posée est pourquoi ne pas s’appuyer complètement sur Apache ZooKeeper pour l’implémentation de l’appartenance au cluster, potentiellement en utilisant sa prise en charge prête à l’emploi pour l’appartenance aux groupes avec des nœuds éphémères ? Pourquoi avons-nous pris la peine d’implémenter notre protocole d’appartenance ? Il y avait principalement trois raisons :
Déploiement/hébergement dans le cloud :
Zookeeper n’est pas un service hébergé (du moins au moment de la rédaction de ce contenu, en juillet 2015, et quand nous avons implémenté ce protocole pour la première fois à l’été 2011, il n’y avait pas de version de Zookeeper en cours d’exécution comme service hébergé par n’importe quel grand fournisseur de cloud). Cela signifie que dans l’environnement cloud, les clients Orleans doivent déployer/exécuter/gérer leur instance d’un cluster ZK. Ce n’est là qu’un autre fardeau inutile, que nous ne voulions pas imposer à nos clients. En utilisant la table Azure, nous nous appuyons sur un service géré hébergé qui simplifie considérablement la vie de notre client. En fait, dans le cloud, utilisez le cloud en tant que plateforme, et non pas en tant qu’infrastructure. D’un autre côté, lors de l’exécution locale et de la gestion de vos serveurs, s’appuyer sur ZK comme implémentation de l’élément
IMembershipTable
est une option viable.Détection directe des défaillances :
Lorsque vous utilisez l’appartenance aux groupes de ZK avec des nœuds éphémères, la détection des défaillances s’effectue entre les serveurs Orleans (clients ZK) et les serveurs ZK. Cela peut ne pas nécessairement correspondre aux problèmes réseau réels entre des serveurs Orleans. Notre désir était que la détection des défaillances reflète avec précision l’état de la communication à l’intérieur du cluster. Plus précisément, dans notre conception, si un silo Orleans ne peut pas communiquer avec
IMembershipTable
, il n’est pas considéré comme mort et peut continuer à fonctionner. Par contre, si nous utilisons l’appartenance aux groupes de ZK avec des nœuds éphémères, une déconnexion d’un serveur ZK peut entraîner la déclaration d’un silo Orleans (client ZK) comme mort, alors qu’il peut être actif et pleinement fonctionnel.Portabilité et flexibilité :
Dans le cadre de la philosophie d’Orleans, nous ne voulons pas imposer une forte dépendance à toute technologie particulière, mais plutôt disposer d’une conception flexible où différents composants peuvent facilement basculer entre différentes implémentations. L’abstraction
IMembershipTable
sert exactement cet objectif.
Remerciements
Nous reconnaissons la contribution d’Alex Kogan à la conception et à l’implémentation de la première version de ce protocole. Ce travail a été effectué dans le cadre d’un stage d’été dans Microsoft Research à l’été 2011.
L’implémentation de IMembershipTable
basée sur ZooKeeper a été effectuée par Shay Hazor, l’implémentation de IMembershipTable
basée sur SQL a été effectuée par Veikko Eeva, l’implémentation de IMembershipTable
basée sur AWS DynamoDB a été effectuée par Gutemberg Ribeiro et l’implémentation de IMembershipTable
basée sur Consul a été effectuée par Paul North.