Configuration multicluster
La configuration multicluster détermine quels sont les clusters qui font partie du multicluster. Elle ne change pas automatiquement, elle est contrôlée par l’opérateur. Ainsi, elle est assez différente du mécanisme d’appartenance utilisé dans un cluster, et qui détermine automatiquement l’ensemble des silos qui font partie du cluster.
Nous utilisons la terminologie suivante pour les clusters d’un service :
- Un cluster est actif s’il a au moins un silo actif. Sinon, il est inactif.
- Un cluster est joint s’il fait partie de la configuration multicluster actuelle. Sinon, il est non joint.
Le fait d’être actif/inactif ne dépend pas du fait d’être joint/non joint : les quatre combinaisons sont possibles.
Tous les clusters d’un service particulier sont connectés par un réseau Gossip. Le réseau Gossip propage les informations de configuration et d’état.
Injecter une configuration
Un opérateur émet des changements de configuration en les injectant dans le réseau multicluster. Les configurations peuvent être injectées dans n’importe quel cluster et ensuite étendues à tous les clusters actifs. Chaque nouvelle configuration se compose d’une liste d’ID de cluster qui forment le multicluster. Elle dispose également d’un horodatage UTC qui permet de suivre sa propagation sur le réseau Gossip.
Initialement, la configuration multicluster a une valeur null, ce qui signifie que la liste multicluster est vide (elle ne contient aucun cluster). Ainsi, l’opérateur doit dans un premier temps injecter une configuration multicluster. Une fois injectée, cette configuration est conservée de manière persistante dans tous les silos connectés (durant l’exécution) et dans tous les canaux Gossip spécifiés (si ces canaux sont persistants).
Nous imposons certaines restrictions sur l’injection de nouvelles configurations, qu’un opérateur doit suivre :
- Chaque nouvelle configuration peut ajouter plusieurs clusters ou supprimer certains clusters (mais pas les deux à la fois).
- Un opérateur ne doit pas émettre de nouvelle configuration tant qu’un changement de configuration précédent est toujours en cours de traitement.
Ces restrictions permettent de garantir que les protocoles tels que le protocole mono-instance peuvent correctement gérer le mutex des activations, même en cas de changements apportés à la configuration.
Grain de gestion
Les configurations multiclusters peuvent être injectées sur n’importe quel nœud de n’importe quel cluster, à l’aide du grain de gestion de Orleans. Par exemple, pour injecter une configuration multicluster composée des trois clusters {us1, eu1, us2}, nous pouvons passer une chaîne énumérable au grain de gestion :
var clusters = "us1,eu1,us2".Split(',');
var mgtGrain = client.GetGrain<IManagementGrain>(0);
mgtGrain.InjectMultiClusterConfiguration(clusters, "my comment here"));
Le premier argument de InjectMultiClusterConfiguration(IEnumerable<String>, String, Boolean) est une collection d’ID de cluster, qui vont définir la nouvelle configuration multicluster. Le deuxième argument est une chaîne de commentaires (facultative) qui peut être utilisée pour étiqueter les configurations avec des informations arbitraires, par exemple qui les a injectées et pourquoi.
Il existe un troisième argument facultatif, un booléen appelé checkForLaggingSilosFirst
, dont la valeur par défaut est true. Cela signifie que le système effectue une vérification optimale pour déterminer s’il existe des silos qui n’ont pas encore rattrapé la configuration actuelle, et qu’il rejette le changement s’il trouve un tel silo. Cela permet de détecter les violations de la restriction selon laquelle un seul changement de configuration doit être en attente à la fois (bien que cela ne permette pas de le garantir en toutes circonstances).
Configuration par défaut
Dans les situations où la configuration multicluster est connue à l’avance et où le déploiement est renouvelé à chaque fois (à des fins de test), nous pouvons être amenés à fournir une configuration par défaut. La configuration globale prend en charge un attribut facultatif DefaultMultiCluster, qui accepte une liste d’ID de cluster séparés par des virgules :
var silo = new HostBuilder()
.UseOrleans(builder =>
{
builder.Configure<MultiClusterOptions>(options =>
{
options.DefaultMultiCluster = new[] { "us1", "eu1", "us2" };
})
})
.Build();
Une fois qu’un silo a démarré avec ce paramètre, il vérifie si la configuration multicluster actuelle a une valeur null et, si tel est le cas, injecte la configuration donnée avec l’horodatage UTC actuel.
Avertissement
Les canaux Gossip multiclusters persistants (basés sur AzureTable) conservent la dernière configuration injectée, sauf s’ils sont supprimés explicitement. Dans ce cas, la spécification de DefaultMultiCluster
n’a aucun effet au moment du redéploiement d’un cluster, car la configuration stockée dans les canaux Gossip n’a pas une valeur null.>
Canal Gossip
Un opérateur peut également injecter la configuration directement dans le canal Gossip. Les changements apportés au canal sont détectés et propagés automatiquement par les communications Gossip périodiques en arrière-plan, mais éventuellement très lentement (l’utilisation du grain de gestion est beaucoup plus rapide). L’estimation approximative du temps de propagation est de 30 secondes (ou tout autre intervalle Gossip spécifié dans la configuration globale) multiplié par le logarithme binaire du nombre total de silos dans tous les clusters. Toutefois, dans la mesure où les paires Gossip sont sélectionnées au hasard, elles peuvent être à la fois beaucoup plus rapides ou beaucoup plus lentes.
S’ils utilisent le canal Gossip basé sur des tables Azure, les opérateurs peuvent injecter une nouvelle configuration en modifiant simplement l’enregistrement de configuration dans OrleansGossipTable
, à l’aide d’un outil permettant de modifier les données dans les tables Azure. L’enregistrement de configuration a le format suivant :
Nom | Type | Valeur |
---|---|---|
PartitionKey | String | ServiceId |
RowKey | String | « CONFIG » |
Clusters | String | liste d’ID de cluster séparés par des virgules, par exemple « us1,eu1,us2 » |
Commentaire | String | commentaire facultatif |
GossipTimestamp | DateTime | horodatage UTC de la configuration |
Notes
Quand vous modifiez cet enregistrement dans le stockage, GossipTimestamp
doit également avoir une valeur plus récente que sa valeur actuelle (sinon le changement est ignoré). La méthode la plus pratique, et recommandée, consiste à supprimer le champ GossipTimestamp
. Notre implémentation de canal Gossip le remplace ensuite automatiquement par l’horodatage correct actuel (l’horodatage de la table Azure est utilisé).
Procédures de cluster
L’ajout ou la suppression d’un cluster du multicluster doit souvent être coordonné dans un contexte plus grand. Nous vous recommandons de toujours suivre les procédures décrites ci-dessous quand vous ajoutez/supprimez des clusters du multicluster.
Procédure d’ajout d’un cluster
- Démarrez un nouveau cluster Orleans, et attendez que tous les silos soient opérationnels.
- Injectez une configuration qui contient le nouveau cluster.
- Commencez à router les requêtes des utilisateurs vers le nouveau cluster.
Procédure de suppression d’un cluster
- Arrêtez de router les nouvelles requêtes des utilisateurs vers le cluster.
- Injectez une configuration qui ne contient plus le cluster.
- Arrêtez tous les silos du cluster.
Une fois qu’un cluster a été supprimé de cette façon, vous pouvez le rajouter en suivant la procédure d’ajout d’un nouveau cluster.
Activité sur les clusters non joints
Il peut exister de brèves périodes où un cluster est à la fois actif et non joint :
- Un cluster qui vient de démarrer peut commencer à exécuter du code avant qu’il ne se trouve en configuration multicluster (entre les étapes 1 et 2 de la procédure d’ajout d’un cluster)
- Un cluster désactivé peut toujours exécuter du code avant l’arrêt des silos (entre les étapes 2 et 3 de la procédure de suppression d’un cluster).
Dans ces situations intermédiaires, les actions suivantes sont possibles :
- Pour les grains GSI (Global Single Instance) : un grain peut avoir une activation dupliquée sur un cluster non joint.
- Pour les grains versionnés : les activations sur les clusters non joints ne reçoivent pas de notifications quand l’état du grain change.