Partilhar via


Custo de movimento do serviço

Um fator que o Gerenciador de Recursos de Cluster do Service Fabric considera ao tentar determinar quais alterações fazer em um cluster é o custo dessas alterações. A noção de "custo" é trocada pelo quanto o cluster pode ser melhorado. O custo é levado em conta ao mover serviços para balanceamento, desfragmentação e outros requisitos. O objetivo é atender aos requisitos da forma menos disruptiva ou dispendiosa.

A mudança de serviços custa tempo de CPU e largura de banda de rede no mínimo. Para serviços com monitoração de estado, é necessário copiar o estado desses serviços, consumindo memória e disco adicionais. Minimizar o custo das soluções que o Gerenciador de Recursos de Cluster do Azure Service Fabric apresenta ajuda a garantir que os recursos do cluster não sejam gastos desnecessariamente. No entanto, você também não quer ignorar soluções que melhorariam significativamente a alocação de recursos no cluster.

O Cluster Resource Manager tem duas maneiras de calcular os custos e limitá-los enquanto tenta gerenciar o cluster. O primeiro mecanismo é simplesmente contar cada movimento que ele faria. Se duas soluções forem geradas com aproximadamente o mesmo saldo (pontuação), o Gerenciador de Recursos de Cluster prefere aquela com o menor custo (número total de movimentos).

Esta estratégia funciona bem. Mas, como acontece com cargas padrão ou estáticas, é improvável em qualquer sistema complexo que todos os movimentos sejam iguais. É provável que alguns sejam muito mais caros.

Definindo custos de movimentação

Você pode especificar o custo de movimentação padrão para um serviço quando ele é criado:

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

Você também pode especificar ou atualizar o MoveCost dinamicamente para um serviço após a criação do serviço:

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

Especificando dinamicamente o custo de movimentação por réplica

Os trechos anteriores são todos para especificar MoveCost para um serviço inteiro de uma só vez de fora do próprio serviço. No entanto, o custo de movimentação é mais útil quando o custo de movimentação de um objeto de serviço específico muda ao longo de sua vida útil. Como os próprios serviços provavelmente têm a melhor ideia de quão caro eles são para mover um determinado tempo, há uma API para que os serviços relatem seu próprio custo de movimentação individual durante o tempo de execução.

C#:

this.Partition.ReportMoveCost(MoveCost.Medium);

Nota

Você só pode definir o custo de movimento para réplicas secundárias por meio de código.

Relatar o custo de movimentação de uma partição

A seção anterior descreve como réplicas de serviço ou instâncias relatam o próprio MoveCost. Fornecemos a API do Service Fabric para relatar valores MoveCost em nome de outras partições. Às vezes, a réplica ou instância de serviço não pode determinar o melhor valor MoveCost por si só e deve depender de outra lógica de serviços. Relatar MoveCost em nome de outras partições, juntamente com relatar carga em nome de outras partições, permite que você gerencie completamente partições de fora. Essas APIs eliminam a necessidade do padrão Sidecar, da perspetiva do Cluster Resource Manager.

Você pode relatar atualizações do MoveCost para uma partição diferente com a mesma chamada de API. Você precisa especificar o objeto PartitionMoveCostDescription para cada partição que deseja atualizar com novos valores de MoveCost. A API permite várias maneiras de atualizar o MoveCost:

  • Uma partição de serviço com monitoração de estado pode atualizar sua réplica principal MoveCost.
  • Os serviços stateless e stateful podem atualizar o MoveCost de todas as suas réplicas ou instâncias secundárias.
  • Os serviços stateless e stateful podem atualizar o MoveCost de uma réplica ou instância específica em um nó.

