I contenuti di questo sito sono stati tradotti mediante intelligenza artificiale (IA) o tecnologia di traduzione automatica e potrebbero contenere errori.

Skip to content

Come Roblox ha utilizzato Theta Sketches per potenziare l'analisi dei dati dei creatori

SEO image for Roblox Appoints Naveen Chopra as Chief Financial Officer

L'analisi dei dati è essenziale per i giochi multiplayer in tempo reale di oggi. Noi di Roblox ci concentriamo sullo sviluppo di strumenti di misurazione per aiutare i nostri creatori ad avere successo. I nostri strumenti di analisi gratuiti e pronti all'uso offrono ai creatori informazioni immediate sulla crescita delle loro esperienze, sull'acquisizione e sulla fidelizzazione degli utenti, aiutandoli a massimizzare il loro successo. 

La creazione di sistemi di analisi aggiornati su cui fanno affidamento milioni di creatori Roblox rappresenta una sfida importante. Per affrontarla, abbiamo ottimizzato il nostro motore di query analitiche in modo che un cluster di elaborazione a 120 core possa gestire più di 6 milioni di query al giorno provenienti da circa 300.000 visitatori giornalieri che accedono a 86 TB di dati. Il cuore della nostra soluzione è un database di elaborazione analitica online (OLAP) che abbiamo scelto per la sua scalabilità e integrazione con algoritmi di approssimazione. Utilizzando una combinazione di tecniche di rollup dei dati e algoritmi HyperLogLog e Theta Sketch, forniamo analisi per milioni di esperienze Roblox1

Introduzione all'analisi OLAP

Più dati vengono interrogati, più tempo ci vuole per ottenere i risultati. Quando riusciamo a ridurre i dati necessari e ad accelerare il processo di analisi, i creatori possono ottenere informazioni quasi in tempo reale sulle loro azioni. Alcune delle tecniche che utilizziamo includono:

  1. Archiviazione a colonne: l'OLAP, Druid, legge solo le colonne necessarie.
  2. Filtri di partizione e ordinamento: l'OLAP legge solo i file rilevanti che indicizzano direttamente i blocchi di dati necessari.
  3. Rollup: l'OLAP aggrega parzialmente gli eventi utilizzando raggruppamenti comuni.

I rollup, in particolare, consentono agli OLAP di operare tra i più grandi motori di query SQL, come Spark o Presto (con latenze di decine di secondi), e le query puntuali o SQL limitate, che di solito forniscono dati completamente aggregati. Con i rollup, le query vengono indiceate in base a raggruppamenti di dimensioni, con conseguenti riduzioni significative della cardinalità totale delle righe. Quando si esaminano miliardi o addirittura trilioni di eventi grezzi, può essere molto più efficiente raggrupparli in milioni di raggruppamenti che possono essere aggregati con una latenza inferiore al secondo. Ad esempio: 

Sebbene i rollup offrano i vantaggi di riduzione sopra menzionati, alcune metriche sono resistenti a essi, comprese le query che richiedono un ordinamento completo della tabella dei dati grezzi, come conteggi distinti, percentili e query di frequenza.

Fortunatamente, possiamo aggirare queste limitazioni con tecniche che restituiscono un risultato approssimativo statisticamente limitato basato su strutture di dati complesse che contengono un campione dell'intero set di dati. Queste strutture di dati sono progettate per essere utilizzate nelle tecniche di rollup e combinano due conteggi distinti tramite un'operazione di unione, simile alla somma di due numeri.

Analisi dei carichi di lavoro di Roblox Analytics

Noi di Roblox mettiamo a disposizione dei creatori una dashboard centralizzata dove possono trovare le informazioni più importanti. Queste includono: 

  • Coinvolgimento: utenti attivi giornalieri (DAU), utenti attivi mensili (MAU), fidelizzazione e funnel 
  • Monetizzazione: ricavi, ricavi medi per utente, vendite ed economia
  • Dati di acquisizione 
  • Personalizzazione delle miniature e risultati degli esperimenti
  • Analisi dei consigli in home
  • E molto altro ancora. 
