Partilhar via


Gestão do Estado de Atores Confiáveis

Atores confiáveis são objetos de thread único que podem encapsular lógica e estado. Como os atores são executados em Serviços Confiáveis, eles podem manter o estado de forma confiável usando os mesmos mecanismos de persistência e replicação. Dessa forma, os atores não perdem seu estado após falhas, após a reativação após a coleta de lixo ou quando são movidos entre nós em um cluster devido ao balanceamento de recursos ou atualizações.

Persistência e replicação de estado

Todos os atores confiáveis são considerados stateful porque cada instância do ator é mapeada para um ID exclusivo. Isso significa que chamadas repetidas para o mesmo ID de ator são roteadas para a mesma instância de ator. Em um sistema sem monitoração de estado, por outro lado, não é garantido que as chamadas de cliente sejam roteadas para o mesmo servidor todas as vezes. Por esta razão, os serviços de atores são sempre serviços de estado.

Mesmo que os atores sejam considerados estatais, isso não significa que eles devam armazenar o estado de forma confiável. Os atores podem escolher o nível de persistência e replicação de estado com base em seus requisitos de armazenamento de dados:

  • Estado persistente: o estado é persistido no disco e replicado para três ou mais réplicas. O estado persistente é a opção de armazenamento de estado mais durável, onde o estado pode persistir durante a interrupção completa do cluster.
  • Estado volátil: o estado é replicado para três ou mais réplicas e mantido apenas na memória. O estado volátil fornece resiliência contra falha de nó e falha de ator, e durante atualizações e balanceamento de recursos. No entanto, o estado não é persistido para o disco. Então, se todas as réplicas são perdidas de uma só vez, o estado também é perdido.
  • Nenhum estado persistente: o estado não é replicado ou gravado em disco, apenas usado para atores que não precisam manter o estado de forma confiável.

Cada nível de persistência é simplesmente um provedor de estado diferente e uma configuração de replicação do seu serviço. Se o estado é ou não gravado no disco depende do provedor de estado - o componente em um serviço confiável que armazena o estado. A replicação depende de quantas réplicas um serviço é implantado. Assim como acontece com os Serviços Confiáveis, tanto o provedor de estado quanto a contagem de réplicas podem ser facilmente definidos manualmente. A estrutura ator fornece um atributo que, quando usado em um ator, seleciona automaticamente um fornecedor de estado predefinido e gera automaticamente definições para contagem de réplicas para atingir uma destas três definições de persistência. O atributo StatePersistence não é herdado por classe derivada, cada tipo de Ator deve fornecer seu nível StatePersistence.

Estado persistente

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl  extends FabricActor implements MyActor
{
}

Essa configuração usa um provedor de estado que armazena dados no disco e define automaticamente a contagem de réplicas de serviço como 3.

Estado volátil

[StatePersistence(StatePersistence.Volatile)]
class MyActor : Actor, IMyActor
{
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Volatile)
class MyActorImpl extends FabricActor implements MyActor
{
}

Essa configuração usa um provedor de estado somente na memória e define a contagem de réplicas como 3.

Nenhum estado persistente

[StatePersistence(StatePersistence.None)]
class MyActor : Actor, IMyActor
{
}
@StatePersistenceAttribute(statePersistence = StatePersistence.None)
class MyActorImpl extends FabricActor implements MyActor
{
}

Essa configuração usa um provedor de estado somente na memória e define a contagem de réplicas como 1.

Padrões e configurações geradas

Quando você estiver usando o StatePersistence atributo, um provedor de estado será selecionado automaticamente para você em tempo de execução quando o serviço de ator for iniciado. A contagem de réplicas, no entanto, é definida em tempo de compilação pelas ferramentas de compilação do ator do Visual Studio. As ferramentas de compilação geram automaticamente um serviço padrão para o serviço de ator no ApplicationManifest.xml. Os parâmetros são criados para o tamanho mínimo do conjunto de réplicas e o tamanho do conjunto de réplicas de destino.

Você pode alterar esses parâmetros manualmente. Mas cada vez que o StatePersistence atributo é alterado, os parâmetros são definidos para os valores de tamanho do conjunto de réplica padrão para o atributo selecionado StatePersistence , substituindo quaisquer valores anteriores. Em outras palavras, os valores definidos em ServiceManifest.xml só são substituídos no momento da compilação quando você altera o valor do StatePersistence atributo.

