Coût du déplacement de services

L’un des facteurs que Service Fabric Cluster Resource Manager prend en compte pour déterminer les modifications à apporter à un cluster est leur coût. La notion de « coût » est mise en balance avec la capacité d’amélioration du cluster. Le coût est pris en compte lors du déplacement de services à des fins d’équilibrage, de défragmentation ou autres. L’objectif est de répondre aux exigences en limitant les perturbations et le coût.

Le déplacement de services coûte au minimum du temps processeur et de la bande passante réseau. Pour les services avec état, il suppose de copier l’état de ces services, ce qui consomme davantage de mémoire et de disque. Réduire le coût des solutions fournies par Azure Service Fabric Cluster Resource Manager permet de s’assurer que les ressources du cluster ne sont pas exploitées inutilement. Mais il ne faut pas non plus ignorer les solutions qui pourraient améliorer considérablement l’allocation de ressources dans le cluster.

Cluster Resource Manager dispose de deux modes de calcul et de limitation des coûts lorsqu’il gère le cluster. Le premier mécanisme consiste simplement à compter chacun des déplacements qui seraient effectués. Si deux solutions présentant à peu près le même solde (score) sont générées, Cluster Resource Manager préfère celle qui affiche le coût le plus bas (nombre total de déplacements).

Cette stratégie fonctionne bien. Mais, comme avec les charges par défaut ou statiques, il est peu probable dans n’importe quel système complexe que tous les déplacements soient égaux. Certains sont susceptibles d’être beaucoup plus coûteux.

Définir les coûts de déplacement

Vous pouvez spécifier le coût par défaut de déplacement d’un service lors de sa création :

PowerShell :

New-ServiceFabricService -ApplicationName $applicationName -ServiceName $serviceName -ServiceTypeName $serviceTypeName –Stateful -MinReplicaSetSize 3 -TargetReplicaSetSize 3 -PartitionSchemeSingleton -DefaultMoveCost Medium

C# :

FabricClient fabricClient = new FabricClient();
StatefulServiceDescription serviceDescription = new StatefulServiceDescription();
//set up the rest of the ServiceDescription
serviceDescription.DefaultMoveCost = MoveCost.Medium;
await fabricClient.ServiceManager.CreateServiceAsync(serviceDescription);

Vous pouvez également spécifier ou mettre à jour dynamiquement MoveCost pour un service après sa création :

PowerShell :

Update-ServiceFabricService -Stateful -ServiceName "fabric:/AppName/ServiceName" -DefaultMoveCost High

C# :

StatefulServiceUpdateDescription updateDescription = new StatefulServiceUpdateDescription();
updateDescription.DefaultMoveCost = MoveCost.High;
await fabricClient.ServiceManager.UpdateServiceAsync(new Uri("fabric:/AppName/ServiceName"), updateDescription);

Spécifier dynamiquement le coût de déplacement pour chaque réplica

Les extraits de code précédents permettent tous de spécifier MoveCost pour la totalité d’un service d’un seul coup en dehors du service proprement dit. Toutefois, le coût de déplacement prend toute son utilité lorsque, pour un objet de service donné, il change au cours de sa vie. Étant donné que ce sont probablement les services eux-mêmes qui sont les mieux placés pour savoir combien coûte leur déplacement à un instant t, il existe une API qui permet aux services de signaler leur propre coût de déplacement à l’exécution.

C# :

this.Partition.ReportMoveCost(MoveCost.Medium);

Notes

Vous ne pouvez définir le coût de déplacement que pour les réplicas secondaires par le biais du code.

Rapport sur le coût de déplacement pour une partition

La section précédente décrit comment les réplicas de service ou les instances signalent eux-mêmes MoveCost. Nous avons fourni l’API Service Fabric pour signaler les valeurs MoveCost pour le compte d’autres partitions. Parfois, le réplica ou l’instance de service ne peut pas déterminer la meilleure valeur MoveCost par lui-même et doit s’appuyer sur d’autres logiques de services. La création de rapports MoveCost pour le compte d’autres partitions, en plus des rapports de charge pour le compte d’autres partitions, vous permet de gérer entièrement les partitions à partir de l’extérieur. Ces API éliminent les besoins en matière de modèle de side-car, du point de vue du gestionnaire des ressources clusters.

Vous pouvez signaler des mises à jour MoveCost pour une partition différente avec le même appel d’API. Vous devez spécifier l’objet PartitionMoveCostDescription pour chaque partition que vous souhaitez mettre à jour avec les nouvelles valeurs de MoveCost. L’API permet de mettre à jour MoveCost de plusieurs façons :

  • Une partition de service avec état peut mettre à jour sa charge de réplica principal MoveCost.
  • Les services sans état et avec état peuvent mettre à jour MoveCost de tous ses réplicas secondaires ou instances.
  • Les services sans état et avec état peuvent mettre à jour MoveCost d’un réplica ou d’une instance spécifique sur un nœud.

