Dimensionamento no Service Fabric

O Azure Service Fabric facilita a criação de aplicações dimensionáveis ao gerir os serviços, partições e réplicas nos nós de um cluster. A execução de muitas cargas de trabalho no mesmo hardware permite a utilização máxima de recursos, mas também proporciona flexibilidade em termos de como opta por dimensionar as cargas de trabalho. Este vídeo do Channel 9 descreve como pode criar aplicações de microsserviços dimensionáveis:

O dimensionamento no Service Fabric é realizado de várias formas diferentes:

  1. Dimensionar ao criar ou remover instâncias de serviço sem estado
  2. Dimensionar ao criar ou remover novos serviços nomeados
  3. Dimensionar ao criar ou remover novas instâncias de aplicações nomeadas
  4. Dimensionar com serviços particionados
  5. Dimensionar ao adicionar e remover nós do cluster
  6. Dimensionar com as métricas do Cluster Resource Manager

Dimensionar ao criar ou remover instâncias de serviço sem estado

Uma das formas mais simples de dimensionar no Service Fabric funciona com serviços sem estado. Quando cria um serviço sem estado, tem a oportunidade de definir um InstanceCount. InstanceCount define quantas cópias em execução do código desse serviço são criadas quando o serviço é iniciado. Digamos, por exemplo, que existem 100 nós no cluster. Digamos também que um serviço é criado com um InstanceCount de 10. Durante o tempo de execução, essas 10 cópias em execução do código podem ficar demasiado ocupadas (ou não podem estar suficientemente ocupadas). Uma forma de dimensionar essa carga de trabalho é alterar o número de instâncias. Por exemplo, alguma parte do código de monitorização ou gestão pode alterar o número existente de instâncias para 50 ou para 5, dependendo se a carga de trabalho precisa de aumentar ou reduzir horizontalmente com base na carga.

C#:

StatelessServiceUpdateDescription updateDescription = new StatelessServiceUpdateDescription(); 
updateDescription.InstanceCount = 50;
await fabricClient.ServiceManager.UpdateServiceAsync(new Uri("fabric:/app/service"), updateDescription);

PowerShell:

Update-ServiceFabricService -Stateless -ServiceName $serviceName -InstanceCount 50

Utilizar a Contagem de Instâncias Dinâmicas

Especificamente para serviços sem estado, o Service Fabric oferece uma forma automática de alterar a contagem de instâncias. Isto permite que o serviço dimensione dinamicamente com o número de nós disponíveis. A forma de optar por este comportamento é definir a contagem de instâncias = -1. InstanceCount = -1 é uma instrução para o Service Fabric que diz "Executar este serviço sem estado em cada nó". Se o número de nós for alterado, o Service Fabric altera automaticamente a contagem de instâncias para corresponder, garantindo que o serviço está em execução em todos os nós válidos.

C#:

StatelessServiceDescription serviceDescription = new StatelessServiceDescription();
//Set other service properties necessary for creation....
serviceDescription.InstanceCount = -1;
await fc.ServiceManager.CreateServiceAsync(serviceDescription);

PowerShell:

New-ServiceFabricService -ApplicationName $applicationName -ServiceName $serviceName -ServiceTypeName $serviceTypeName -Stateless -PartitionSchemeSingleton -InstanceCount "-1"

Dimensionar ao criar ou remover novos serviços nomeados

Uma instância de serviço nomeada é uma instância específica de um tipo de serviço (veja Ciclo de vida da aplicação do Service Fabric) dentro de alguma instância de aplicação nomeada no cluster.

As novas instâncias de serviço nomeadas podem ser criadas (ou removidas) à medida que os serviços ficam mais ou menos ocupados. Isto permite que os pedidos sejam distribuídos por mais instâncias de serviço, o que normalmente permite que a carga nos serviços existentes diminua. Ao criar serviços, o Cluster do Service Fabric Resource Manager coloca os serviços no cluster de forma distribuída. As decisões exatas são regidas pelas métricas no cluster e outras regras de colocação. Os serviços podem ser criados de várias formas diferentes, mas as mais comuns são através de ações administrativas, como alguém que chama New-ServiceFabricServiceou através de chamadas CreateServiceAsyncde código . CreateServiceAsync até pode ser chamado a partir de outros serviços em execução no cluster.

