Custo de movimento do serviço

Um fator que o Cluster do Service Fabric Resource Manager considera ao tentar determinar que alterações fazer a um cluster é o custo dessas alterações. A noção de "custo" é trocada em relação à quantidade de cluster que pode ser melhorada. O custo é contabilizado ao mover serviços para balanceamento, desfragmentação e outros requisitos. O objetivo é cumprir os requisitos da forma menos disruptiva ou dispendiosa.

Mover serviços custa, no mínimo, o tempo da CPU e a largura de banda de rede. Para serviços com monitorizaçã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 Cluster do Azure Service Fabric Resource Manager cria ajuda a garantir que os recursos do cluster não são gastos desnecessariamente. No entanto, também não quer ignorar soluções que melhorariam significativamente a alocação de recursos no cluster.

O cluster Resource Manager tem duas formas de calcular os custos e limitá-los enquanto tenta gerir o cluster. O primeiro mecanismo é simplesmente contar cada movimento que faria. Se forem geradas duas soluções com o mesmo saldo (pontuação), o Cluster Resource Manager prefere aquela com o custo mais baixo (número total de movimentações).

Esta estratégia funciona bem. No entanto, tal como acontece com as cargas predefinidas ou estáticas, é pouco provável que em qualquer sistema complexo todos os movimentos sejam iguais. Alguns são susceptíveis de ser muito mais caros.

Definir Custos de Movimentação

Pode especificar o custo de movimentação predefinido de um serviço quando este é 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);

Também pode especificar ou atualizar o MoveCost dinamicamente para um serviço depois de o serviço ter sido criado:

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

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

Os fragmentos anteriores destinam-se a especificar MoveCost para um serviço inteiro de uma só vez a partir 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 da sua vida útil. Uma vez que os próprios serviços provavelmente têm a melhor ideia de quão dispendiosos são para mover um determinado tempo, há uma API para os serviços reportarem o seu próprio custo de movimentação individual durante o runtime.

C#:

this.Partition.ReportMoveCost(MoveCost.Medium);

Nota

Só pode definir o custo de movimento das réplicas secundárias através de código.

Custo de movimentação de relatórios de uma partição

A secção anterior descreve como as réplicas de serviço ou as instâncias reportam MoveCost. Fornecemos a API do Service Fabric para reportar valores MoveCost em nome de outras partições. Por vezes, a réplica de serviço ou instância não consegue determinar o melhor valor MoveCost por si só e tem de depender de outra lógica de serviços. Comunicar MoveCost em nome de outras partições, juntamente com a carga de relatórios em nome de outras partições, permite-lhe gerir completamente as partições de fora. Estas APIs eliminam as necessidades do padrão Sidecar, da perspetiva do cluster Resource Manager.

Pode reportar atualizações moveCost para uma partição diferente com a mesma chamada à API. Tem de especificar o objeto PartitionMoveCostDescription para cada partição que pretende atualizar com novos valores de MoveCost. A API permite várias formas de atualizar MoveCost:

  • Uma partição de serviço com monitorização de estado pode atualizar a respetiva réplica primária MoveCost.
  • Os serviços sem estado e com monitorização de estado podem atualizar a MoveCost de todas as réplicas ou instâncias secundárias.
  • Os serviços sem estado e com monitorização de estado podem atualizar o MoveCost de uma réplica ou instância específica num nó.

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

  • PartitionNotFound - O ID de partição especificado não existe.
  • Reconfiguração Pendente – a partição está atualmente a ser reconfigurada.
  • 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 num nó especificado.
  • InvalidOperation - A atualizar MoveCost para uma partição que pertence à aplicação do Sistema.

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, irá efetuar uma atualização do último custo de movimentação comunicado para uma partição 53df3d7f-5471-403b-b736-bde6ad584f42. O custo de movimentação da réplica primária será Muito Elevado. Todos os custos de movimentação de réplicas secundárias serão Zero, exceto o custo de movimentação de 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 a atualização do custo de movimentação da réplica primária ou de todas as réplicas secundárias, pode deixar a entrada correspondente como nula.

Impacto do custo de movimentação

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

  • MoveCosts são relativos uns aos outros, exceto Zero e VeryHigh.
  • O custo de movimentação zero significa que a movimentação é livre e não deve contar com a classificação da solução.
  • Definir o custo de movimentação para Alto ou Muito Próximo não garante que a réplica nunca será movida.
  • As réplicas com o custo de movimentação VeryHigh só serão movidas se existir uma violação de restrição no cluster que não possa ser corrigida de outra forma (mesmo que seja necessário mover muitas outras réplicas para corrigir a violação)

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

A MoveCost ajuda-o a encontrar as soluções que causam menos interrupções em geral e são mais fáceis de alcançar ao chegar ao 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 movimentação são:

  • A quantidade de estado ou dados que o serviço tem de mover.
  • O custo da desconexão dos clientes. Mover uma réplica primária é normalmente mais dispendioso do que o custo de mover uma réplica secundária.
  • O custo de interromper uma operação a bordo. Algumas operações ao nível do arquivo de dados ou operações realizadas em resposta a uma chamada de cliente são dispendiosas. Depois de um determinado ponto, não quer detê-los se não tiver de o fazer. Por isso, enquanto a operação está em curso, aumenta o custo de movimentação deste objeto de serviço para reduzir a probabilidade de se mover. Quando a operação estiver concluída, deve voltar a definir o custo como normal.

Importante

A utilização do custo de movimentação VeryHigh deve ser cuidadosamente considerada, uma vez que restringe significativamente a capacidade do Cluster Resource Manager de encontrar uma solução de colocação globalmente ideal no cluster. As réplicas com o custo de movimentação VeryHigh só serão movidas se existir uma violação de restrição no cluster que não possa ser corrigida de outra forma (mesmo que seja necessário mover muitas outras réplicas para corrigir a violação)

Ativar o custo de movimentação no cluster

Para que os MoveCosts mais granulares sejam tidos em conta, a MoveCost tem de estar ativada no cluster. Sem esta definição, o modo predefinido de contagem de movimentos é utilizado para calcular MoveCost e os relatórios MoveCost são ignorados.

ClusterManifest.xml:

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

através de ClusterConfig.json para implementações autónomas ou Template.json para clusters alojados no Azure:

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

Passos seguintes