Kosten von Dienstverschiebungen

Ein Faktor bei den Überlegungen im Cluster Resource Manager von Service Fabric zu Veränderungen an einem Cluster sind die Kosten, die mit diesen Änderungen verbunden sind. Die „Kosten“ werden dabei gegen die mögliche Verbesserung des Clusters abgewogen. Die Kosten werden berücksichtigt, wenn Dienste zum Lastenausgleich, zur Defragmentierung und aufgrund anderer Anforderungen verschoben werden. Ziel ist es, die Anforderungen auf die am wenigsten störende und kostengünstigste Weise zu erfüllen.

Das Verschieben von Diensten kostet zumindest CPU-Zeit und Netzwerkbandbreite. Für zustandsbehaftete Dienste muss eine Kopie des Zustands der Dienste erstellt werden. Dies erfordert zusätzlichen Speicherplatz im Arbeitsspeicher und auf dem Datenträger. Durch Minimieren der Kosten von Lösungen, die vom Cluster Resource Manager in Azure Service Fabric bereitgestellt werden, kann sichergestellt werden, dass die Ressourcen des Clusters nicht unnötigerweise verbraucht werden. Sie möchten jedoch auch alle Lösungen kennen, die die Zuordnung von Ressourcen im Cluster erheblich verbessern würden.

Der Cluster Resource Manager bietet zwei Möglichkeiten, die Kosten zu berechnen und zu beschränken und gleichzeitig den Cluster möglichst optimal zu verwalten. Bei der ersten Möglichkeit wird einfach jede einzelne Verschiebung gezählt, die erforderlich ist. Wenn zwei Lösungen mit nahezu identischem Lastenausgleich (Bewertung) generiert werden, wird im Cluster Resource Manager die Lösung mit den geringsten Kosten (Gesamtzahl der Verschiebungen) bevorzugt.

Diese Strategie funktioniert sehr gut. Aber wie bei standardmäßigen oder statischen Lasten ist es in einem komplexen System unwahrscheinlich, dass alle Verschiebungen gleich sind. Einige sind wahrscheinlich viel teurer.

Festlegen der Verschiebungskosten

Sie können die Standardverschiebungskosten für einen Dienst bei dessen Erstellung angeben:

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);

Sie können MoveCost für einen Dienst auch nach dessen Erstellung dynamisch angeben oder aktualisieren:

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);

Dynamisches Angeben der Verschiebungskosten pro Replikat

In sämtlichen vorangegangenen Codeausschnitten wird MoveCost direkt für einen gesamten Dienst außerhalb des Diensts angegeben. Verschiebungskosten erweisen sich jedoch als besonders nützlich, wenn sich die Verschiebungskosten eines bestimmten Dienstobjekts im Lauf seiner Lebensdauer ändern. Da die entsprechenden Kosten für die Verschiebung zu einem bestimmten Zeitpunkt wahrscheinlich am besten den jeweiligen Diensten zu entnehmen sind, liegt eine API für Dienste zum Erfassen der individuellen Verschiebungskosten während der Laufzeit vor.

C#:

this.Partition.ReportMoveCost(MoveCost.Medium);

Hinweis

Sie können die Verschiebungskosten für sekundäre Replikate nur über Code festlegen.

Bericht der Verschiebungskosten für eine Partition

Der vorherige Abschnitt beschreibt, wie Service-Replikate oder Instanzen selbst MoveCost melden. Wir haben Service Fabric API für die Meldung von MoveCost-Werten im Namen anderer Partitionen bereitgestellt. Manchmal kann der Dienst Replica oder die Instanz den besten MoveCost-Wert nicht selbst ermitteln und muss sich auf die Logik anderer Dienste verlassen. Die Berichterstattung über MoveCost im Namen anderer Partitionen ermöglicht Ihnen neben der Berichterstattung über die Auslastung anderer Partitionen die vollständige Verwaltung der Partitionen von außen. Diese APIs machen das Sidecar-Muster aus der Sicht des Clusterressourcen-Managers überflüssig.

Sie können mit demselben API-Aufruf MoveCost-Aktualisierungen für eine andere Partition melden. Sie müssen das Objekt PartitionMoveCostDescription für jede Partition angeben, die Sie mit neuen Werten für MoveCost aktualisieren möchten. Die API bietet mehrere Möglichkeiten, MoveCost zu aktualisieren:

  • Eine zustandsabhängige Dienst-Partition kann ihr primäres Replikat MoveCost aktualisieren.
  • Sowohl zustandslose als auch zustandsabhängige Dienste können die MoveCost aller sekundären Replikate oder Instanzen aktualisieren.
  • Sowohl zustandslose als auch zustandsabhängige Dienste können die MoveCost einer bestimmten Replik oder Instanz auf einem Knoten aktualisieren.

