A trajetória da Roblox rumo a 2 trilhões de eventos de análise por dia
Construindo uma infraestrutura escalável de ingestão de dados analíticos

Todos os dias, uma média de 97,8 milhões de usuários* visita o Roblox para se comunicar, criar e jogar juntos. Juntas, essas interações geram 2 petabytes de dados de eventos analíticos. Graças a um novo sistema de ingestão escalável, alcançamos recentemente um marco importante: nosso sistema agora processa mais de 2 trilhões de eventos por dia. Esse sistema possibilita os algoritmos de personalização, segurança e economia que impulsionam a plataforma Roblox.
Anteriormente, um serviço de fila na nuvem ingeria os dados analíticos gerados pelo Roblox em uma única tabela lógica, chamada events_hourly. Ela era particionada por data, hora e tags definidas arbitrariamente, como web, mobile ou friendService. Nossos cientistas de dados e engenheiros contavam com tarefas em lote programadas para extrair eventos específicos para tabelas dedicadas. A criação e o envio de novos eventos analíticos não exigiam um esquema pré-definido. Os engenheiros controlavam seu próprio esquema de tabela a jusante, na etapa do pipeline de extração, transformação e carregamento (ETL).

Essa configuração era flexível e permitia que os engenheiros agissem rapidamente, mas apresentava desafios.
- À medida que o volume de eventos crescia, interagir com 2 trilhões de linhas particionadas apenas por data, hora e tags se tornava cada vez mais ineficiente.
- Um atraso de seis horas no final do dia para a tabela events_hourly e um atraso de 24 horas para a tabela events_daily criavam períodos em que os pipelines de dados ficavam bloqueados.
- O gerenciamento de permissões, camadas, retenção e alertas no nível do conjunto de dados tornou-se mais complexo.
- A documentação, o histórico e a propriedade dos eventos estavam ausentes, resultando em baixa usabilidade e rastreabilidade dos dados.
- A infraestrutura de ingestão, construída com o serviço de fila na nuvem, gerou um custo de ingestão na nuvem de 23 Gbps.

Eliminando a extração dispendiosa de eventos
A análise de dados dependia anteriormente da extração de dados de uma única tabela lógica por meio de muitos pipelines em lote. Isso era necessário para executar consultas grandes e de alto desempenho — mas também tornava o processamento mais lento. O uso do serviço de back-end de ingestão para encaminhar esses eventos para tabelas dedicadas elimina os pipelines de extração em lote, atribuindo um esquema aos eventos analíticos e definindo uma tabela de destino antecipadamente.
Escolhemos o Protobuf (proto) como a linguagem de esquema para eventos analíticos na Roblox. Essa foi uma escolha natural, já que o proto e o gRPC são nossas estruturas preferidas para serviços de desenvolvimento. Além disso, o proto oferece excelente suporte para definir opções personalizadas que utilizamos para coletar metadados adicionais, como propriedade, retenção, canais de software de produtividade e esquema de eventos.

Após escolher nossa linguagem de esquema, examinamos o que acontece quando um esquema é atualizado e quais atualizações devem ser permitidas. Para dar suporte ao maior número possível de consumidores downstream que utilizam o esquema publicado, a equipe de dados adotou o modo transitivo retroativo descrito no Schema Registry. Com essa abordagem, é permitido adicionar e excluir temporariamente um campo. Isso permite alterações no esquema sem a necessidade de coordenação com os consumidores downstream.
No exemplo acima, podemos adicionar e excluir um campo atualizando o arquivo proto.