<ApplicationManifest xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="Application12Type" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
   <Parameters>
      <Parameter Name="MyActorService_PartitionCount" DefaultValue="10" />
      <Parameter Name="MyActorService_MinReplicaSetSize" DefaultValue="3" />
      <Parameter Name="MyActorService_TargetReplicaSetSize" DefaultValue="3" />
   </Parameters>
   <ServiceManifestImport>
      <ServiceManifestRef ServiceManifestName="MyActorPkg" ServiceManifestVersion="1.0.0" />
   </ServiceManifestImport>
   <DefaultServices>
      <Service Name="MyActorService" GeneratedIdRef="77d965dc-85fb-488c-bd06-c6c1fe29d593|Persisted">
         <StatefulService ServiceTypeName="MyActorServiceType" TargetReplicaSetSize="[MyActorService_TargetReplicaSetSize]" MinReplicaSetSize="[MyActorService_MinReplicaSetSize]">
            <UniformInt64Partition PartitionCount="[MyActorService_PartitionCount]" LowKey="-9223372036854775808" HighKey="9223372036854775807" />
         </StatefulService>
      </Service>
   </DefaultServices>
</ApplicationManifest>

Gestor do Estado

Cada instância de ator tem seu próprio gerenciador de estado: uma estrutura de dados semelhante a um dicionário que armazena de forma confiável pares chave/valor. O gestor estadual é um invólucro em torno de um provedor estatal. Você pode usá-lo para armazenar dados, independentemente de qual configuração de persistência é usada. Ele não fornece nenhuma garantia de que um serviço de ator em execução possa ser alterado de uma configuração de estado volátil (somente na memória) para uma configuração de estado persistente por meio de uma atualização contínua, preservando os dados. No entanto, é possível alterar a contagem de réplicas para um serviço em execução.

As chaves do gerenciador de estado devem ser strings. Os valores são genéricos e podem ser de qualquer tipo, incluindo tipos personalizados. Os valores armazenados no gerenciador de estado devem ser serializáveis por contrato de dados porque podem ser transmitidos pela rede para outros nós durante a replicação e podem ser gravados no disco, dependendo da configuração de persistência de estado de um ator.

O gestor de estado expõe métodos de dicionário comuns para gerir o estado, semelhantes aos encontrados no Reliable Dictionary.

Para obter exemplos de gerenciamento do estado do ator, leia Acesso, salvar e remover o estado Atores confiáveis.

Melhores práticas

Aqui estão algumas práticas sugeridas e dicas de solução de problemas para gerenciar o estado do ator.

Tornar o estado do ator o mais granular possível

Isso é fundamental para o desempenho e o uso de recursos do seu aplicativo. Sempre que há qualquer gravação/atualização para o "estado nomeado" de um ator, todo o valor correspondente a esse "estado nomeado" é serializado e enviado pela rede para as réplicas secundárias. Os secundários gravam-no no disco local e respondem à réplica primária. Quando o primário recebe confirmações de um quórum de réplicas secundárias, ele grava o estado em seu disco local. Por exemplo, suponha que o valor é uma classe que tem 20 membros e um tamanho de 1 MB. Mesmo se você modificou apenas um dos membros da classe que é de tamanho 1 KB, você acaba pagando o custo de serialização e rede e disco grava para o 1 MB completo. Da mesma forma, se o valor for uma coleção (como uma lista, matriz ou dicionário), você pagará o custo da coleção completa, mesmo que modifique um de seus membros. A interface StateManager da classe ator é como um dicionário. Você deve sempre modelar a estrutura de dados que representa o estado do ator em cima deste dicionário.

Gerir corretamente o ciclo de vida do ator

Você deve ter uma política clara sobre como gerenciar o tamanho do estado em cada partição de um serviço de ator. Seu serviço de atores deve ter um número fixo de atores e reutilizá-los tanto quanto possível. Se você criar continuamente novos atores, você deve excluí-los assim que terminarem seu trabalho. A estrutura do ator armazena alguns metadados sobre cada ator que existe. A exclusão de todo o estado de um ator não remove metadados sobre esse ator. Você deve excluir o ator (consulte excluindo atores e seu estado) para remover todas as informações sobre ele armazenadas no sistema. Como uma verificação extra, você deve consultar o serviço de ator (consulte enumerando atores) de vez em quando para se certificar de que o número de atores está dentro do intervalo esperado.

Se você vir que o tamanho do arquivo de banco de dados de um Ator Service está aumentando além do tamanho esperado, certifique-se de que está seguindo as diretrizes anteriores. Se você estiver seguindo essas diretrizes e ainda estiver enfrentando problemas de tamanho de arquivo de banco de dados, abra um tíquete de suporte com a equipe do produto para obter ajuda.

Próximos passos

O estado armazenado em Reliable Actors deve ser serializado antes de ser gravado em disco e replicado para alta disponibilidade. Saiba mais sobre a serialização do tipo Ator.

Em seguida, saiba mais sobre o diagnóstico do ator e o monitoramento de desempenho.