Partilhar via


Grãos de trabalhador apátrida

Por padrão, o Orleans tempo de execução não cria mais de uma ativação de um grão dentro do cluster. Esta é a expressão mais intuitiva do modelo Virtual Ator com cada grão a corresponder a uma entidade com um tipo/identidade único. No entanto, também há casos em que um aplicativo precisa executar operações funcionais sem estado que não estão vinculadas a uma entidade específica no sistema. Por exemplo, se o cliente enviar solicitações com cargas compactadas que precisam ser descompactadas antes que possam ser roteadas para o grão de destino para processamento, essa lógica de descompressão/roteamento não está vinculada a uma entidade específica no aplicativo e pode ser facilmente dimensionada.

Quando o StatelessWorkerAttribute é aplicado a uma classe de grãos, indica ao tempo de execução que os Orleans grãos dessa classe devem ser tratados como grãos de trabalhadores apátridas. Os grãos de trabalhador apátrida têm as seguintes propriedades que tornam sua execução muito diferente da das classes de grãos normais.

  1. O Orleans tempo de execução pode e criará várias ativações de um grão de trabalhador sem estado em diferentes silos do cluster.
  2. As solicitações feitas a grãos de trabalhador sem estado são executadas localmente, desde que o silo seja compatível e, portanto, não incorrerão em custos de rede ou serialização. Se o silo local não for compatível, as solicitações serão encaminhadas para um silo compatível.
  3. O Orleans Runtime cria automaticamente ativações adicionais de um grão de trabalhador sem estado se as já existentes estiverem ocupadas. O número máximo de ativações de um grão de trabalhador sem estado que o tempo de execução cria por silo é limitado por padrão pelo número de núcleos de CPU na máquina, a menos que especificado explicitamente pelo argumento opcional maxLocalWorkers .
  4. Devido aos pontos 2 e 3, as ativações de grãos de trabalhadores apátridas não são endereçáveis individualmente. Duas solicitações subsequentes a um grão trabalhador apátrida podem ser processadas por diferentes ativações dele.

Os grãos de trabalhador sem estado fornecem uma maneira direta de criar um pool gerenciado automaticamente de ativações de grãos que aumenta e diminui automaticamente com base na carga real. O tempo de execução sempre verifica se há ativações de grãos de trabalhador sem estado disponíveis na mesma ordem. Por causa disso, ele sempre envia solicitações para a primeira ativação local ociosa que pode encontrar e só chega à última se todas as ativações anteriores estiverem ocupadas. Se todas as ativações estiverem ocupadas e o limite de ativação não tiver sido atingido, ele criará mais uma ativação no final da lista e enviará a solicitação para ela. Isso significa que, quando a taxa de solicitações a um trabalhador sem estado aumenta e as ativações existentes estão todas ocupadas no momento, o tempo de execução expande o pool de suas ativações até o limite. Por outro lado, quando a carga cai, e pode ser tratada por um número menor de ativações do grão trabalhador apátrida, as ativações na cauda da lista não receberão solicitações enviadas para eles. Eles ficarão ociosos e, eventualmente, desativados pelo processo de coleta de ativação padrão. Assim, o pool de ativações acabará encolhendo para corresponder à carga.

O exemplo a seguir define uma classe MyStatelessWorkerGrain de grão de trabalhador sem estado com o limite máximo de número de ativação padrão.

[StatelessWorker]
public class MyStatelessWorkerGrain : Grain, IMyStatelessWorkerGrain
{
    // ...
}

Fazer uma chamada para um grão trabalhador apátrida é o mesmo que para qualquer outro grão. A única diferença é que, na maioria dos casos, um único ID de grão é usado, por exemplo 0 ou Guid.Empty. Vários IDs de grão podem ser usados quando se tem vários pools de grãos de trabalhador sem estado, um por ID é desejável.

var worker = GrainFactory.GetGrain<IMyStatelessWorkerGrain>(0);
await worker.Process(args);

Este define uma classe de grãos de trabalhador apátrida com não mais do que uma ativação de grão por silo.

[StatelessWorker(1)] // max 1 activation per silo
public class MyLonelyWorkerGrain : ILonelyWorkerGrain
{
    //...
}

Note que StatelessWorkerAttribute não altera a reentrância da classe de grãos alvo. Assim como qualquer outro grão, os grãos de trabalhador apátrida não são reentrantes por padrão. Eles podem ser explicitamente tornados reentrantes adicionando a ReentrantAttribute à classe de grãos.

Estado

A parte "apátrida" de "trabalhador apátrida" não significa que um trabalhador apátrida não possa ter um Estado e limita-se apenas a executar operações funcionais. Como qualquer outro grão, um grão de trabalhador apátrida pode carregar e manter na memória qualquer estado que precise. É apenas porque várias ativações de um grão de trabalhador sem estado podem ser criadas nos mesmos e diferentes silos do cluster, não há um mecanismo fácil para coordenar o estado mantido por ativações diferentes.

Vários padrões úteis envolvem o estado de detenção de trabalhador apátrida.

Itens de cache a quente dimensionados

Para itens de cache ativo com alta taxa de transferência, manter cada item em um grão de trabalhador sem estado faz com que:

  1. Dimensionar automaticamente dentro de um silo e em todos os silos do cluster, e;
  2. Torna os dados sempre disponíveis localmente no silo que recebeu a solicitação do cliente por meio de seu gateway de cliente, para que as solicitações possam ser respondidas sem um salto de rede extra para outro silo.

Reduzir a agregação de estilo

Em alguns cenários, os aplicativos precisam calcular determinadas métricas em todos os grãos de um tipo específico no cluster e relatar as agregações periodicamente. Exemplos são relatar vários jogadores por mapa de jogo, a duração média de uma chamada VoIP, etc. Se cada um dos muitos milhares ou milhões de grãos reportasse suas métricas a um único agregador global, o agregador ficaria imediatamente sobrecarregado incapaz de processar a enxurrada de relatórios. A abordagem alternativa é transformar essa tarefa em uma etapa 2 (ou mais) para reduzir a agregação de estilo. A primeira camada de agregação é feita relatando grãos enviando suas métricas para um grão de pré-agregação de trabalhador sem estado. O Orleans tempo de execução criará automaticamente várias ativações do grão de trabalhador sem estado com cada silo. Como todas essas chamadas serão processadas localmente sem chamadas remotas ou serialização das mensagens, o custo dessa agregação será significativamente menor do que em um caso remoto. Agora, cada uma das ativações de grãos de trabalhador sem estado de pré-agregação, independentemente ou em coordenação com outras ativações locais, pode enviar seus relatórios agregados para o agregador final global (ou para outra camada de redução, se necessário) sem sobrecarregá-lo.