Armazenamento de Memória

*Este conteúdo é traduzido por IA (Beta) e pode conter erros. Para ver a página em inglês, clique aqui.

MemoryStoreService é um serviço de dados de alto desempenho e baixa latência que fornece armazenamento de dados rápido em memória acessível de todos os servidores em uma sessão ao vivo. Armazenamentos de Memória são adequados para dados frequentes e efeitos de duração que mudam rapidamente e não precisam ser duradouros, porque el

Estruturas de Dados

Em vez de acessar diretamente dados brutos, armazenamentos de memória têm três estruturas de dados primitivas compartilhadas entre servidores para processamento rápido: mapa sortido, fila e mapa de hashes. Cada estrutura de dados é uma boa opção para alguns casos de uso:

  • Criação de partidas baseada em habilidade - Salve informações do usuário, como o nível de habilidade, em uma fila compartilhada entre servidores e use servidores de lobby para executar a criação de partidas regularmente.
  • Negociação e leilão entre servidores - Habilite a negociação universal entre diferentes servidores, onde os usuários podem bidar em itens com preços de mudança de tempo real, com um mapa sortudo de pares de valor de chave.
  • Tabelas de classificação globais - Armazena e atualiza classificações de usuários em uma tabela de classificação compartilhada dentro de um mapa ordenado .
  • Inventários compartilhados - Salve itens de inventário e estatísticas em um mapa de hash compartilhado , onde os usuários podem usar itens de inventário concomitantemente um com o outro.
  • Cache for Persistent Data - Sincronize e copie seus dados persistentes em um armazenamento de dados para um armazenamento de memória hash mapa que pode atuar como um cache e melhorar o performancede sua experiência.

Em geral, se você precisar acessar dados com base em uma chave específica, use um mapa de hashes. Se você precisar que os dados sejam ordenados, use um mapa sortido. Se você precisar processar seus dados em um determinado ordenado, use uma fila.

Limites e Quotas

Para manter a escalabilidade e performancedo sistema, os armazenamentos de memória têm quotas de uso de dados para o tamanho da memória, solicitações de API e tamanho da estrutura de dados.

Os armazenamentos de memória têm uma política de expulsão com base no tempo de expiração, também conhecido como tempo para viver (TTL). Os itens são expulsos depois que expiram, e o quota de memória é liberado para novas entradas. Quando você atinge o limite de memória, todos os pedidos de gravação seguintes falharão até que os itens expirem ou você exclua manualmente.

Tamanho da Memória

O limite de memória limita a quantidade total de memória que uma experiência pode consumir. Não é um valor fixo. Em vez disso, ele muda ao longo do tempo dependendo do número de usuários na experiência de acordo com a seguinte fórmula: 64KB + 1KB * [number of users] . O limite aplica-se no nível da experiência em vez do nível do servidor.

Quando os usuários se juntam à experiência, o quota de memória adicional está disponível imediatamente. Quando os usuários saem da experiência, o quota não se reduz imediatamente. Existe um período de rastreamento de oito dias antes que o quota reavalie para um valor mais baixo.

Depois que sua experiência atinge o tamanho da memória, qualquer solicitação de API que aumente o tamanho da memória sempre falha. Solicitações que diminuem ou não alteram o tamanho da memória ainda são bem-sucedidas.

Com o painel de observabilidade, você pode ver o tamanho da memória do seu experimento em tempo real usando o gráfico Uso de Memória.

Limites de Pedido de API

Para limites de solicitação de API, há uma unidade de solicitação quota que se aplica a todas as chamadas da API MemoryStoreService. A quota é 1000 + 100 * [number de usuários concurrentes] unidades por minuto.

A maioria das chamadas da API só consome uma unidade de pedido, com algumas exceções:

  • MemoryStoreSortedMap:GetRangeAsync()

    Consume unidades com base no número de itens retornados. Por exemplo, se este método retornar 10 itens, a chamada contará como 10 unidades de solicitação. Se ele retornar uma resposta vazia, contará como uma unidade de solicitação.

  • MemoryStoreQueue:ReadAsync()

    Consume unidades com base no número de itens retornados, como MemoryStoreSortedMap:GetRangeAsync() ', mas consume uma unidade adicional a cada dois segundos ao ler. Especifique o tempo máximo de leitura com o parâmetro waittimeout.

  • MemoryStoreHashMap:UpdateAsync()

    Consume um mínimo de duas unidades.

  • MemoryStoreHashMap:ListItemsAsync()

    Consume [number de partitions scanned] + [items returned] unidades.