A criação de serviços dinamicamente pode ser utilizada em todos os tipos de cenários e é um padrão comum. Por exemplo, considere um serviço com estado que representa um fluxo de trabalho específico. As chamadas que representam trabalho serão apresentadas neste serviço e este serviço irá executar os passos para esse fluxo de trabalho e registar o progresso.

Como faria este dimensionamento de serviços específico? O serviço pode ser multi-inquilino de alguma forma e aceitar chamadas e iniciar passos para muitas instâncias diferentes do mesmo fluxo de trabalho de uma só vez. No entanto, isso pode tornar o código mais complexo, uma vez que agora tem de se preocupar com muitas instâncias diferentes do mesmo fluxo de trabalho, todas em diferentes fases e de diferentes clientes. Além disso, o processamento de vários fluxos de trabalho ao mesmo tempo não resolve o problema de dimensionamento. Isto deve-se ao facto de, em algum momento, este serviço consumir demasiados recursos para caber num computador específico. Muitos serviços não criados para este padrão também se deparam com dificuldades devido a algum estrangulamento ou abrandamento inerente ao código. Estes tipos de problemas fazem com que o serviço não funcione tão bem quando o número de fluxos de trabalho simultâneos que está a controlar aumenta.

Uma solução é criar uma instância deste serviço para cada instância diferente do fluxo de trabalho que pretende controlar. Este é um ótimo padrão e funciona quer o serviço seja sem estado ou com monitorização de estado. Para que este padrão funcione, normalmente existe outro serviço que funciona como um "Serviço do Gestor de Cargas de Trabalho". A tarefa deste serviço é receber pedidos e encaminhar esses pedidos para outros serviços. O gestor pode criar dinamicamente uma instância do serviço de carga de trabalho quando recebe a mensagem e, em seguida, transmitir pedidos a esses serviços. O serviço de gestor também pode receber chamadas de retorno quando um determinado serviço de fluxo de trabalho concluir a tarefa. Quando o gestor recebe estas chamadas de retorno, pode eliminar essa instância do serviço de fluxo de trabalho ou deixá-la se forem esperadas mais chamadas.

As versões avançadas deste tipo de gestor podem até criar conjuntos dos serviços que gere. O conjunto ajuda a garantir que, quando um novo pedido é recebido, não tem de esperar que o serviço aumente. Em vez disso, o gestor pode simplesmente escolher um serviço de fluxo de trabalho que não esteja atualmente ocupado a partir do conjunto ou encaminhar aleatoriamente. Manter um conjunto de serviços disponíveis torna o processamento de novos pedidos mais rápido, uma vez que é menos provável que o pedido tenha de esperar que um novo serviço seja acelerado. A criação de novos serviços é rápida, mas não gratuita ou instantânea. O conjunto ajuda a minimizar a quantidade de tempo que o pedido tem de aguardar antes de ser reparado. Muitas vezes, verá este padrão de agrupamento e gestor quando os tempos de resposta forem mais importantes. Colocar o pedido em fila e criar o serviço em segundo plano e , em seguida , transmiti-lo também é um padrão de gestor popular, tal como está a criar e eliminar serviços com base em algum controlo da quantidade de trabalho que esse serviço tem atualmente pendente.

Dimensionar ao criar ou remover novas instâncias de aplicações nomeadas

Criar e eliminar instâncias de aplicações inteiras é semelhante ao padrão de criação e eliminação de serviços. Para este padrão, existe um serviço de gestor que está a tomar a decisão com base nos pedidos que está a ver e nas informações que está a receber dos outros serviços dentro do cluster.

