Cómo Roblox utilizó Theta Sketches para ampliar el análisis de creadores

La analítica es esencial para los juegos multijugador en tiempo real actuales. En Roblox, nos centramos en desarrollar herramientas de medición para ayudar a nuestros creadores a prosperar. Nuestra analítica gratuita y lista para usar ofrece a los creadores información instantánea sobre el crecimiento de sus experiencias, la captación de usuarios y la retención, lo que les ayuda a maximizar su éxito.
Crear los sistemas de análisis actualizados de los que dependen millones de creadores de Roblox es un reto importante. Para abordarlo, hemos optimizado nuestro motor de consultas analíticas de modo que un clúster de procesamiento de 120 núcleos pueda atender más de 6 millones de consultas al día procedentes de aproximadamente 300 000 visitantes diarios que acceden a 86 TB de datos. El núcleo de nuestra solución es una base de datos de procesamiento analítico en línea (OLAP) que elegimos por su escalabilidad y su integración con algoritmos de aproximación. Mediante una combinación de técnicas de agregación de datos y los algoritmos HyperLogLog y Theta Sketch, proporcionamos análisis para millones de experiencias de Roblox1.
Introducción al análisis OLAP
Cuantos más datos se consultan, más tiempo se tarda en obtener resultados. Cuando somos capaces de reducir los datos necesarios y acelerar el proceso de análisis, los creadores pueden obtener información casi en tiempo real sobre sus acciones. Algunas de las técnicas que utilizamos incluyen:
- Almacenamiento en columnas: el OLAP, Druid, solo lee las columnas necesarias.
- Filtros de partición y ordenación: el OLAP solo lee los archivos relevantes que se indexan directamente a los bloques de datos necesarios.
- Rollup: el OLAP agrega parcialmente los eventos utilizando agrupaciones comunes.
Los rollups, en particular, permiten a los OLAP operar entre los motores de consultas SQL más grandes, como Spark o Presto (con latencias de decenas de segundos), y las consultas puntuales o SQL limitado, que suelen servir datos totalmente agregados. Con los rollups, las consultas se organizan por agrupaciones de dimensiones, lo que da lugar a grandes reducciones en la cardinalidad total de las filas. Al analizar miles de millones o incluso billones de eventos sin procesar, puede resultar mucho más eficiente agruparlos en millones de agrupaciones que se puedan agregar con una latencia inferior a un segundo. Por ejemplo:

Aunque los rollups ofrecen las ventajas de reducción mencionadas anteriormente, ciertas métricas son resistentes a ellos, incluidas las consultas que requieren una clasificación completa de la tabla de datos sin procesar, como recuentos distintos, percentiles y consultas de frecuencia.
Afortunadamente, podemos sortear estas limitaciones con técnicas que devuelven un resultado aproximado estadísticamente limitado basado en estructuras de datos complejas que contienen una muestra del conjunto de datos completo. Estas estructuras de datos están diseñadas para utilizarse en técnicas de rollup y combinan dos recuentos distintos mediante una operación de unión, similar a la suma de dos números.
Desglose de las cargas de trabajo de Roblox Analytics
En Roblox, ofrecemos a los creadores un panel de control centralizado donde pueden encontrar sus datos más importantes. Entre ellos se incluyen:
- Interacción: usuarios activos diarios (DAU), usuarios activos mensuales (MAU), retención y embudos
- Monetización: ingresos, ingresos medios por usuario, ventas y economía
- Datos de adquisición
- Personalización de miniaturas y resultados de experimentos
- Análisis de las recomendaciones de la página de inicio
- Y mucho más por venir.

Selección y optimización del motor de búsqueda
Superar los retos de rendimiento
En una ronda final de pruebas de producción en entorno de prueba, descubrimos un reto importante: era necesario reforzar el rendimiento de las consultas MAU tras pasar de consultas únicas de gran tamaño a patrones de agregación diarios. Estos son cruciales para nuestras visualizaciones de análisis de creadores.
Descubrimos que la estructura de la consulta afectaba en gran medida al rendimiento subyacente de nuestra solución OLAP. Las consultas estándar con múltiples etapas de ejecución (como las sentencias «GROUP BY» anidadas2) suelen trasladar gran parte del trabajo a los nodos de intermediación ligeros.
Este es un problema clásico de big data en el que una parte de la consulta acaba ejecutándose en pequeños nodos de servicio importantes. Esperábamos que nuestras estructuras de datos aproximadas funcionaran como simples recuentos o sumas, pero descubrimos que, en realidad, se comportaban de forma muy diferente.
La siguiente figura ilustra el problema. Muestra cómo nuestros nodos históricos realizaban una agregación parcial, acumulando un Theta Sketch para cada día y luego enviando sus datos de vuelta al broker. A continuación, el broker intentaba fusionar cada gran boceto diario en un único valor mensual por día. Para 30 días de usuarios activos mensuales (MAU), esto significaba fusionar 1800 Theta Sketches de tamaño máximo en un broker, lo que daba lugar a una consulta más lenta y propensa a fallos que monopolizaba la CPU del broker.