Chaque mise à jour MoveCost pour la partition doit contenir au moins une valeur valide qui sera modifiée. Par exemple, vous pouvez ignorer la mise à jour du réplica principal avec l’affectation de la valeur Null à l’entrée du réplica principal, d’autres entrées seront utilisées pendant la mise à jour de MoveCost et ignorer la mise à jour MoveCost pour le réplica principal. Étant donné que la mise à jour de MoveCost pour plusieurs partitions avec un appel d’API unique est possible, l’API fournit une liste de codes de retour pour la partition correspondante. Si nous acceptons et traitons avec succès une demande de mise à jour MoveCost, le code de retour est Success. Dans le cas contraire, l’API fournit un code d’erreur :

  • PartitionNotFound - L’ID de partition spécifié n’existe pas.
  • ReconfigurationPending - La partition est en cours de reconfiguration.
  • InvalidForStatelessServices : une tentative de modification du MoveCost d’un réplica principal pour une partition appartenant à un service sans état a été effectuée.
  • ReplicaDoesNotExist - Le réplica ou l’instance secondaire n’existe pas sur un nœud spécifié.
  • InvalidOperation : mise à jour de MoveCost pour une partition qui appartient à l’application système.

C# :

Guid partitionId = Guid.Parse("53df3d7f-5471-403b-b736-bde6ad584f42");
string nodeName0 = "NodeName0";

OperationResult<UpdatePartitionMoveCostResultList> updatePartitionMoveCostResults =
    await this.FabricClient.UpdatePartitionMoveCostAsync(
        new UpdatePartitionMoveCostQueryDescription
        {
            new List<PartitionMoveCostDescription>()
            {
                new PartitionMoveCostDescription(
                    partitionId,
                    MoveCost.VeryHigh,
                    MoveCost.Zero,
                    new List<ReplicaMoveCostDescription>()
                    {
                        new ReplicaMoveCostDescription(nodeName0, MoveCost.Medium)
                    })
            }
        },
        this.Timeout,
        cancellationToken);

Dans cet exemple, vous allez effectuer une mise à jour de la dernière charge signalée pour une partition 53df3d7f-5471-403b-b736-bde6ad584f42. Le coût de déplacement du réplica principal sera VeryHigh. Tous les réplicas secondaires ont un coût de déplacement égal à zéro, à l’exception du coût de déplacement pour un réplica secondaire spécifique situé sur le nœud NodeName0. Le coût de déplacement pour un réplica spécifique sera Moyen. Si vous souhaitez ignorer la mise à jour du coût de déplacement pour le réplica principal ou tous les réplicas secondaires, vous pouvez faire en sorte que l’entrée correspondante soit Null.

Impact du coût de déplacement

MoveCost a cinq niveaux : zéro, faible, moyen, élevé et VeryHigh. Les règles suivantes s’appliquent :

  • À l’exception de Zero et VeryHigh, ces niveaux MoveCost sont liés les uns aux autres.
  • Un coût de déplacement de zéro signifie que le déplacement est gratuit et ne doit pas compter dans le score de la solution.
  • Le fait de régler votre coût de déplacement sur High ou VeryHigh ne permet pas de garantir que le réplica ne sera jamais déplacé.
  • Les réplicas avec un coût de déplacement VeryHigh sont déplacés uniquement si une violation de contrainte existant dans le cluster ne peut pas être résolue d’une autre façon (même si elle nécessite de déplacer de nombreux autres réplicas pour résoudre la violation)

Coût du déplacement comme facteur de sélection des réplicas pour les déplacements

MoveCost vous permet de rechercher les solutions qui provoquent globalement le moins de perturbations et qui sont les plus faciles à mettre en place tout en obtenant un équilibre équivalent. La notion de coût d’un service peut être liée à beaucoup de choses. Les facteurs les plus courants pour calculer le coût de déplacement sont :

  • La quantité d’état ou de données que le service doit déplacer.
  • Le coût de déconnexion des clients. Le déplacement d’un réplica principal coûte généralement plus cher que celui d’un réplica secondaire.
  • Le coût d’interruption d’une opération en cours. Certaines opérations au niveau du magasin de données ou en réponse à un appel du client sont coûteuses. Après un certain point, il est préférable de ne pas les arrêter si vous n’êtes pas obligé de le faire. Par conséquent, pendant l’opération, vous augmentez le coût du déplacement de cet objet de service afin de réduire la probabilité qu’il se déplace. Lorsque l’opération se termine, vous rétablissez le coût normal.

Important

L’utilisation du coût de déplacement VeryHigh doit être soigneusement envisagée, car elle restreint de manière significative la capacité du Gestionnaire des ressources clusters à trouver une solution de placement globalement optimale dans le cluster. Les réplicas avec un coût de déplacement VeryHigh sont déplacés uniquement si une violation de contrainte existant dans le cluster ne peut pas être résolue d’une autre façon (même si elle nécessite de déplacer de nombreux autres réplicas pour résoudre la violation)

Activer le coût de déplacement dans un cluster

Pour que les coûts de déplacement pris en compte soient aussi précis que possible, MoveCost doit être activé dans le cluster. Sans ce paramètre, le mode par défaut, qui consiste à compter les déplacements, est utilisé pour calculer MoveCost, et les rapports MoveCost sont ignorés.

ClusterManifest.xml :

        <Section Name="PlacementAndLoadBalancing">
            <Parameter Name="UseMoveCostReports" Value="true" />
        </Section>

via ClusterConfig.json pour les déploiements autonomes ou Template.json pour les clusters hébergés sur Azure :

"fabricSettings": [
  {
    "name": "PlacementAndLoadBalancing",
    "parameters": [
      {
          "name": "UseMoveCostReports",
          "value": "true"
      }
    ]
  }
]

Étapes suivantes