Partilhar via


Configurar e utilizar a afinidade de serviço no Service Fabric

A afinidade é um controlo fornecido principalmente para ajudar a facilitar a transição de aplicações monolíticas maiores para o mundo da cloud e dos microsserviços. Também é utilizado como uma otimização para melhorar o desempenho dos serviços, embora fazê-lo possa ter efeitos colaterais.

Digamos que está a trazer uma aplicação maior ou que simplesmente não foi concebida com microsserviços em mente, para o Service Fabric (ou qualquer ambiente distribuído). Este tipo de transição é comum. Comece por levantar toda a aplicação para o ambiente, empacotá-la e certificar-se de que está a funcionar sem problemas. Depois começas a dividi-lo em diferentes serviços mais pequenos que falam uns com os outros.

Eventualmente, poderá descobrir que a aplicação está a ter alguns problemas. Normalmente, os problemas enquadram-se numa destas categorias:

  1. Algum componente X na aplicação monolítica tinha uma dependência não documentada do componente Y e acabou de transformar esses componentes em serviços separados. Uma vez que estes serviços estão agora em execução em nós diferentes no cluster, estão avariados.
  2. Estes componentes comunicam através de (pipes com nome local | memória partilhada | ficheiros no disco) e precisam realmente de ser capazes de escrever num recurso local partilhado por motivos de desempenho neste momento. Essa dependência difícil é removida mais tarde, talvez.
  3. Está tudo bem, mas acontece que estes dois componentes são, na verdade, sensíveis ao desempenho/conversa. Quando os moveram para serviços separados, o desempenho geral da aplicação aumentou ou a latência aumentou. Como resultado, a aplicação geral não está a corresponder às expectativas.

Nestes casos, não queremos perder o nosso trabalho de refatorização e não queremos voltar ao monólito. A última condição pode até ser desejável como uma otimização simples. No entanto, até podermos redesenhar os componentes para funcionarem naturalmente como serviços (ou até podermos resolver as expectativas de desempenho de outra forma), vamos precisar de algum sentido de localidade.

O que fazer? Bem, podes tentar ativar a afinidade.

Como configurar a afinidade

Para configurar a afinidade, defina uma relação de afinidade entre dois serviços diferentes. Pode considerar a afinidade como "apontar" um serviço noutro e dizer "Este serviço só pode ser executado onde esse serviço está em execução". Por vezes, referimo-nos à afinidade como uma relação principal/subordinada (onde aponta o menor para o elemento principal). A afinidade garante que as réplicas ou instâncias de um serviço são colocadas nos mesmos nós que os de outro serviço.

ServiceCorrelationDescription affinityDescription = new ServiceCorrelationDescription();
affinityDescription.Scheme = ServiceCorrelationScheme.Affinity;
affinityDescription.ServiceName = new Uri("fabric:/otherApplication/parentService");
serviceDescription.Correlations.Add(affinityDescription);
await fabricClient.ServiceManager.CreateServiceAsync(serviceDescription);

Nota

Um serviço subordinado só pode participar numa única relação de afinidade. Se quiser que o menor seja afinizado a dois serviços principais ao mesmo tempo, tem algumas opções:

  • Inverter as relações (ter parentService1 e parentService2 no serviço subordinado atual) ou
  • Designe um dos pais como um hub por convenção e tenha todos os serviços a apontar para esse serviço.

O comportamento de colocação resultante no cluster deve ser o mesmo.

Diferentes opções de afinidade

A afinidade é representada através de um de vários esquemas de correlação e tem dois modos diferentes. O modo de afinidade mais comum é aquilo a que chamamos NonAlignedAffinity. Em NonAlignedAffinity, as réplicas ou instâncias dos diferentes serviços são colocadas nos mesmos nós. O outro modo é AlignedAffinity. A Afinidade Alinhada é útil apenas com serviços com estado. Configurar dois serviços com estado para ter afinidade alinhada garante que as primárias desses serviços são colocadas nos mesmos nós que os outros. Também faz com que cada par de secundários sejam colocados nos mesmos nós. Também é possível (embora menos comum) configurar NonAlignedAffinity para serviços com estado. Para NonAlignedAffinity, as diferentes réplicas dos dois serviços com estado seriam executadas nos mesmos nós, mas as primárias poderiam acabar em nós diferentes.

Modos de Afinidade e Respetivos Efeitos

Melhor estado pretendido

Uma relação de afinidade é o melhor esforço. Não fornece as mesmas garantias de colocação ou fiabilidade executadas no mesmo processo executável. Os serviços numa relação de afinidade são entidades fundamentalmente diferentes que podem falhar e ser movidos de forma independente. Uma relação de afinidade também pode quebrar, embora estas quebras sejam temporárias. Por exemplo, as limitações de capacidade podem significar que apenas alguns dos objetos de serviço na relação de afinidade podem caber num determinado nó. Nestes casos, apesar de existir uma relação de afinidade, não pode ser imposta devido às outras restrições. Se for possível fazê-lo, a violação será automaticamente corrigida mais tarde.

Correntes vs. estrelas

Atualmente, o Cluster Resource Manager não consegue modelar cadeias de relações de afinidade. O que isto significa é que um serviço que é uma criança numa relação de afinidade não pode ser um elemento principal noutra relação de afinidade. Se quiser modelar este tipo de relação, tem de modelá-lo como uma estrela, em vez de uma cadeia. Para passar de uma cadeia para uma estrela, a criança mais inferior seria, em vez disso, parentada para o pai do primeiro filho. Dependendo da disposição dos seus serviços, poderá ter de o fazer várias vezes. Se não existir um serviço principal natural, poderá ter de criar um que sirva de marcador de posição. Consoante os seus requisitos, também poderá querer analisar Os Grupos de Aplicações.

Cadeias vs. Estrelas no Contexto das Relações de Afinidade

Outra coisa a ter em atenção sobre as relações de afinidade atualmente é que são direcionais por predefinição. Isto significa que a regra de afinidade só impõe que o menor colocado com o elemento principal. Não garante que o elemento principal esteja localizado com o menor. Portanto, se houver uma violação de afinidade e corrigir a violação por alguma razão, não é viável mover a criança para o nó do encarregado de educação, então . Definir a configuração MoveParentToFixAffinityViolation como true removeria a direcionalidade. Também é importante ter em atenção que a relação de afinidade não pode ser perfeita ou imposta instantaneamente, uma vez que os diferentes serviços têm ciclos de vida diferentes e podem falhar e mover-se de forma independente. Por exemplo, digamos que o principal falha subitamente para outro nó porque falhou. O Cluster Resource Manager e o Gestor de Ativação Pós-falha processam primeiro a ativação pós-falha, uma vez que manter os serviços atualizados, consistentes e disponíveis é a prioridade. Assim que a ativação pós-falha for concluída, a relação de afinidade é quebrada, mas o Cluster Resource Manager considera que está tudo bem até reparar que o menor não está localizado com o elemento principal. Estes tipos de verificações são efetuadas periodicamente. Mais informações sobre como o Cluster Resource Manager avalia as restrições estão disponíveis neste artigo e este fala mais sobre como configurar a cadência em que estas restrições são avaliadas.

Suporte de criação de partições

A última coisa a notar sobre a afinidade é que as relações de afinidade não são suportadas onde o elemento principal é particionado. Os serviços principais particionados podem eventualmente ser suportados, mas atualmente não é permitido.

Passos seguintes