Nuestra solución consistió en ejecutar el OLAP con menos trabajadores históricos de gran tamaño para maximizar la localidad de los datos en las fuentes que dependían de consultas de aproximación. En la práctica, esto devolvió a nuestros nodos históricos una operación de fusión que podría haber requerido el procesamiento de más de 100 MB de datos.
Para lograrlo en SQL, utilizamos una unión en línea para que las consultas propagaran la información necesaria a los nodos históricos y preparamos una consulta con una lista de fechas de resultados en línea. Cada fecha de resultado puede entonces recopilar los datos relevantes de los segmentos de los nodos históricos. A continuación, los datos se devuelven al broker, donde los resultados se fusionan rápidamente en un único mapa de fechas de resultados a datos métricos, como se ve a continuación.

Esta optimización tuvo un impacto espectacular en el rendimiento de las consultas a gran escala. En el desglose por país de los usuarios activos mensuales (MAU) de una experiencia importante, el rendimiento medio de las consultas mejoró 5 veces (de 17,53 segundos a 3,23), como se muestra en el gráfico siguiente. También observamos una reducción de 50 veces en el tiempo de CPU en el broker (de 16,83 segundos a 0,34).
Aunque los resultados varían, esto pone de relieve la importancia de tratar con cuidado las operaciones complejas (como la fusión de millones de bocetos). Suponer que estas operaciones son equivalentes a simples agregaciones puede dar lugar a importantes problemas de rendimiento, especialmente en sistemas en los que son habituales las agregaciones de clientes de última milla.
Resúmenes y un cubo theta teórico

También exploramos un cubo theta, o un enfoque generalizado para salvar la brecha entre las tablas de resumen básicas y las tablas totalmente sin procesar mediante intersecciones de conjuntos aproximadas. Este enfoque aborda una limitación fundamental: las tablas de resumen pierden su ventaja cuando las consultas deben abarcar muchas capas de dimensiones de alta cardinalidad. Esto se debe a que cada dimensión hace que la cardinalidad del resumen se escale como ∏dim (producto de las dimensiones).
Diseñamos un sistema que agregaría por grupos de dimensiones comunes con un límite de cardinalidad, lo que permitiría realizar consultas de rendimiento de rollup sobre cualquier elemento del grupo. A continuación, al buscar combinaciones de dimensiones entre grupos, intentaríamos una unión aproximada (join4) entre los conjuntos y devolveríamos los resultados métricos junto con estimaciones de error. Una consulta con un error estimado elevado se reenviaría a una tabla sin procesar, donde los numerosos filtros deberían permitir grandes optimizaciones de pushdown.


Dado que podemos calcular esta tasa de error rápidamente, también sirve como una clara indicación de que la lectura de la tabla sin procesar probablemente será eficaz. En los casos en que los datos superpuestos sean pequeños en relación con la unión (por ejemplo, los hablantes de japonés en Alemania), se filtrará un gran número de filas de la tabla sin procesar. Esto da lugar a optimizaciones de pushdown eficientes. Un sistema que utilice grupos de dimensiones, uniones aproximadas y lecturas de tablas sin procesar basadas en errores maximizaría realmente el rendimiento del rollup en consultas aptas para la aproximación.
Para Roblox, esta solución será más aplicable en nuestro siguiente nivel de escala —potencialmente para el análisis dinámico de embudos o de eventos personalizados—, mientras que nuestra sencilla réplica de rollup actual satisface las necesidades actuales.
Creación de una plataforma de autoservicio
Una vez optimizado nuestro broker, nos centramos en crear herramientas para la incorporación y consulta de conjuntos de datos añadidos a nuestra solución OLAP. Creamos una biblioteca de código abierto de UDAF para Spark y Trino destinada a nuestras funciones de datasketch, lo que permitió a Spark utilizar el mismo formato binario de datasketch que nuestro OLAP6. Esto mantuvo la mayor parte de nuestra carga de trabajo de cálculo en Spark y ayudó a estandarizar la aproximación en todo Roblox, lo que podría reducir los costes de cálculo hasta en un 80 % para determinados conjuntos de datos.
Simplificamos la incorporación con una extensión interna de nuestro programador de trabajos por lotes y definimos una API de estilo dataframe que guía a los desarrolladores a la hora de decidir sobre medidas y dimensiones definitivas, reduciendo el impacto de las consultas abiertas. También hemos publicado en código abierto algunos flujos de trabajo de muestra sobre cómo cargamos y consultamos estos datos en nuestro OLAP.
Nuestros conjuntos de datos analíticos optimizados proporcionan ahora información detallada a nuestros creadores. Nuestras optimizaciones mejoraron el rendimiento medio en 4 veces y el rendimiento en el peor de los casos en 50 veces. La plataforma de autoservicio permite a nuestro equipo de Creator Analytics seguir iterando sobre nuevos conjuntos de datos para los desarrolladores. Estamos encantados de ver cómo desarrolladores de todos los tamaños utilizan estas herramientas para crear experiencias increíbles en Roblox.
1 Calculado a partir de los últimos 60 días de universos únicos con cualquier acceso
2 Como esta consulta
MAU básica 3 Los resultados son del 21 al 28 de marzo de 2025
4 Realizado así: SELECT c.experience_id, c.country, p.platform, THETA_INTERSECT(c.user_theta, p.user_theta) from (select experience_id, country, user_theta from theta_cube where agg_level = country) c union (select experience_id, platform, user_theta from theta_cube where agg_level = platform) p
5 https://datasketches.apache.org/docs/Theta/ThetaSketchSetOpsAccuracy.html
6 A través de una función SQL de Druid COMPLEX_DECODE_BASE64('HLLSketch', sketch_col_name ).


