Diretrizes e recomendações para Coleções Confiáveis no Azure Service Fabric
Esta seção fornece diretrizes para usar o Gerenciador de Estado Confiável e Coleções Confiáveis. A meta é ajudar os usuários a evitar armadilhas comuns.
Diretrizes de coleta confiável
As diretrizes são organizadas como recomendações simples prefixadas com uma ação a ser realizada e os termos Considere, Evite e Não.
- Não modifique um objeto de tipo personalizado retornado por operações de leitura (por exemplo,
TryPeekAsync
ouTryGetValueAsync
). As Coleções Confiáveis, como as Coleções Simultâneas, retornam uma referência aos objetos e não uma cópia. - Faça uma cópia em profundidade do objeto de tipo personalizado retornado antes de modificá-lo. Como estruturas e tipos internos são passagem-por-valor, você não precisa fazer uma cópia em profundidade deles, a menos que eles contenham campos de tipo de referência ou propriedades que você pretende modificar.
- Não use
TimeSpan.MaxValue
para tempos limites. Tempos limite devem ser usados para detectar deadlocks. - Não use uma transação depois que ela tiver sido confirmada, anulada ou descartada.
- Não use uma enumeração fora do escopo da transação que em foi criado.
- Não crie uma transação dentro da instrução
using
de outra transação porque isso pode causar deadlocks. - Não crie um estado confiável com
IReliableStateManager.GetOrAddAsync
e use o estado confiável na mesma transação. Isso resultará em uma InvalidOperationException. - Certifique-se de que a implementação de
IComparable<TKey>
esteja correta. O sistema depende deIComparable<TKey>
para mesclar os pontos de verificação. - Use bloqueio de atualização durante a leitura de um item com uma intenção de atualizá-lo para impedir determinada classe de deadlocks.
- Considere manter o número de Coleções Confiáveis por partição inferior a 1000. Prefira Coleções Confiáveis com mais itens em vez de mais Coleções Confiáveis com menos itens.
- Considere manter seus itens (por exemplo, TKey + TValue para o Dicionário Confiável) abaixo de 80 KBytes: quanto menor, melhor. Isso reduz a quantidade de uso do Heap de Objetos Grandes, bem como os requisitos de disco e de E/S da rede. Muitas vezes, isso reduz a replicação de dados duplicados quando apenas uma pequena parte do valor está sendo atualizada. Uma maneira comum de fazer isso no Dicionário Confiável é dividir as linhas em várias linhas.
- Considere o uso da funcionalidade de backup e restauração para ter uma recuperação de desastre.
- Evite a mistura de operações de entidade única e operações de várias entidades (por exemplo, de
GetCountAsync
,CreateEnumerableAsync
) na mesma transação devido a níveis de isolamento diferentes. - Trate InvalidOperationException. As transações do usuário podem ser anuladas pelo sistema por diversos motivos. Por exemplo, quando o Gerenciador de Estado Confiável muda sua função Primária ou quando uma transação de longa execução bloqueia o truncamento do log transacional. Nesses casos, o usuário pode receber InvalidOperationException, indicando que a transação já foi encerrada. Supondo que o encerramento da transação não foi solicitado pelo usuário, a melhor maneira de tratar essa exceção é descartar a transação, verificar se o token de cancelamento foi sinalizado (ou se a função da réplica foi alterada) e, caso não tenha, criar uma nova transação e tentar novamente.
- Não aplique operações paralelas ou simultâneas em uma transação. Há suporte para apenas uma operação de thread de usuário em uma transação. Caso contrário, isso causará problemas de perda de memória e bloqueio.
- Considere descartar a transação assim que possível após a conclusão da confirmação (especialmente ao usar ConcurrentQueue).
- Não execute nenhum código de bloqueio dentro de uma transação.
- Quando a cadeia de caracteres é usada como a chave para um dicionário confiável, a ordem de classificação usa o comparador de cadeia de caracteres CurrentCulture padrão. Observe que a ordem de classificação CurrentCulture é diferente do comparador de cadeia de caracteres Ordinal.
- Não descarte nem cancele uma transação de confirmação. Não há suporte para isso e pode fazer com que o processo principal falhe.
- Certifique-se de que a ordem de operação de dicionários diferentes permaneça a mesma para todas as transações simultâneas ao ler ou gravar vários dicionários para evitar deadlock.
Eis aqui algumas coisas que se deve manter em mente:
- O tempo limite padrão é de 4 segundos para todas as APIs de Coleta Confiável. A maioria dos usuários deve usar o tempo limite padrão.
- O token de cancelamento padrão é
CancellationToken.None
em todas as APIs de Coleções Confiáveis. - O parâmetro de tipo de chave (TKey) para um Dicionário Confiável deve implementar corretamente
GetHashCode()
eEquals()
. As chaves devem ser imutáveis. - Para obter alta disponibilidade para as Coleções Confiáveis, cada serviço deve ter pelo menos um destino e uma réplica mínima com tamanho definido como 3.
- As operações de leitura no secundário podem ler versões que não são confirmadas por quorum. Isso significa que uma versão dos dados que é lida por meio de um único secundário pode ter um progresso falso. As leituras do Primário são sempre estáveis: elas nunca podem ter um progresso falso.
- A segurança/privacidade dos dados persistentes em uma coleção confiável pelo seu aplicativo é sua decisão e sujeita às proteções fornecidas pelo gerenciamento de armazenamento, ou seja, a criptografia de disco do sistema operacional pode ser usada para proteger seus dados em repouso.
- A enumeração
ReliableDictionary
usa uma estrutura de dados classificada ordenada por chave. Para tornar a enumeração eficiente, as confirmações são adicionadas a uma tabela de hash temporária e, posteriormente, movidas para a estrutura de dados classificada principal após o ponto de verificação. O Adds/Updates/Deletes tem o melhor runtime de O(1) e o pior runtime de O(log n), no caso de verificações de validação na presença da chave. Gets pode ser O(1) ou O(log n) se você estiver lendo de uma confirmação recente ou de uma confirmação mais antiga.
Diretrizes adicionais para coletas confiáveis voláteis
Ao decidir usar coletas confiáveis voláteis, considere o seguinte:
ReliableDictionary
tem suporte volátilReliableQueue
tem suporte volátilReliableConcurrentQueue
NÃO tem suporte volátil- Os serviços persistentes NÃO PODEM se tornar voláteis. Alterar o sinalizador
HasPersistedState
parafalse
requer a recriação de todo o serviço do zero - Os serviços voláteis NÃO PODEM se tornar persistentes. Alterar o sinalizador
HasPersistedState
paratrue
requer a recriação de todo o serviço do zero HasPersistedState
é uma configuração de nível de serviço. Isso significa que TODAS as coletas serão persistentes ou voláteis. Não é possível misturar coletas voláteis e persistentes- A perda de Quorum de uma partição volátil resulta em uma perda de dados completa
- O backup e a restauração NÃO estão disponíveis para serviços voláteis