サービスの移動コスト

クラスターに対してどのような変更を行うかを決定するときに Service Fabric Cluster Resource Manager が考慮する要因は、それらの変更のコストです。 "コスト" の概念は、クラスターをどの程度向上させることができるかとのトレードオフです。 コストは、均衡化、デフラグ、およびその他の要件に対応するためにサービスを移動するときに考慮されます。 その目標は、中断が最も少ない方法またはコストがかからない方法で要件を満たすことです。

サービスの移動には、最低でも CPU 時間とネットワーク帯域幅のコストがかかります。 ステートフル サービスでは、サービスの状態をコピーする必要があり、メモリとディスクがさらに消費されます。 Azure Service Fabric Cluster Resource Manager が見つけ出すソリューションのコストを最小限に抑えることによって、クラスターのリソースが不必要に費やされることがないことを保証できます。 一方でクラスター内のリソースの割り当てを大幅に改善するソリューションを無視することは避けたいものです。

Cluster Resource Manager は、クラスターを管理するときに、コストを 2 つの方法で計算し、それらを制限します。 最初のメカニズムは、実行するすべての移動の回数を単純にカウントします。 2 つのソリューションがほぼ同じバランス (スコア) で生成される場合、Cluster Resource Manager は、コスト (移動の合計数) が小さいほうを優先します。

この戦略は効果的に機能します。 ただし、既定の負荷や静的な負荷の場合と同様に、すべての移動が等しい複雑なシステムではそうはいきません。 一部のコストがはるかに高くなる可能性があります。

移動コストの設定

サービスの作成時に、サービスの既定の移動コストを指定できます。

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

サービスの作成後に、サービスの MoveCost を動的に指定するか更新することもできます。

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

レプリカごとの動的な移動コストの指定

上記のすべてのスニペットは、サービスの外部からサービス全体の MoveCost を一度に指定するためのものです。 ただし、移動コストは、特定のサービス オブジェクトの移動コストがその有効期間中に変化する場合に最も役に立ちます。 サービス自体が特定の時点でかかる移動コストを最も把握している可能性が高いため、実行時に個々の移動コストをレポートするためのサービス向けの API があります。

C#:

this.Partition.ReportMoveCost(MoveCost.Medium);

注意

セカンダリ レプリカの移動コストは、コードを使用してのみ設定できます。

パーティションの移動コストを報告する

前のセクションでは、サービス レプリカまたはインスタンス レポートの MoveCost 自体について説明しました。 他のパーティションに代わって MoveCost 値をレポートする Service Fabric API を提供しました。 しばしば、サービスレプリカまたはインスタンスが最適な MoveCost 値を特定できず、他のサービスロジックに依存しなければならない場合があります。 他のパーティションに代わってMoveCost を レポートすると共に、他のパーティションに代わって負荷をレポートすることで、外部からパーティションを完全に管理できます。 これらの API は、Cluster Resource Manager の観点から、 Sidecar パターンの必要性を排除します。

同じ API 呼び出しを使用して、別のパーティションの MoveCost 更新を報告することができます。 新しい MoveCost の値で更新する各パーティションに対して、PartitionMoveCostDescription オブジェクトを指定する必要があります。 この API では、複数の方法で MoveCost を更新できます。

  • ステートフル サービス パーティションは、プライマリ レプリカの MoveCost を更新できます。
  • ステートレスとステートフルのどちらのサービスでも、そのすべてのセカンダリ レプリカまたはインスタンスの MoveCost を更新できます。
  • ステートレスとステートフルのどちらのサービスでも、ノード上の特定のレプリカまたはインスタンスの MoveCost を更新できます。

パーティションの MoveCost の更新には、変更される有効な値が少なくとも1つ含まれている必要があります。 たとえば、プライマリ レプリカ エントリに null 値を割り当てることでプライマリ レプリカ更新プログラムをスキップし、他のエントリを MoveCost 更新中に使用して、プライマリ レプリカの MoveCost 更新をスキップすることができます。 1 回の API 呼び出しで複数のパーティションの MoveCost を更新できるため、API は対応するパーティションのリターンコードの一覧を提供します。 MoveCost 更新の要求を正常に受け入れて処理した場合、リターンコードは Success になります。 それ以外の場合、API はエラーコードを提供します。

  • PartitionNotFound - 指定されたパーティション ID が存在しません。
  • ReconfigurationPending - パーティションは現在再構成されています。
  • InvalidForStatelessServices - ステートレス サービスに属しているパーティションのプライマリ レプリカの MoveCost を変更しようとしました。
  • ReplicaDoesNotExist - 指定されたノードにセカンダリ レプリカまたはインスタンスが存在しません。
  • InvalidOperation - システムアプリケーションに属しているパーティションの MoveCost を更新しています。

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

この例では、パーティション 53df3d7f-5471-403b-b736-bde6ad584f42 の最後に報告された移動コストの更新を実行します。 プライマリ レプリカの移動コストが VeryHigh になります。 ノードNodeName0 にある特定のセカンダリ レプリカの移動コストを除き、すべてのセカンダリ レプリカの移動コストが 0 になります。 特定のレプリカの移動コストは Medium になります。 プライマリ レプリカまたはすべてのセカンダリ レプリカの移動コストの更新をスキップする場合は、対応するエントリを null のままにします。

移動コストの影響

MoveCost には 5 つのレベルがあります。Zero、Low、Medium、High、VeryHigh です。 次の規則が適用されます。

  • Zero と VeryHigh を除き、MoveCost は互いに相対的です。
  • 移動コストが Zero の場合、移動にコストはかからず、ソリューションのスコアに対してカウントされません。
  • 移動コストを High または VeryHigh に設定しても、レプリカが移動されることは "決してない" という保証は提供され "ません"。
  • VeryHigh 移動コストでのレプリカは、他の方法では解決できないクラスター内での制約違反があった場合にのみ、(違反の解決のために他の多くのレプリカを移動する必要があったとしても) 移動されます。

移動するレプリカを選択する際の要因としての移動コスト

移動コストは、同等のバランスを最も簡単に維持したまま全体的な中断が最小限になるソリューションを見つけるのに役立ちます。 サービスのコストの概念はさまざまなものに関係する可能性があります。 最も一般的なものは次のとおりです。

  • サービスが移動する必要のある状態またはデータの量。
  • クライアント切断のコスト。 通常、プライマリ レプリカの移動は、セカンダリ レプリカの移動よりもコストが高くなります。
  • 実行中の操作を中断するコスト。 一部のデータ ストア レベル操作またはクライアント コールの応答で実行される操作にはコストがかかります。 特定の時点以降では、必要でなければ処理を中止しない方が適切です。 操作の実行中に移動コストを高くすると、そのサービス オブジェクトが移動される可能性は低くなります。 操作が完了したら、コストを通常の設定に戻します。

重要

VeryHigh 移動コストの使用は、クラスター内でグローバルに最適化された配置ソリューションを検出する Cluster Resource Manager の機能が大幅に制限されることから、慎重に検討する必要があります。 VeryHigh 移動コストでのレプリカは、他の方法では解決できないクラスター内での制約違反があった場合にのみ、(違反の解決のために他の多くのレプリカを移動する必要があったとしても) 移動されます。

クラスターでの移動コストの有効化

細かい MoveCosts を考慮するためには、MoveCost をクラスターで有効にする必要があります。 この設定がない場合は、移動をカウントする既定のモードを使用して MoveCost が計算され、MoveCost レポートは無視されます。

ClusterManifest.xml:

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

スタンドアロン デプロイの ClusterConfig.json 経由または Azure でホストされたクラスターの Template.json 経由:

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

次のステップ