Use estas práticas para organizar e gerenciar dados confiáveis, escaláveis e observáveis ao longo de seu ciclo de vida.
Organize seus dados
Crie menos armazenamentos de dados
Os armazenamentos de dados se comportam de maneira semelhante a tabelas em bancos de dados. Use um pequeno conjunto fixo de armazenamentos de dados e organize os registros dentro deles por chave. Por exemplo, armazene o perfil de cada jogador em um único armazenamento de dados PlayerData em vez de criar um armazenamento de dados para cada jogador.
Use uma ou poucas chaves por jogador
Armazene os dados persistentes de cada jogador sob uma chave sempre que os dados se encaixarem dentro do limite de tamanho de objeto de 4 MB. Por exemplo, use uma chave como User_123456 no armazenamento de dados PlayerData. Esse padrão reduz solicitações, permite que você atualize valores relacionados de forma atômica e torna os retrocessos mais fáceis de entender.
Se diferentes partes dos dados de um jogador tiverem padrões de acesso diferentes ou se aproximarem dos limites de tamanho ou taxa por chave, divida o registro em um pequeno número de chaves determinísticas. Mantenha os dados que devem mudar de forma atômica na mesma chave.
Use padrões e prefixos de chave estáticos
Construa nomes de chave a partir de identificadores estáveis e padrões estáticos, como User_{UserId}. Não use nomes de exibição ou outros valores que possam mudar. Padrões estáticos tornam as chaves previsíveis entre servidores e ferramentas. Para armazenamentos de dados, eles também permitem que o processamento automatizado do direito de ser esquecido identifique os dados dos jogadores.
Use prefixos para agrupar chaves relacionadas. Por exemplo, uma experiência que suporta múltiplos perfis de personagem pode usar User_123456/Profile/Warrior e User_123456/Profile/Mage. Você pode então passar User_123456/Profile para ListKeysAsync() para listar os perfis daquele jogador.
Escopos são outra maneira de subdividir um armazenamento de dados. Um escopo adiciona uma string a cada chave naquela instância de armazenamento de dados, e o padrão é global.
Avalie módulos de armazenamento de dados
Módulos de armazenamento de dados de terceiros são sempre uma opção e, em muitos casos, podem ser preferidos a construir sistemas do zero. Antes de adotar um, revise sua propriedade, status de manutenção e conjuntos de recursos. Entenda como acessar e migrar seus dados sem o módulo.
Reduza e distribua solicitações
Armazene dados do jogador na memória
Carregue os dados de um jogador no início de uma sessão e mantenha uma cópia local do servidor para o jogo. Atualize a cópia local em vez de enviar uma solicitação de armazenamento de dados para cada alteração. Salve-a periodicamente, quando o jogador sair, quando o servidor desligar e em pontos críticos, como o processamento de compras. Escolha um intervalo de salvamento periódico que permaneça dentro dos seus limites de solicitação e seja mais curto do que qualquer expiração de bloqueio de sessão; o exemplo de dados do jogador e compras usa 180 segundos.
Espalhe solicitações recorrentes
Não inicie solicitações recorrentes de cada servidor no mesmo cronograma. Antes de iniciar um loop de frequência fixa, atribua a cada servidor ou jogador um deslocamento inicial aleatório. Para loops de polling ou coordenação que não exigem uma cadência exata, adicione jitter aleatório limitado a cada intervalo. Esses padrões distribuem solicitações ao longo do tempo e reduzem picos de tráfego sincronizados.
Tente novamente falhas transitórias
Envolva solicitações em pcall() e tente novamente falhas transitórias com retrocesso exponencial. Adicione jitter aleatório a cada atraso para que os servidores não tentem novamente simultaneamente. Limite o atraso e o número de tentativas, e não tente novamente erros causados por solicitações inválidas ou operações que não podem mais fornecer resultados úteis.
Processar tentativas de armazenamento de dados em ordem para cada chave. Uma solicitação mais antiga que tenta novamente após uma solicitação mais nova ter sucesso pode sobrescrever dados mais novos. Também leve em conta gravações com resultados desconhecidos: uma chamada falhada significa que o servidor não recebeu uma resposta bem-sucedida, mas o backend pode ter concluído a gravação. Para mais informações, consulte Códigos de erro e limites de armazenamento de dados e Tentativas.
Prefira UpdateAsync em vez de SetAsync
Prefira UpdateAsync() quando uma gravação depender do valor atual ou quando múltiplos servidores possam gravar a mesma chave. UpdateAsync() lê o valor mais recente em seu callback antes de gravar, o que reduz atualizações perdidas. SetAsync() sobrescreve a chave sem ler primeiro e pode causar inconsistência se dois servidores gravarem ao mesmo tempo.
Use SetAsync() quando você criar uma nova chave ou substituir um valor que não depende do valor anterior. Para uma comparação dos dois métodos, consulte Set vs update.
Divida chaves quentes
Cada chave tem limites de taxa de leitura e gravação. Se um registro lógico consistentemente atingir esses limites após você reduzir solicitações desnecessárias, divida-o entre chaves determinísticas. Escolha um fragmento estável a partir de um identificador, como User_{UserId}_Inventory_{ShardId}, para que cada servidor direcione os mesmos dados para o mesmo fragmento.
A fragmentação torna a manutenção da consistência e a realização de migrações futuras mais complexas. Não fragmentar dados que se encaixam em uma chave e permanecem abaixo de seus limites de taxa.
Construa um fluxo de trabalho de operações
Use as ferramentas disponíveis juntas:
- Observe. Use o Painel de Observabilidade de Armazenamentos de Dados para rastrear solicitações, status de resposta, taxa de transferência e armazenamento. Configure alertas personalizados para métricas importantes de armazenamento de dados para que sua equipe possa responder a falhas sustentadas ou crescimento inesperado. As notificações do Creator Hub também informam quando o armazenamento se aproxima ou excede limites e incluem orientações e links para painéis.
- Inspecione. Use o Gerenciador de Armazenamentos de Dados para examinar armazenamentos de dados, chaves, uso de armazenamento e custos estimados. Se a experiência tiver mais de 100 armazenamentos de dados, a lista de Armazenamentos de Dados não mostra tamanhos e contagens de chaves. Use Open Cloud ou o Processador em Lote de Armazenamentos de Dados para essas métricas.
- Remedie. Use o Gerenciador de Armazenamentos de Dados para registros individuais. Use as APIs de armazenamento de dados do Open Cloud ou o Processador em Lote de Armazenamentos de Dados para fluxos de trabalho repetíveis ou em grande escala.
- Escale intencionalmente. Primeiro, reduza o armazenamento e as solicitações desnecessárias. Se o uso legítimo exceder as cotas padrão, avalie os Serviços Estendidos.
Open Cloud e servidores de jogos compartilham o orçamento de solicitações em nível de experiência. Limite a taxa de scripts operacionais do Open Cloud para que não interfiram no tráfego ao vivo.
Gerencie o ciclo de vida dos dados
Use versões de armazenamento de dados em vez de criar uma nova chave para cada revisão. Somente a versão mais recente de uma chave conta para o uso de armazenamento, e as versões permitem que você inspecione ou restaure valores anteriores.
Use armazenamentos em memória para dados temporários e que mudam rapidamente. Os dados do armazenamento em memória expiram automaticamente e não adicionam ao armazenamento persistente de dados.
Exclua dados de teste quando os testes terminarem e remova dados de eventos expirados ou recursos aposentados. Depois de marcar um armazenamento de dados para exclusão, há um buffer de 30 dias durante o qual você pode restaurá-lo. Após esses 30 dias, a Roblox exclui permanentemente o armazenamento de dados. Para mais informações, consulte Gerenciador de Armazenamentos de Dados.
Configure o processamento do direito de ser esquecido
Configure o processamento automatizado do direito de ser esquecido (RTBF) para dados de jogadores que seguem padrões de armazenamento de dados e chaves estáticas. O RTBF automatizado é o fluxo de trabalho preferido porque a Roblox aplica seus modelos de exclusão quando processa uma solicitação elegível.
Se o RTBF automatizado não suportar seu esquema de dados, use o webhook de direito à exclusão para executar um fluxo de trabalho de exclusão personalizado. Verifique se qualquer um dos fluxos de trabalho remove todos os dados correspondentes dos jogadores.