Quando deve ser utilizada a criação de uma nova instância de aplicação nomeada em vez de criar uma nova instância de serviço nomeada em algumas aplicações já existentes? Existem alguns casos:

  • A nova instância da aplicação destina-se a um cliente cujo código tem de ser executado em algumas definições de identidade ou segurança específicas.
    • O Service Fabric permite definir diferentes pacotes de código para serem executados em identidades específicas. Para iniciar o mesmo pacote de código em identidades diferentes, as ativações têm de ocorrer em instâncias de aplicação diferentes. Considere um caso em que tem as cargas de trabalho de um cliente existente implementadas. Estes podem estar em execução numa determinada identidade para que possa monitorizar e controlar o acesso a outros recursos, como bases de dados remotas ou outros sistemas. Neste caso, quando um novo cliente se inscreve, provavelmente não quer ativar o código no mesmo contexto (espaço de processo). Apesar de poder fazê-lo, isto torna mais difícil para o seu código de serviço agir no contexto de uma determinada identidade. Normalmente, tem de ter mais segurança, isolamento e código de gestão de identidades. Em vez de utilizar diferentes instâncias de serviço nomeadas na mesma instância de aplicação e, por conseguinte, o mesmo espaço de processo, pode utilizar diferentes instâncias da Aplicação do Service Fabric. Isto facilita a definição de diferentes contextos de identidade.
  • A nova instância da aplicação também serve como um meio de configuração
    • Por predefinição, todas as instâncias de serviço nomeadas de um determinado tipo de serviço numa instância de aplicação serão executadas no mesmo processo num determinado nó. Isto significa que, embora possa configurar cada instância de serviço de forma diferente, fazê-lo é complicado. Os serviços têm de ter algum token que utilizem para procurar a configuração num pacote de configuração. Normalmente, este é apenas o nome do serviço. Isto funciona bem, mas aloja a configuração aos nomes das instâncias de serviço nomeadas individuais nessa instância da aplicação. Isto pode ser confuso e difícil de gerir, uma vez que a configuração é normalmente um artefacto de tempo de conceção com valores específicos da instância da aplicação. Criar mais serviços significa sempre mais atualizações de aplicações para alterar as informações nos pacotes de configuração ou implementar novos para que os novos serviços possam procurar as suas informações específicas. Muitas vezes, é mais fácil criar uma nova instância de aplicação nomeada. Em seguida, pode utilizar os parâmetros da aplicação para definir qualquer configuração necessária para os serviços. Desta forma, todos os serviços criados nessa instância de aplicação com nome podem herdar definições de configuração específicas. Por exemplo, em vez de ter um único ficheiro de configuração com as definições e personalizações de cada cliente, como segredos ou limites de recursos por cliente, teria uma instância de aplicação diferente para cada cliente com estas definições substituídas.
  • A nova aplicação funciona como um limite de atualização
    • No Service Fabric, diferentes instâncias de aplicações nomeadas servem como limites para a atualização. Uma atualização de uma instância de aplicação nomeada não afetará o código que outra instância de aplicação nomeada está a executar. As diferentes aplicações acabarão por executar versões diferentes do mesmo código nos mesmos nós. Isto pode ser um fator quando precisa de tomar uma decisão de dimensionamento porque pode escolher se o novo código deve ou não seguir as mesmas atualizações que outro serviço. Por exemplo, digamos que uma chamada chega ao serviço de gestor que é responsável por dimensionar as cargas de trabalho de um determinado cliente ao criar e eliminar serviços dinamicamente. No entanto, neste caso, a chamada destina-se a uma carga de trabalho associada a um novo cliente. A maioria dos clientes gosta de estar isolada uns dos outros não só pelos motivos de segurança e configuração listados anteriormente, mas porque proporciona mais flexibilidade em termos de execução de versões específicas do software e escolha quando são atualizados. Também pode criar uma nova instância de aplicação e criar o serviço lá simplesmente para criar partições adicionais da quantidade de serviços que qualquer atualização irá tocar. As instâncias de aplicações separadas proporcionam uma maior granularidade ao efetuar atualizações de aplicações e também ativam testes A/B e implementações Blue/Green.
  • A instância da aplicação existente está cheia
    • No Service Fabric, a capacidade da aplicação é um conceito que pode utilizar para controlar a quantidade de recursos disponíveis para instâncias de aplicações específicas. Por exemplo, pode decidir que um determinado serviço precisa de ter outra instância criada para dimensionar. No entanto, esta instância de aplicação está sem capacidade para uma determinada métrica. Se este cliente ou carga de trabalho em particular continuar a receber mais recursos, poderá aumentar a capacidade existente dessa aplicação ou criar uma nova aplicação.

