Como a Roblox ampliou sua plataforma Kafka para mais de 18 trilhões de mensagens por dia
Otimização de ponta a ponta para sistemas eficientes

Nos últimos dois anos, expandimos nossa plataforma interna de fila de mensagens em mais de 2,5 vezes a cada ano, atingindo mais de 18 trilhões de mensagens por dia. Atualmente, processamos mais de 300 milhões de mensagens por segundo, mantendo uma disponibilidade de 99,995%. Essa plataforma de fila de mensagens, construída com base no Apache Kafka, tornou-se uma parte essencial da forma como movimentamos dados em toda a empresa. Ela suporta cargas de trabalho como eventos analíticos, pipelines de moderação, sistemas de correspondência e muito mais. Esses números são impressionantes, mas o que é mais importante é como chegamos até aqui.
O impacto da otimização de ponta a ponta
Um equívoco comum sobre sistemas de grande escala é que a capacidade é, em grande parte, um problema de hardware. Em nossa experiência, as melhorias mais impactantes são obtidas ao tratar a escalabilidade como um problema de engenharia de ponta a ponta.
Equipes de toda a Roblox desenvolveram várias plataformas com base na fila de mensagens, incluindo pipelines de treinamento de IA, abstrações de processamento de fluxo e sistemas de telemetria. A parceria com os responsáveis por essas plataformas nos permite ajudar a garantir o cumprimento das melhores práticas, como a ativação de processamento em lote e compactação. Isso resulta em sistemas eficientes, sem envolver os usuários finais em configurações detalhadas.

Alinhar-se com as equipes que utilizam a plataforma em relação às prioridades de negócios, métricas e critérios de sucesso é fundamental e ajuda a impulsionar a colaboração entre equipes. As principais métricas variam entre as camadas do sistema: enquanto podemos otimizar os servidores Kafka para lidar com grandes volumes de dados de forma eficiente com menos máquinas, os usuários finais podem querer otimizar a latência de ponta a ponta até o nível de milissegundos, ou o tempo total para que sua tarefa em lote conclua a gravação dos dados.
Nem todo tráfego é igual
Uma lição importante que aprendemos é que plataformas de grande escala são mais confiáveis quando não tratam todo o tráfego da mesma forma. Algumas cargas de trabalho exigem latência muito baixa e proteção robusta durante picos de demanda, como nossos sistemas de matchmaking, que operam com latência de ponta a ponta inferior a 10 milissegundos. Outras apresentam volume extremamente alto, mas são mais tolerantes a atrasos, como nossos pipelines de ingestão de eventos analíticos, que podem funcionar sem problemas mesmo com vários segundos de latência de ponta a ponta. Se ambas forem tratadas da mesma forma, o tráfego de maior volume pode sobrecarregar o tráfego mais crítico para os negócios, especialmente durante picos de carga.
Para resolver esse problema, agrupamos o tráfego de acordo com os requisitos de cada caso de uso, a fim de garantir que cada um seja bem atendido. O equilíbrio entre latência de ponta a ponta e taxa de transferência no Kafka é uma das principais considerações ao configurar novos casos de uso. Isso se aplica a todo o caminho dos dados, do produtor ao servidor e ao consumidor: cada um deles possui configurações que podem ser ajustadas para otimizar a taxa de transferência ou a latência. As configurações do lado do cliente podem ser ajustadas para casos de uso individuais, mas as configurações do lado do servidor são menos flexíveis, pois é inviável manter um cluster dedicado para cada caso de uso distinto.
Aplicamos essa abordagem de otimização de cada cluster para os casos de uso que ele atende ao longo da pilha, até a camada de hardware.
O hardware ainda é fundamental
Começamos executando o Kafka em máquinas com HDDs em RAID10. À medida que o volume de tráfego cresceu, a capacidade de E/S de disco de nossas máquinas tornou-se o principal gargalo que limitava a taxa de transferência do Kafka por servidor. Para resolver isso, fizemos duas otimizações. Convertemos os brokers para usar SSDs tanto quanto possível, transferindo o gargalo da capacidade de E/S de disco para a taxa de transferência de rede ou espaço em disco (já que os SSDs que adquirimos tinham menos espaço em disco). Isso aumentou a taxa de transferência de E/S de disco em 10 vezes. Também começamos a converter nossos HDDs restantes de RAID10 para RAID0. Isso praticamente dobrou a capacidade de E/S de disco, já que cada gravação com RAID0 requer apenas uma única gravação em disco, em vez de duas.
A desvantagem é que, como cada réplica de mensagem é gravada em um disco por broker, em vez de dois, a mudança do RAID10 para o RAID0 pode acarretar riscos à confiabilidade. Para manter a confiabilidade, trabalhamos com casos de uso importantes para aumentar as confirmações (acks) e a replicação de dados, incluindo a replicação para várias regiões.
Aproveitar ao máximo os recursos de armazenamento e throughput de cada máquina exigiu trabalho adicional. Otimizamos nossas alocações de memória e configurações de gerenciamento do cache de páginas para que o Kafka possa armazenar mensagens em buffer e atender a leituras ou fornecer dados recentes a partir da memória, acessando o disco e consumindo IOPS valiosas apenas quando necessário, como na leitura de dados históricos.
Também realizamos testes de desempenho para compreender os limites do hardware e determinar quais limites no nível do software precisamos definir. Na prática, isso significa definir limites de leitura e gravação para os brokers do Kafka, que variam de acordo com o hardware em que os clusters estão rodando. Nossas máquinas com SSD podem lidar com maior throughput por broker, enquanto nossas máquinas com HDD são mais adequadas para casos de uso que exigem retenção de longo prazo de dados históricos.
Construindo para a Confiabilidade
A plataforma de filas é um componente crítico da infraestrutura da Roblox, e manter a confiabilidade é fundamental. Testes pré-lançamento, bem como testes contínuos de cenários de falha (às vezes chamados de “exercícios de dia de jogo”), têm sido essenciais para validar que nossa infraestrutura é resiliente a modos de falha, como falha de um único host, falha de rack, problemas de rede e muitos outros. A plataforma interna de testes de caos da nossa equipe de confiabilidade possibilitou e otimizou o processo de simulação de vários cenários de falha. Esses testes ajudam a identificar melhorias ou regressões no sistema e a construir excelência operacional, validando regularmente os alertas e garantindo que os operadores estejam familiarizados com as etapas para lidar com diversos problemas — mesmo aqueles mais raros.
Também projetamos e implementamos processos de failover capazes de restaurar rapidamente a funcionalidade da fila para casos de uso dependentes. Mesmo no caso de falha total de um cluster individual, somos capazes de transferir clientes para um cluster em bom estado com capacidade suficiente. Para garantir que tenhamos capacidade ociosa disponível suficiente, mantemos um cluster Kafka em standby. Isso ajuda a eliminar qualquer risco de problemas de “vizinho ruidoso” ao transferir tráfego entre clusters ativos.
O diagrama abaixo mostra as etapas gerais para a execução de um failover. Primeiro, um operador identifica o escopo do failover. Em seguida, os tópicos e as listas de controle de acesso (ACLs) são criados no cluster em espera por meio de uma operação em massa automatizada. Por fim, o operador atualiza as configurações do nosso serviço de plano de controle, que os clientes consultam para determinar se é necessária alguma reconexão. A ilustração abaixo se refere a casos de uso genéricos em tempo real. Temos estratégias e ferramentas adicionais para outros casos de uso e cenários, incluindo espelhamento de tópicos usando o Mirror Maker 2, ferramentas de preenchimento retroativo de dados e muito mais.

