El contenido de este sitio se ha traducido mediante inteligencia artificial (IA) o tecnología de traducción automática, y puede contener errores.

Skip to content

Cómo Roblox amplió su plataforma Kafka hasta superar los 18 billones de mensajes al día

Optimización integral para sistemas eficientes

En los últimos dos años, hemos ampliado nuestra plataforma interna de colas de mensajes más de 2,5 veces cada año, hasta superar los 18 billones de mensajes al día. Actualmente procesamos más de 300 millones de mensajes por segundo, manteniendo una disponibilidad del 99,995 %. Esta plataforma de colas de mensajes, basada en Apache Kafka, se ha convertido en una parte fundamental de cómo movemos los datos en toda la empresa. Soporta cargas de trabajo como eventos de análisis, flujos de moderación, sistemas de emparejamiento y muchas más. Estas cifras son impresionantes, pero lo más importante es cómo hemos llegado hasta aquí. 

El impacto de la optimización de extremo a extremo 

Una idea errónea muy extendida sobre los sistemas a gran escala es que la capacidad es principalmente un problema de hardware. Según nuestra experiencia, las mejoras más significativas se consiguen al abordar la escalabilidad como un problema de ingeniería de extremo a extremo.

Los equipos de Roblox han creado diversas plataformas basadas en la cola de mensajes, entre las que se incluyen flujos de trabajo de entrenamiento de IA, abstracciones de procesamiento de flujos y sistemas de telemetría. Colaborar con los responsables de estas plataformas nos permite garantizar el cumplimiento de las mejores prácticas, como habilitar el procesamiento por lotes y la compresión. El resultado son sistemas eficientes sin que los usuarios finales tengan que involucrarse en configuraciones detalladas.

Nuestra arquitectura de colas y las plataformas relacionadas permiten a otros equipos desarrollar sin tener que reinventar la rueda ni preocuparse por la configuración

Es fundamental alinearse con los equipos que utilizan la plataforma en cuanto a prioridades empresariales, métricas y criterios de éxito, ya que esto ayuda a impulsar la colaboración entre equipos. Las métricas clave varían según las capas del sistema: aunque podamos optimizar los servidores de Kafka para gestionar de forma eficiente grandes volúmenes de datos con menos máquinas, es posible que los usuarios finales quieran optimizar la latencia de extremo a extremo hasta el nivel de milisegundos, o el tiempo total que tarda su trabajo por lotes en completar la escritura de datos. 

No todo el tráfico es igual

Una lección clave que hemos aprendido es que las plataformas a gran escala son más fiables cuando no tratan todo el tráfico por igual. Algunas cargas de trabajo requieren una latencia muy baja y una protección sólida durante los picos de tráfico, como nuestros sistemas de emparejamiento, que operan con una latencia de extremo a extremo inferior a 10 milisegundos. Otras tienen un volumen extremadamente elevado, pero son más tolerantes al retraso, como nuestras canalizaciones de ingestión de eventos analíticos, que pueden funcionar sin problemas incluso con varios segundos de latencia de extremo a extremo. Si ambas se gestionan de la misma manera, el tráfico de mayor volumen puede desplazar al tráfico más crítico para el negocio, especialmente durante los picos de carga.

Para resolver este problema, agrupamos el tráfico según los requisitos de cada caso de uso para garantizar que cada uno reciba el apoyo adecuado. El equilibrio entre la latencia de extremo a extremo y el rendimiento en Kafka es una de las principales consideraciones a la hora de configurar nuevos casos de uso. Esto se aplica a lo largo de toda la ruta de datos, desde el productor hasta el servidor y el consumidor: cada uno de ellos cuenta con configuraciones que pueden ajustarse para optimizar bien el rendimiento, bien la latencia. Las configuraciones del lado del cliente pueden ajustarse para casos de uso individuales, pero las del lado del servidor son menos flexibles, ya que resulta insostenible mantener un clúster dedicado para cada caso de uso distinto. 

Aplicamos este enfoque de optimización de cada clúster para los casos de uso a los que da servicio a lo largo de la pila, hasta la capa de hardware. 

El hardware sigue siendo fundamental

Empezamos ejecutando Kafka en máquinas con discos duros (HDD) en RAID10. A medida que crecía el volumen de tráfico, la capacidad de E/S de disco de nuestras máquinas se convirtió en el principal cuello de botella que limitaba el rendimiento de Kafka por servidor. Para solucionarlo, realizamos dos optimizaciones. Convertimos los brokers para que utilizaran SSD en la medida de lo posible, desplazando el cuello de botella de la capacidad de E/S de disco al rendimiento de red o al espacio en disco (ya que los SSD que adquirimos tenían menos espacio en disco). Esto multiplicó por diez el rendimiento de E/S de disco. También empezamos a convertir nuestros discos duros restantes de RAID10 a RAID0. Esto duplicó aproximadamente la capacidad de E/S de disco, ya que cada escritura con RAID0 solo requiere una única operación de escritura en disco en lugar de dos. 

La contrapartida es que, dado que cada réplica de mensaje se escribe en un disco por broker en lugar de en dos, pasar de RAID10 a RAID0 puede conllevar un riesgo de fiabilidad. Para mantener la fiabilidad, trabajamos con casos de uso importantes para aumentar los acks y la replicación de datos, incluida la replicación en varias regiones.