Durante la creazione del nostro sistema, ci siamo concentrati sull'ottimizzazione delle query nel caso peggiore. Si tratta in genere di conteggi distinti di grandi dimensioni (>100 milioni di UUID), come gli utenti attivi mensili (MAU) per le esperienze più popolari, che possono rallentare i tempi di caricamento da pochi secondi a diversi minuti. Abbiamo creato un framework di approssimazione statistica per mantenere le query entro una latenza di due secondi. Abbiamo adattato le tecniche HyperLogLog e Theta Sketch dalle librerie standard del settore, riducendo le query nel caso peggiore da oltre 100 milioni di righe a circa 5 milioni.
Scelta e ottimizzazione del motore di ricerca
Dopo aver selezionato la nostra soluzione OLAP, abbiamo caricato sei mesi di dati di coinvolgimento e abbiamo testato i limiti prestazionali del nostro sistema. Con circa 100 core e 500 GB di memoria, abbiamo scoperto di poter unire in modo casuale 5 milioni di oggetti binari Theta Sketch (per un totale di circa 100 MB) in due secondi. Ciò è stato fatto su query a freddo lette dal disco senza accedere ad alcuna cache in memoria. Le opzioni di archiviazione in rete come le letture S3, che Clickhouse e Duckdb offrono di default, mostrano prestazioni significativamente peggiori. 
Superare le sfide legate alle prestazioni

Durante un'ultima serie di test di produzione in shadow, abbiamo scoperto una sfida importante: le prestazioni delle nostre query MAU dovevano essere potenziate dopo il passaggio da singole query di grandi dimensioni a modelli di aggregazione giornalieri. Questi sono fondamentali per le nostre visualizzazioni di analisi dei creatori. 

Abbiamo scoperto che la struttura della query influiva notevolmente sulle prestazioni sottostanti della nostra soluzione OLAP. Le query standard con più fasi di esecuzione (come le istruzioni "GROUP BY" annidate2) spesso trasferiscono gran parte del lavoro sui nodi broker leggeri. 

Si tratta di un classico problema dei big data in cui una parte della query finisce per essere eseguita su piccoli nodi di servizio importanti. Ci aspettavamo che le nostre strutture di dati approssimative funzionassero come semplici conteggi o somme, ma abbiamo scoperto che in realtà si comportavano in modo molto diverso. 

La figura seguente illustra il problema. Mostra come i nostri nodi storici effettuassero un'aggregazione parziale, raggruppando un Theta Sketch per ogni giorno e poi rinviando i dati al broker. Il broker tentava quindi di unire ogni grande sketch giornaliero in un unico valore mensile per giorno. Per 30 giorni di MAU, ciò significava unire 1.800 Theta Sketch di dimensione massima su un broker, il che comportava una query più lenta e soggetta a errori che monopolizzava la CPU del broker. 

La nostra soluzione è stata quella di eseguire l'OLAP con un numero ridotto di worker storici di grandi dimensioni per massimizzare la località dei dati per le origini dati che si basavano su query di approssimazione. In pratica, ciò ha riportato sui nostri nodi storici un'operazione di unione che avrebbe potuto richiedere più di 100 MB di elaborazione dei dati.

Per ottenere questo risultato in SQL, abbiamo utilizzato un join inline per far sì che le query propagassero le informazioni necessarie ai nodi storici e abbiamo preparato una query con un elenco di date di risultato inline. Ogni data di risultato può quindi raccogliere i dati rilevanti dai segmenti dei nodi storici. I dati vengono quindi ritrasmessi al broker, dove i risultati vengono rapidamente uniti in un'unica mappa di date di risultato e dati metrici, come mostrato di seguito.

Questa ottimizzazione ha avuto un impatto notevole sulle prestazioni per le query su larga scala. Per la ripartizione MAU per paese di un'esperienza importante, le prestazioni medie delle query sono migliorate di 5 volte (da 17,53 secondi a 3,23), come mostrato nel grafico sottostante. Abbiamo anche osservato una riduzione di 50 volte del tempo di CPU sul broker (da 16,83 secondi a 0,34). 

Sebbene i risultati possano variare, ciò evidenzia l'importanza di gestire con attenzione le operazioni complesse (come l'unione di milioni di sketch). Considerare queste operazioni equivalenti a semplici aggregazioni può portare a significativi problemi di prestazioni, specialmente su sistemi in cui sono comuni le aggregazioni client dell'ultimo miglio.

Rollup e un cubo theta teorico

La query analitica media sulla nostra piattaforma presenta un numero minimo di suddivisioni e raramente riguarda dimensioni ad alta cardinalità (come il paese). Sapendo questo, abbiamo deciso di duplicare i nostri dati, creando una tabella di rollup con un numero inferiore di dimensioni, che sarebbe stata sufficiente per oltre il 98%3 delle nostre query. Ha ottenuto prestazioni quattro volte migliori sulla query media.

Abbiamo anche esplorato un theta cube, ovvero un approccio generalizzato per colmare il divario tra le tabelle di rollup di base e le tabelle completamente grezze tramite intersezioni approssimative di insiemi. Questo approccio affronta una limitazione fondamentale: le tabelle di rollup perdono il loro vantaggio quando le query devono toccare molti livelli di dimensioni ad alta cardinalità. Questo perché ogni dimensione fa sì che la cardinalità del rollup si scali come ∏dim (prodotto delle dimensioni).

Abbiamo progettato un sistema in grado di aggregare per gruppi di dimensioni comuni con un limite di cardinalità, consentendo query di rollup performanti su qualsiasi elemento del gruppo. Quindi, quando si cercano combinazioni di dimensioni tra i gruppi, si tenta un join4 approssimativo tra gli insiemi e si restituiscono i risultati delle metriche insieme alle stime di errore. Una query con un errore stimato elevato verrebbe inoltrata a una tabella grezza, dove i numerosi filtri dovrebbero consentire ottimizzazioni pushdown di ampia portata.

Questo approccio del cubo theta cambia la dimensionalità, determinando un'espansione ∑dim (somma delle dimensioni) per il numero di righe invece dell'espansione ∏dim. Naturalmente, ciò può comportare una perdita di precisione, una dinamica direttamente proporzionale alla dimensione della sovrapposizione5 tra i due gruppi di dimensioni. La ragione alla base di ciò è direttamente correlata al modo in cui i Theta Sketches memorizzano un elenco ordinato in stile K-bottom, che massimizzerà le collisioni tra due insiemi con un'elevata sovrapposizione intrinseca.

Poiché possiamo calcolare rapidamente questo tasso di errore, ciò costituisce anche un segnale forte che la lettura della tabella grezza sarà probabilmente performante. Nei casi in cui i dati sovrapposti sono pochi rispetto all'unione (ad esempio, i parlanti giapponesi in Germania), un gran numero di righe della tabella grezza verrà filtrato. Ciò si traduce in ottimizzazioni pushdown efficienti. Un sistema che utilizza gruppi di dimensioni, join approssimativi e letture della tabella grezza basate sugli errori massimizzerebbe davvero le prestazioni di rollup su query adatte all'approssimazione.

Per Roblox, questa soluzione sarà più applicabile al nostro prossimo livello di scalabilità, potenzialmente per l'analisi dinamica del funnel o degli eventi personalizzati, mentre la nostra attuale replica di rollup semplice soddisfa le esigenze odierne.

Creazione di una piattaforma self-service

Una volta ottimizzato il nostro broker, ci siamo dedicati alla creazione di strumenti per l'onboarding e l'interrogazione dei set di dati aggiunti alla nostra soluzione OLAP. Abbiamo creato una libreria open source Spark e Trino UDAF per le nostre funzioni datasketch, consentendo a Spark di utilizzare lo stesso formato binario datasketch del nostro OLAP6. Ciò ha permesso di mantenere la maggior parte del nostro carico di lavoro di calcolo in Spark e ha contribuito a standardizzare l'approssimazione in Roblox, riducendo potenzialmente i costi di calcolo fino all'80% per determinati set di dati.

Abbiamo semplificato l'onboarding con un'estensione interna al nostro scheduler di lavori batch e definito un'API in stile dataframe che guida gli sviluppatori nella scelta di misure e dimensioni definitive, riducendo l'impatto delle query aperte. Abbiamo anche reso open source alcuni flussi di lavoro di esempio su come carichiamo e interroghiamo questi dati nel nostro OLAP.

I nostri set di dati analitici ottimizzati stanno ora fornendo approfondimenti dettagliati ai nostri creatori. Le nostre ottimizzazioni hanno migliorato le prestazioni medie di 4 volte e quelle nel caso peggiore di 50 volte. La piattaforma self-service consente al nostro team di Creator Analytics di continuare a iterare su nuovi set di dati per gli sviluppatori. Siamo entusiasti di vedere sviluppatori di ogni dimensione utilizzare questi strumenti per creare esperienze incredibili su Roblox.

1 Calcolato sugli ultimi 60 giorni di universi unici con qualsiasi accesso
2 Come questa query
MAU ingenua 3 I risultati sono dal 21 al 28 marzo 2025
4 Eseguito in questo modo: 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 Tramite una funzione SQL di Druid COMPLEX_DECODE_BASE64('HLLSketch', sketch_col_name ).