O quórum de pedidos também é aplicado no nível da experiência, em vez do nível do servidor. Isso fornece flexibilidade para alocar os pedidos entre os servidores, desde que a taxa total de pedidos não exceda o quórum. Se você exceder o quórum, você receberá uma resposta de erro quando o serviço limitar suas solicitações.

Com a observabilidade função disponível, você pode ver o quórum de unidade de pedido de sua experiência em tempo real.

Limites de Tamanho da Estrutura de Dados

Para um único mapa ou fila sortida, os seguintes limites de tamanho e contagem de itens aplicam-se:

  • Número máximo de itens: 1,000,000
  • Tamanho máximo total (incluindo chaves para mapas classificados): 100 MB

Limites de Per-Partition

Veja Limites de Per-Partition.

Melhores Práticas

Para manter seu padrão de uso de memória ótimo e evitar apertar os limites, siga essas melhores práticas:

  • Remova itens processados. Limpe consistentemente os itens lidos usando o método MemoryStoreQueue:RemoveAsync() para filas e MemoryStoreSortedMap:RemoveAsync() para mapas sortidos pode liberar memória e manter a estrutura de dados atualizada.

  • Defina o tempo de expiração para o menor tempo possível ao adicionar dados. Embora o tempo de expiração padrão seja 45 dias para ambos Class.MemoryStoreQueue:AddAsync() e Class.MemoryStoreSortedMap:SetAsync() , definir o tempo mais curto possível pode limpar automaticamente os dados antigos para impedir que eles ocupem sua memória de uso.

    • Não armazene uma grande quantidade de dados com uma longa expiração, pois isso pode exceder sua quota de memória e potencialmente causar problemas que podem interromper sua experiência inteira.
    • Sempre exclua itens não necessários ou configure uma expiração de itens curta.
    • Normalmente, você deve usar exclusão explícita para liberar memória e expiração de itens como um mecanismo de segurança para impedir que itens não usados ocupem memória por um período de tempo Extendido.
  • Só mantenha os valores necessários na memória.

    Por exemplo, para uma experiência de casa de leilão, você só precisa manter o lance mais alto. Você pode usar MemoryStoreQueue:UpdateAsync() em uma chave para manter o lance mais alto, em vez de manter todos os lances em sua estrutura de dados.

  • Use desconectar exponencial para ajudar a manter abaixo dos limites de solicitação da API.

    Por exemplo, se você receber um DataUpdateConflict, você pode tentar novamente depois de dois segundos, então quatro, oito, etc. em vez de enviar pedidos constantemente para Class.MemoryStoreService para obter a resposta correta.

  • Divida estruturas de dados gigantes em várias menores por sharding .

    Muitas vezes, é mais fácil gerenciar dados em estruturas menores do que armazenar tudo em uma única estrutura de dados grande. Essa abordagem também pode ajudar a evitar limites de uso e taxas. Por exemplo, se você tiver um mapa sorteado que usa prefixos para suas chaves, considere separar cada prefixo em seu próprio mapa sorteado. Para uma experiência popular, você pode até separar os usuários em vários mapas com base nos últimos dígitos de seus ID

  • Compre valores armazenados.

    Por exemplo, considere usar o algoritmo LZW para reduzir o tamanho do valor armazenado.

Observabilidade

O Painel de Observabilidade da Memória fornece insights e análises de monitoramento e solução de problemas para acompanhar e solucionar problemas relacionados ao uso de armazenamento de memória. Com gráficos atualizados em tempo real sobre diferentes aspectos do uso de armazenamento de memória e solicitações de API, você pode rastrear o padrão de uso de memória de sua experiência, ver os quotas atribuídos atuais e monitorar o status da API e identificar possíveis problemas para a otimização de desem

A tabela a seguir lista e descreve todos os códigos de status de respostas de API disponíveis no Painel de Observabilidade's Pedido por Status e Solicitações por API x Status gráficos. Para mais informações sobre como resolver esses erros, see Troubleshooting . Para o limite ou limite específico que um erro relaciona, see 1>Limits and Quot