Jede MoveCost-Aktualisierung für eine Partition sollte mindestens einen gültigen Wert enthalten, der geändert wird. Sie können beispielsweise die Aktualisierung des primären Replikats überspringen, indem Sie dem Eintrag für das primäre Replikat die Zahl Null zuweisen. Die anderen Einträge werden während der MoveCost-Aktualisierung verwendet und wir überspringen die MoveCost-Aktualisierung für das primäre Replikat. Da die Aktualisierung von MoveCost für mehrere Partitionen mit einem einzigen API-Aufruf möglich ist, bietet die API eine Liste von Rückgabecodes für die entsprechende Partition. Wenn wir eine Anforderung für eine MoveCost-Aktualisierung erfolgreich annehmen und bearbeiten, lautet der Rückgabecode Success. Andernfalls liefert die API einen Fehlercode:

  • PartitionNotFound: Die angegebene Partitions-ID ist nicht vorhanden.
  • ReconfigurationPending: Die Partition wird zurzeit neu konfiguriert.
  • InvalidForStatelessServices: Es wurde versucht, die MoveCost eines primären Replikats für eine Partition zu ändern, die zu einem zustandslosen Dienst gehört.
  • ReplicaDoesNotExist: Das sekundäre Replikat oder die Instanz für einen angegebenen Knoten ist nicht vorhanden.
  • InvalidOperation – Aktualisierung von MoveCost für eine Partition, die zur Anwendung System gehört.

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);

In diesem Beispiel aktualisieren Sie die zuletzt gemeldeten Verschiebekosten für eine Partition 53df3d7f-5471-403b-b736-bde6ad584f42. Die Kosten für die Verschiebung des primären Replikat sind VeryHigh. Die Kosten für die Verschiebung aller sekundären Replikate werden auf Null gesetzt, mit Ausnahme der Kosten für die Verschiebung eines bestimmten sekundären Replikats, das sich auf dem Knoten NodeName0 befindet. Die Verschiebungskosten für ein bestimmtes Replikat sind mittel. Wenn Sie die Aktualisierung der Verschiebungskosten für das primäre Replikat oder alle sekundären Replikate überspringen möchten, können Sie den entsprechenden Eintrag als Null belassen.

Auswirkungen von Verschiebungskosten

MoveCost hat fünf Ebenen: Zero, Low, Medium, High und VeryHigh. Es gelten die folgenden Regeln:

  • MoveCosts stehen zueinander in einem Verhältnis, mit Ausnahme von Zero und VeryHigh.
  • Zero bedeutet, dass das Verschieben keine Kosten generiert und die Bewertung der Lösung nicht negativ beeinflussen sollte.
  • Das Umstellen der Kosten auf High oder VeryHigh bietet keine Garantie, dass das Replikat nie verschoben wird.
  • Replikate mit Verschiebungskosten von VeryHigh werden nur verschoben, wenn eine Einschränkungsverletzung im Cluster vorliegt, die nicht auf andere Weise behoben werden kann (selbst wenn zum Beheben der Verletzung viele andere Replikate verschoben werden müssen).

Verschiebungskosten als Faktor bei der Auswahl der zu verschiebenden Replikate

MoveCost hilft Ihnen dabei, Lösungen zu finden, die insgesamt die geringsten Unterbrechungen verursachen, am leichtesten umzusetzen sind und dabei das beste Gleichgewicht versprechen. Die Kosten für einen Dienst können von Vielem abhängen. Die gängigsten Faktoren bei der Berechnung der Kosten von Verschiebungen sind:

  • Die Menge von Zuständen oder Daten, die ein Dienst verschieben soll.
  • Die Kosten der Trennung von Clients. Die Verschiebung eines primären Replikats ist normalerweise kostenintensiver als die Verschiebung eines sekundären Replikats.
  • Die Kosten für Unterbrechungen einer sich in der Ausführung befindenden Operation. Einige Operationen auf Datenspeicherebene oder Operationen, die als Antwort auf einen Clientaufruf ausgeführt werden, sind kostenaufwendig. Ab einem bestimmten Punkt werden sie nicht mehr unnötigerweise freiwillig abgebrochen. Sie erhöhen daher während des Vorgangs die Kosten für das Verschieben dieses Dienstobjekts, um die Wahrscheinlichkeit zu verringern, dass es verschoben wird. Wenn der Vorgang abgeschlossen ist, können Sie die Kosten wieder auf den normalen Wert zurückstufen.

Wichtig

Die Nutzung von VeryHigh-Verschiebungskosten sollte sorgfältig erwogen werden, da dabei erheblich die Fähigkeit des Clusterressourcen-Managers beeinträchtigt wird, eine global-optimale Platzierungslösung im Cluster zu ermitteln. Replikate mit Verschiebungskosten von VeryHigh werden nur verschoben, wenn eine Einschränkungsverletzung im Cluster vorliegt, die nicht auf andere Weise behoben werden kann (selbst wenn zum Beheben der Verletzung viele andere Replikate verschoben werden müssen).

Aktivieren von Verschiebungskosten in Ihrem Cluster

Damit die differenzierten MoveCosts berücksichtigt werden können, muss MoveCost in Ihrem Cluster aktiviert werden. Ohne diese Einstellung wird der Standardmodus für das Zählen von Verschiebungen zur Berechnung von MoveCost verwendet. MoveCost-Berichte werden dagegen ignoriert.

ClusterManifest.xml

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

Über „ClusterConfig.json“ für eigenständige Bereitstellungen bzw. über „Template.json“ für in Azure gehostete Cluster:

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

Nächste Schritte