A Roblox possui requisitos rigorosos de segurança, o que também é um aspecto fundamental da confiabilidade. Implementamos recursos de segurança padrão, como criptografia em trânsito (com mTLS), criptografia em repouso (com disco criptografado), requisitos de tempo de retenção de dados e autenticação/autorização com entidades do Kafka e ACLs. Também fazemos a rotação automática das credenciais dos nossos usuários para melhorar ainda mais a segurança.
Além disso, criamos um tratamento personalizado em nosso plano de controle para facilitar a aplicação rápida de patches no sistema operacional e a remoção de racks. Durante a aplicação de patches no sistema operacional, mantemos os dados no disco para que as máquinas atualizadas possam recuperar rapidamente a integridade após se reconectarem ao cluster do Kafka. Dessa forma, podemos aplicar patches em toda a nossa frota em até 30 dias, mesmo enquanto ela continua a crescer. Com ferramentas como o Cruise Control, replicamos nossos dados de forma a levar em conta os racks, de modo que racks inteiros possam ser colocados offline para manutenção e aplicação de patches na rede sem afetar a disponibilidade dos dados.
O Caminho a Seguir
O próximo capítulo para nossa plataforma de filas consiste em torná-la ainda mais simples para os desenvolvedores, ao mesmo tempo em que continuamos a melhorar a elasticidade e o isolamento. Estamos investindo em novas abstrações, incluindo proxies de produtor e consumidor, bem como conectores totalmente gerenciados. Esses sistemas irão desacoplar ainda mais as equipes de aplicativos da complexidade da infraestrutura e tornarão nossas plataformas mais fáceis de adotar e gerenciar em escala. Por exemplo, um proxy de consumidor permitirá o padrão de consumidores concorrentes, possibilitando que a plataforma ofereça suporte a uma gama mais ampla de casos de uso e desacople o dimensionamento dos processadores do dimensionamento das partições do Kafka. Isso é valioso para casos de uso como o processamento de picos massivos de notificações, que não exigem ordenação e podem se beneficiar do aumento temporário do número de processadores sem metas obrigatórias de entrega de ponta a ponta.
Escalar o Kafka não se resume apenas a aumentar o número e o tamanho dos clusters. Trata-se de construir a disciplina de engenharia, as abstrações e o modelo operacional que permitem à Roblox continuar em nossa jornada para conectar um bilhão de pessoas todos os dias com otimismo e civilidade.
Agradecimentos: Agradecemos a Danny Yuan e George Li por suas contribuições significativas para a plataforma de fila do Roblox.