Código de StatusDescrição
SucessoSucesso.
Limite de Memória de Estrutura de DadosExcede o limite de tamanho da memória da estrutura de dados (100MB).
Conflito de DadosConflito devido a uma atualização concomitante.
Negado de AcessoNão autorizado a acessar dados de experiência. Este pedido não consome unidades de pedido ou usa quota.
Erro InternoErro interno.
Solicitação inválidaA solicitação não tem informações necessárias ou tem informações malformadas.
Limite de Itens de Estrutura de DadosExcede o limite de nível de item da estrutura de dados (1M).
Nenhum item encontradoNenhum item encontrado em MemoryStoreQueue:ReadAsync() ou MemoryStoreSortedMap:UpdateAsync() . ReadAsync() polls a cada 2 segundos e retorna este código de status até que encontre itens na fila.
Limite de Solicitações de DadosExcede o limite de solicitação de nível de estrutura de dados (100.000 unidades de solicitação por minuto).
Limite de Solicitações de PartiçãoExcede o limite de unidade de pedido de partição.
Limite Total de SolicitaçõesExcede o limite de unidade de pedido do nível do universo.
Limite Total de MemóriaExcede o quórum de memória de nível do universo.
ItemValueSizeTooLargeO tamanho do valor excede o limite (32KB).

A tabela a seguir lista códigos do lado do cliente, que não estão disponíveis no Painel de Observabilidade.

Código de StatusDescrição
Erro InternoErro Interno.
Lugar não publicadoVocê deve publicar este lugar para usar o MemoryStoreService.
Acesso Inválido ao ClienteO MemoryStoreService deve ser chamado do servidor.
Expiração de Tempo InválidaO tempo de 'expiração' da campo deve ser entre 0 e 3,888,000.
Solicitação inválidaNão foi possível convertter o valor em JSON.
Solicitação inválidaNão foi possível convertar o sortKey em um número ou string / cadeia / textoválido.
Transformação de retorno de chamada falhouFalha ao invocar a função de chamada de transformação.
RequestThrottledSolicitações de armazenamento de memória recente atingiram um ou mais limites.
Conflito de AtualizaçãoNúmero máximo de tentativas excedido.

Problemas

A tabela a seguir lista e descreve a solução recomendada para cada código de status de resposta:

ErroOpções de solução de problemas
DataStructureCommands / PartitionCommands

  • Adicione um cache local ao salvar informações em outra variável e verificar depois de um determinado intervalo de tempo, como 30 segundos.
  • Use o gráfico Request Count by Status para verificar que voc

    • Fragmentar suas estruturas de dados se você receber uma quantidade significativa de respostas DataStructureCommandsLimit / PartitionCommandsLimit .
    • Implanta uma backoff exponencial para encontrar uma taxa razoável de pedidos para enviar.

Limite Total de Solicitações
Limite de Itens de Estrutura de Dados
  • Aplique as melhores práticas de redução de tamanho da memória.
Limite de Memória de Estrutura de Dados
Limite Total de Memória
Conflito de Dados

    implementa um atraso pequeno entre solicitações para evitar várias solicitações atualizando a mesma chave ao mesmo tempo. Para mapas sortidos, use a função de retorno de chamada no método Class.MemoryStoreSortedMap:UpdateAsync() para cancelar uma solicitação após uma certa quantidade

Erro Interno

  • Verifique a página de status do Roblox
  • .

    File um relatório de bug descrevendo o problema com o ID do Universo da sua experiência.

Solicitação inválida
  • Certifique-se de incluir parâmetros corretos e válidos em sua solicitar / pedir. Exemplos de parâmetros inválidos incluem:
    • Uma string vazia
    • Uma string que excede o limite de comprimento
ItemValueSizeTooLarge
  • Separar ou dividir o valor do item em várias chaves.
    • Para organizar chaves agrupadas, classifique-as alfabeticamente adicionando um prefix à chave.
  • Código ou compactação de valores armazenados.

Testando e Debugando no Studio

Os dados em MemoryStoreService são isolados entre o Studio e a produção, então alterar os dados no Studio não afeta o comportamento de produção. Isso significa que suas chamadas da API do Studio não acessam dados de produção, permitindo que você teste com segurança armazenamentos de memória e novos recursos antes de ir à produção.

Testes do Studio têm os mesmos limites e quotas que a produção. Para quotas calculadas com base no número de usuários, a quota resultante pode ser muito pequena, pois você é o único usuário para testes do Studio. Ao testar do Studio, você também pode notar um ligeiro aumento de latência e taxas de erro elevadas em comparação com o uso na produção devido a alguns controles adicionais que são executados para verificar acesso e permissões.

Para obter informações sobre como debugar um armazenamento de memória em experiências ao vivo ou ao testar em estúdio, use Console de Desenvolvedor.