Aprovechar al máximo las capacidades de almacenamiento y rendimiento de cada máquina requirió un trabajo adicional. Optimizamos nuestras asignaciones de memoria y las configuraciones de gestión de la caché de páginas para que Kafka pueda almacenar mensajes en el búfer y servir lecturas o datos recientes desde la memoria, recurriendo al disco y consumiendo valiosas IOPS solo cuando es necesario, como al leer datos históricos. 

También realizamos pruebas de rendimiento para comprender los límites del hardware y determinar qué límites a nivel de software debemos establecer. En la práctica, esto implica configurar límites de lectura y escritura en los brokers de Kafka, que varían en función del hardware en el que se ejecutan los clústeres. Nuestras máquinas con SSD pueden gestionar un mayor rendimiento por broker, mientras que nuestras máquinas con HDD son más adecuadas para casos de uso que requieren la retención a largo plazo de datos históricos. 

Diseño orientado a la fiabilidad

La plataforma de colas es un componente crítico de la infraestructura de Roblox, por lo que mantener su fiabilidad es fundamental. Las pruebas previas al lanzamiento, así como las pruebas continuas de escenarios de fallo (a veces denominadas «ejercicios de día de partido»), han sido fundamentales para validar que nuestra infraestructura es resistente a modos de fallo como el fallo de un único host, el fallo de un rack, problemas de red y muchos otros. La plataforma interna de pruebas de caos de nuestro equipo de fiabilidad ha permitido y optimizado el proceso de simulación de diversos escenarios de fallo. Estas pruebas ayudan a identificar mejoras o regresiones en el sistema y a alcanzar la excelencia operativa mediante la validación periódica de las alertas y garantizando que los operadores estén familiarizados con los pasos para gestionar diversos problemas, incluso los más infrecuentes.

También hemos diseñado e implementado procesos de conmutación por error que pueden restablecer rápidamente la funcionalidad de las colas para los casos de uso dependientes. Incluso en caso de fallo total de un clúster concreto, somos capaces de redirigir a los clientes a un clúster en buen estado con capacidad suficiente. Para garantizar que disponemos de suficiente capacidad no utilizada, mantenemos un clúster de Kafka en espera. Esto ayuda a eliminar cualquier riesgo de problemas de «vecinos ruidosos» al desviar el tráfico entre clústeres activos.

El siguiente diagrama muestra los pasos generales para ejecutar una conmutación por error. En primer lugar, un operador identifica el alcance de la conmutación por error. A continuación, se crean temas y listas de control de acceso (ACL) en el clúster en espera mediante una operación masiva automatizada. Por último, el operador actualiza las configuraciones de nuestro servicio de plano de control, que los clientes consultan para determinar si es necesaria alguna reconexión. La ilustración que figura a continuación corresponde a casos de uso genéricos en tiempo real. Disponemos de estrategias y herramientas adicionales para otros casos de uso y escenarios, como la duplicación de temas mediante Mirror Maker 2, herramientas de relleno de datos y mucho más.

Roblox tiene requisitos estrictos en materia de seguridad, lo cual también constituye un aspecto fundamental de la fiabilidad. Hemos implementado características de seguridad estándar como el cifrado en tránsito (con mTLS), el cifrado en reposo (con disco cifrado), los requisitos de periodo de retención de datos y la autenticación/autorización con entidades de Kafka y listas de control de acceso (ACL). Además, rotamos automáticamente las credenciales de nuestros usuarios para mejorar aún más la seguridad.

Además, hemos desarrollado un mecanismo personalizado en nuestro plano de control para facilitar la aplicación rápida de parches al sistema operativo y el vaciado de racks. Durante la aplicación de parches al sistema operativo, conservamos los datos en el disco para que las máquinas parcheadas puedan recuperar rápidamente su estado óptimo tras volver a unirse al clúster de Kafka. De esta forma, podemos aplicar parches a todo nuestro parque de servidores en un plazo de 30 días, incluso a medida que sigue creciendo. Con herramientas como Cruise Control, replicamos nuestros datos teniendo en cuenta los racks, de modo que se puedan desconectar racks enteros para realizar tareas de mantenimiento y aplicar parches de red sin que ello afecte a la disponibilidad de los datos.

El camino por delante

El próximo capítulo para nuestra plataforma de colas consiste en hacer que la plataforma resulte aún más sencilla para los desarrolladores, al tiempo que seguimos mejorando la elasticidad y el aislamiento. Estamos invirtiendo en nuevas abstracciones, entre las que se incluyen proxies de productores y consumidores, así como conectores totalmente gestionados. Estos sistemas desacoplarán aún más a los equipos de aplicaciones de la complejidad de la infraestructura y harán que nuestras plataformas sean más fáciles de adoptar y gestionar a gran escala. Por ejemplo, un proxy de consumidor permitirá el patrón de consumidores en competencia, lo que hará que la plataforma admita una gama más amplia de casos de uso y desacople el escalado de los procesadores del escalado de las particiones de Kafka. Esto resulta valioso para casos de uso como el procesamiento de picos masivos de notificaciones, que no requieren ordenación y pueden beneficiarse de un aumento temporal del número de procesadores sin tener que cumplir objetivos de entrega de extremo a extremo.

Escalar Kafka no consiste únicamente en aumentar el número y el tamaño de los clústeres. Se trata de desarrollar la disciplina de ingeniería, las abstracciones y el modelo operativo que permitan a Roblox continuar en nuestro camino para conectar a mil millones de personas cada día con optimismo y civismo. 

Agradecimientos: Gracias a Danny Yuan y George Li por sus importantes contribuciones a la plataforma de colas de Roblox.