Cada atualização MoveCost para partição deve conter pelo menos um valor válido que será alterado. Por exemplo, você pode ignorar a atualização da réplica primária atribuindo null à entrada da réplica primária, outras entradas serão usadas durante a atualização do MoveCost e ignoraremos a atualização do MoveCost para a réplica primária. Como a atualização do MoveCost para várias partições com uma única chamada de API é possível, a API fornece uma lista de códigos de retorno para a partição correspondente. Se aceitarmos e processarmos com sucesso um pedido de atualização do MoveCost, o código de retorno será Sucesso. Caso contrário, a API fornece o código de erro:

  • PartitionNotFound - ID de partição especificada não existe.
  • ReconfigurationPending - A partição está sendo reconfigurada no momento.
  • InvalidForStatelessServices - Foi feita uma tentativa de alterar o MoveCost de uma réplica primária para uma partição pertencente a um serviço sem estado.
  • ReplicaDoesNotExist - A réplica ou instância secundária não existe em um nó especificado.
  • InvalidOperation - Atualizando MoveCost para uma partição que pertence ao aplicativo System.

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

Com este exemplo, você executará uma atualização do último custo de movimentação relatado para uma partição 53df3d7f-5471-403b-b736-bde6ad584f42. O custo de movimentação da réplica principal será muito alto. O custo de movimentação de todas as réplicas secundárias será Zero, exceto o custo de movimentação para uma réplica secundária específica localizada no nó NodeName0. O custo de movimentação de uma réplica específica será Médio. Se quiser ignorar o custo de movimentação de atualização para a réplica primária ou todas as réplicas secundárias, você pode deixar a entrada correspondente como nula.

Impacto do custo de mudança

O MoveCost tem cinco níveis: Zero, Baixo, Médio, Alto e Muito Alto. Aplicam-se as seguintes regras:

  • Os MoveCosts são relativos entre si, exceto Zero e VeryHigh.
  • Custo de movimento zero significa que o movimento é livre e não deve contar para a pontuação da solução.
  • Definir seu custo de mudança como Alto ou Muito Alto não fornece uma garantia de que a réplica nunca será movida.
  • As réplicas com custo de movimentação VeryHigh serão movidas somente se houver uma violação de restrição no cluster que não possa ser corrigida de outra forma (mesmo que exija mover muitas outras réplicas para corrigir a violação)

Mover o custo como um fator na seleção de réplicas para movimento

O MoveCost ajuda-o a encontrar as soluções que causam menos perturbação em geral e que são mais fáceis de alcançar enquanto ainda se chega a um equilíbrio equivalente. A noção de custo de um serviço pode ser relativa a muitas coisas. Os fatores mais comuns no cálculo do custo de mudança são:

  • A quantidade de estado ou dados que o serviço tem que mover.
  • O custo da desconexão de clientes. Mover uma réplica primária geralmente é mais caro do que o custo de mover uma réplica secundária.
  • O custo de interromper uma operação em voo. Algumas operações no nível de armazenamento de dados ou operações realizadas em resposta a uma chamada de cliente são caras. Depois de um certo ponto, você não quer pará-los se não precisar. Assim, enquanto a operação está acontecendo, você aumenta o custo de movimentação desse objeto de serviço para reduzir a probabilidade de que ele se mova. Quando a operação é concluída, você define o custo de volta ao normal.

Importante

O uso do custo de movimentação VeryHigh deve ser cuidadosamente considerado, pois restringe significativamente a capacidade do Cluster Resource Manager de encontrar uma solução de posicionamento globalmente ideal no cluster. As réplicas com custo de movimentação VeryHigh serão movidas somente se houver uma violação de restrição no cluster que não possa ser corrigida de outra forma (mesmo que exija mover muitas outras réplicas para corrigir a violação)

Habilitando o custo de movimentação em seu cluster

Para que os MoveCosts mais granulares sejam levados em consideração, o MoveCost deve ser habilitado em seu cluster. Sem essa configuração, o modo padrão de contagem de movimentos é usado para calcular MoveCost e os relatórios MoveCost são ignorados.

ClusterManifest.xml:

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

via ClusterConfig.json para implantações autônomas ou Template.json para clusters hospedados do Azure:

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

Próximos passos