Dimensionamento ao nível da partição

O Service Fabric suporta a criação de partições. A criação de partições divide um serviço em várias secções lógicas e físicas, cada uma das quais funciona de forma independente. Isto é útil com serviços com estado, uma vez que nenhum conjunto de réplicas tem de processar todas as chamadas e manipular todo o estado de uma só vez. A descrição geral da criação de partições fornece informações sobre os tipos de esquemas de criação de partições suportados. As réplicas de cada partição são distribuídas pelos nós num cluster, distribuindo a carga desse serviço e garantindo que nem o serviço como um todo nem qualquer partição tem um único ponto de falha.

Considere um serviço que utiliza um esquema de criação de partições num intervalo com uma chave baixa de 0, uma chave alta de 99 e uma contagem de partições de 4. Num cluster de três nós, o serviço pode ser definido com quatro réplicas que partilham os recursos em cada nó, conforme mostrado aqui:

Esquema de partição com três nós

Se aumentar o número de nós, o Service Fabric irá mover algumas das réplicas existentes para lá. Por exemplo, digamos que o número de nós aumenta para quatro e as réplicas são redistribuídas. Agora, o serviço tem três réplicas em execução em cada nó, cada uma pertencente a diferentes partições. Isto permite uma melhor utilização de recursos, uma vez que o novo nó não está frio. Normalmente, também melhora o desempenho, uma vez que cada serviço tem mais recursos disponíveis.

Esquema de partição com quatro nós

Dimensionar com as Resource Manager e as métricas do Cluster do Service Fabric

As métricas são a forma como os serviços expressam o seu consumo de recursos para o Service Fabric. A utilização de métricas dá ao Cluster Resource Manager uma oportunidade para reorganizar e otimizar o esquema do cluster. Por exemplo, pode haver muitos recursos no cluster, mas podem não ser alocados aos serviços que estão atualmente a funcionar. A utilização de métricas permite ao Cluster Resource Manager reorganizar o cluster para garantir que os serviços têm acesso aos recursos disponíveis.

Dimensionar ao adicionar e remover nós do cluster

Outra opção para dimensionar com o Service Fabric é alterar o tamanho do cluster. Alterar o tamanho do cluster significa adicionar ou remover nós para um ou mais tipos de nós no cluster. Por exemplo, considere um caso em que todos os nós no cluster estão frequentes. Isto significa que os recursos do cluster são quase todos consumidos. Neste caso, adicionar mais nós ao cluster é a melhor forma de dimensionar. Assim que os novos nós se associarem ao cluster, o Cluster do Service Fabric Resource Manager move os serviços para os mesmos, o que resulta numa menor carga total nos nós existentes. Para serviços sem estado com contagem de instâncias = -1, são criadas automaticamente mais instâncias de serviço. Isto permite que algumas chamadas passem dos nós existentes para os novos nós.

Para obter mais informações, veja Dimensionamento de clusters.

Escolher uma plataforma

Devido às diferenças de implementação entre sistemas operativos, optar por utilizar o Service Fabric com Windows ou Linux pode ser uma parte vital do dimensionamento da sua aplicação. Uma barreira potencial é a forma como o registo faseado é executado. O Service Fabric no Windows utiliza um controlador kernel para um registo de um computador, partilhado entre réplicas de serviço com estado. Este registo pesa cerca de 8 GB. Por outro lado, o Linux utiliza um registo de teste de 256 MB para cada réplica, tornando-o menos ideal para aplicações que pretendem maximizar o número de réplicas de serviço leves em execução num determinado nó. Estas diferenças nos requisitos de armazenamento temporário podem potencialmente informar a plataforma pretendida para a implementação do cluster do Service Fabric.