Os esquemas oferecem muitos benefícios, mas exigir que sejam definidos antecipadamente cria atritos. Cientistas de dados e engenheiros precisam agir rapidamente e iterar sem obstáculos. Para apoiar isso, introduzimos um repositório centralizado de esquemas e criamos um conjunto de ferramentas para tornar a criação de esquemas o mais automatizada e simplificada possível.
Por exemplo, criamos um linter proto personalizado para validar se cada esquema possui os metadados necessários e está em conformidade com as convenções da Roblox. Também criamos um plug-in proto para traduzir um esquema de evento para a linguagem de definição de dados Hive, de modo que a tabela Hive correspondente permaneça sincronizada sempre que um esquema for criado ou atualizado. Todas essas ferramentas estão integradas a um pipeline de CI/CD e são executadas automaticamente quando uma solicitação de pull é criada. Isso permite que os engenheiros identifiquem problemas de esquema antecipadamente e verifiquem eventos em tabelas Hive de teste antes que seus esquemas sejam mesclados. Como resultado, implantar um esquema na produção é tão simples quanto mesclá-lo.
Com uma experiência de desenvolvedor otimizada em vigor, examinamos em que ponto do pipeline de ingestão um evento deveria ser esquematizado e convertido para proto. Pedir aos produtores de eventos que adotassem e enviassem bytes proto serializados seria uma mudança significativa que envolveria várias equipes. Para resolver os pontos críticos e entregar valor de forma incremental, dissociamos o esforço de esquematização dos produtores de eventos, atualizando o serviço de back-end de ingestão para converter eventos recebidos para proto. Agora, os eventos convertidos são coletados em arquivos Parquet, carregados em um armazenamento distribuído e registrados como tabelas Hive individuais.
Captura de eventos em tempo real com os data centers da Roblox
Em seguida, focamos nos custos de fornecimento de eventos de análise. Anteriormente, o backend de ingestão era construído na infraestrutura em nuvem. Os eventos analíticos eram enviados para um serviço de fila, que os armazenava em buffer e, em seguida, os guardava em um armazenamento durável na nuvem para processamento e análise posteriores. Embora um serviço de fila na nuvem simplificasse nosso serviço e permitisse um dimensionamento transparente, ele é difícil de usar por outras tarefas de streaming e mais caro. Para resolver isso, exploramos a possibilidade de trazer o serviço de ingestão para os data centers da Roblox.
Nossa equipe interna de armazenamento havia construído o queue-as-a-service (QaaS), baseado em uma plataforma de streaming de eventos distribuída de código aberto. O QaaS é um ótimo substituto para a ingestão de eventos analíticos, pois os eventos são processados na ordem de entrada (first-in, first-out) e excluídos após um curto período de retenção. Na Roblox, criamos um tópico dedicado para cada evento esquematizado e usamos a contagem de partições para escalar fluxos de eventos de grande porte. A equipe de dados também desenvolveu um serviço dedicado para consumir dados do QaaS, criar arquivos Parquet e fazer o upload desses arquivos para um armazenamento durável na nuvem.
Com o QaaS em funcionamento e um serviço dedicado para criar e armazenar arquivos Parquet, a equipe de dados realizou gravações em segundo plano por seis meses para validar tanto a exatidão dos dados quanto a escalabilidade. Finalmente, após extensas verificações de integridade e completude dos dados, migramos com sucesso a ingestão de eventos analíticos para fora do nosso antigo serviço de fila na nuvem. Esse foi um marco importante. Removemos o custo de recursos de nuvem do caminho de ingestão e reduzimos significativamente a latência entre o disparo de um evento e sua chegada ao nosso data lake. Anteriormente, tínhamos um acordo de nível de serviço de três horas, que frequentemente não cumpríamos — hoje, estamos atingindo consistentemente uma média de 15 minutos.

Progresso e trabalhos futuros

Isso permite que os engenheiros criem pipelines de processamento de eventos em tempo real com base em eventos esquematizados, utilizando o QaaS para alimentar recursos de segurança e recomendação em tempo real. Também lançamos a captura de dados de alteração com a mesma estrutura de esquematização e ingestão do QaaS, eliminando em grande parte os dumps completos do banco de dados. Desde análises em tempo real e streaming de eventos até a descoberta de novos casos de uso, nosso trabalho continua à medida que inovamos e construímos sistemas de dados mais inteligentes, rápidos e econômicos em escala.
Gostaríamos de agradecer a Paul Mou por suas valiosas contribuições para este trabalho.
* Referente ao trimestre encerrado em 31 de março de 2025.


