Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Visualizzare i job BigQuery con Stackdriver, Cloud Functions, Firebase e Pub/Sub

By Aviv LauferNov 8, 20174 min read

Questa pagina è disponibile anche in English, Deutsch, Español, Français, 日本語 e Português.

1 bimx94i4agv23fzxumvs4a 2

In DoiT International usiamo Google BigQuery in modo intensivo come piattaforma di data analytics per reOptimize (oggi parte di DoiT Cloud Intelligence™), la nostra piattaforma di cost optimization per Google Cloud Platform.

Google BigQuery è uno straordinario strumento serverless per interrogare grandi volumi di dati con sintassi SQL standard. Il modello di pricing si basa sulla quantità di dati scansionati da ogni query e si possono eseguire fino a 50 query in parallelo (quelle in cache non vengono conteggiate).

Se nella tua organizzazione lavorano più team, ti serve un modo per sapere cosa è in esecuzione in ogni momento. Non esiste una soluzione out-of-the-box per visualizzare le query attive: a colmare la lacuna ci pensa bqtop.

75cce 1qv99kz0h12i8ea5lc7rhrq

Volevamo costruire sia una semplice utility da riga di comando sia una web app per vedere le query in esecuzione e parte dello storico. Per raccogliere le informazioni necessarie abbiamo realizzato una pipeline completamente serverless che le rende disponibili alla nostra applicazione.

Partiamo dal lato "server"

Per prima cosa creiamo un paio di Stackdriver Logs Sinks per esportare i log di BigQuery su Google Pub/Sub. I sink sono due: il primo filtra i messaggi di log che segnalano l'avvio di una query:

resource.type=bigquery_resource protoPayload.methodName=jobservice.insert

il secondo intercetta le query completate:

resource.type=bigquery_resource protoPayload.methodName=jobservice.jobcompleted

Ogni sink scrive i propri dati su un topic Pub/Sub diverso: bqtop-running-jobs e bqtop-finished-jobs.

Ora che i dati passano dai log a Pub/Sub, dobbiamo scriverli in un database leggibile poi dalla web app o dalla CLI. Per questo caso d'uso cercavamo qualcosa di semplice ma potente, che permettesse di leggere direttamente dal client — evitando così di costruire un backend completo — e che notificasse l'arrivo di dati nuovi o aggiornati, in modo da non dover interrogare periodicamente il database. Firebase di Google ci è sembrata la scelta naturale.

Per spostare i dati da Pub/Sub al database Firebase usiamo Firebase Cloud Functions: ci mettiamo in ascolto dei nuovi eventi sui topic Pub/Sub e li inseriamo nel database.

https://gist.github.com/avivl/30d92a579abd48dd4b3a9131b7f6abfb

I dati vengono salvati in due "tabelle" distinte: una per i job in esecuzione, l'altra per quelli completati. Quando un job termina, va rimosso dalla tabella dei job in esecuzione. Abbiamo poi aggiunto altre funzioni che restano in ascolto delle modifiche ai dati.

https://gist.github.com/avivl/58dbe67e6ade2b45f89e5a5d698c3dd3

Quando arriva un evento che segnala un nuovo dato nel reference dei finished jobs, cerchiamo nel reference dei running jobs un evento con lo stesso jobId e lo eliminiamo.

https://gist.github.com/avivl/c16af302a09a338f41480a11689a10d9

Per migliorare le prestazioni abbiamo creato un indice (l'operazione si effettua nel file database.rules.json).

https://gist.github.com/avivl/7ab33806e5d8da4caf62b9a57778433a

E ora passiamo al "client"

Concluso il lato "server", spostiamoci sul client. Volevamo avere sia uno strumento da riga di comando per gli Engineers sia una web app da mostrare sulla dashboard TV in ufficio.

L'app da riga di comando è una piccola applicazione Python che usa curses per gestire l'interfaccia. Come wrapper per le API di Firebase utilizziamo pyrebase. Come dicevamo, non vogliamo interrogare di continuo il database in cerca di modifiche: preferiamo ricevere una notifica quando qualcosa cambia. Sfruttando due stream del database, otteniamo un callback a ogni variazione.

https://gist.github.com/avivl/8ea27a7f98feb1d8735151ae3ba97bff

Quando l'handler viene invocato, possiamo recuperare i dati e mostrarli all'utente.

Per la web app usiamo React e l'SDK JavaScript di Firebase, così da leggere i dati dal database e visualizzarli sulla pagina.

In sintesi, abbiamo costruito una pipeline efficace che invia i log di BigQuery a Google Pub/Sub, li elabora con Cloud Functions e infine li archivia in Firebase Realtime Database, il tutto senza dover gestire alcun server e con uno sforzo di codice davvero minimo.