Juntar tudo

Vamos levar todas as ideias que discutimos aqui e falar através de um exemplo. Considere o seguinte serviço: está a tentar criar um serviço que funciona como um livro de endereços, mantendo os nomes e as informações de contacto.

À frente, tem várias perguntas relacionadas com o dimensionamento: Quantos utilizadores vai ter? Quantos contactos cada utilizador irá armazenar? Tentar perceber tudo isto quando está a defender o seu serviço pela primeira vez é difícil. Digamos que ia utilizar um único serviço estático com uma contagem de partições específica. As consequências de escolher a contagem de partições errada podem fazer com que tenha problemas de dimensionamento mais tarde. Da mesma forma, mesmo que escolha a contagem certa, poderá não ter todas as informações de que precisa. Por exemplo, também tem de decidir o tamanho do cluster à frente, tanto em termos do número de nós como dos respetivos tamanhos. Normalmente, é difícil prever quantos recursos um serviço vai consumir ao longo da sua duração. Também pode ser difícil saber antecipadamente o padrão de tráfego que o serviço realmente vê. Por exemplo, talvez as pessoas adicionem e removam os seus contactos apenas logo pela manhã, ou talvez seja distribuído uniformemente ao longo do dia. Com base nisto, poderá ter de aumentar horizontalmente e de forma dinâmica. Talvez possa aprender a prever quando vai precisar de aumentar horizontalmente e entrar, mas de qualquer forma provavelmente terá de reagir à alteração do consumo de recursos pelo seu serviço. Isto pode implicar alterar o tamanho do cluster para fornecer mais recursos quando a reorganização da utilização de recursos existentes não é suficiente.

Mas por que motivo tentar escolher um único esquema de partição para todos os utilizadores? Porquê limitar-se a um serviço e a um cluster estático? Normalmente, a situação real é mais dinâmica.

Ao criar para dimensionamento, considere o seguinte padrão dinâmico. Poderá ter de adaptá-la à sua situação:

  1. Em vez de tentar escolher um esquema de criação de partições para todos antecipadamente, crie um "serviço de gestor".
  2. A tarefa do serviço de gestor é analisar as informações dos clientes quando se inscrevem no seu serviço. Em seguida, dependendo dessas informações, o serviço de gestor cria uma instância do seu serviço de armazenamento de contactos realapenas para esse cliente. Se precisarem de configuração, isolamento ou atualizações específicas, também pode decidir criar uma Instância de aplicação para este cliente.

Este padrão de criação dinâmica tem muitas vantagens:

  • Não está a tentar adivinhar a contagem de partições correta para todos os utilizadores antecipadamente ou criar um único serviço que seja infinitamente dimensionável por si só.
  • Os utilizadores diferentes não têm de ter a mesma contagem de partições, contagem de réplicas, restrições de colocação, métricas, cargas predefinidas, nomes de serviço, definições de dns ou qualquer outra propriedade especificada ao nível do serviço ou da aplicação.
  • Ganha segmentação de dados adicional. Cada cliente tem a sua própria cópia do serviço
    • Cada suporte ao cliente pode ser configurado de forma diferente e receber mais ou menos recursos, com mais ou menos partições ou réplicas, conforme necessário, com base na escala esperada.
      • Por exemplo, digamos que o cliente pagou o escalão "Gold" - pode obter mais réplicas ou maior contagem de partições e recursos potencialmente dedicados aos seus serviços através de métricas e capacidades de aplicações.
      • Ou dizem que forneceram informações que indicam que o número de contactos de que precisavam era "Pequeno" - obteriam apenas algumas partições ou poderiam mesmo ser colocados num conjunto de serviços partilhado com outros clientes.
  • Não está a executar várias instâncias ou réplicas de serviço enquanto espera que os clientes apareçam
  • Se um cliente sair, remover as informações do seu serviço é tão simples como fazer com que o gestor elimine esse serviço ou aplicação que criou.

Passos seguintes

Para obter mais informações sobre os conceitos do Service Fabric, veja os seguintes artigos: