Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Visualiser les jobs BigQuery avec Stackdriver, Cloud Functions, Firebase et Pub/Sub

By Aviv LauferNov 8, 20174 min read

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

1 bimx94i4agv23fzxumvs4a 2

Chez DoiT International, nous utilisons largement Google BigQuery comme plateforme d'analyse de données pour reOptimize (désormais intégré à DoiT Cloud Intelligence™), notre plateforme d'optimisation des coûts pour Google Cloud Platform.

Google BigQuery est un formidable outil serverless pour interroger de grands volumes de données via la syntaxe SQL standard. Le modèle tarifaire repose sur la quantité de données scannées lors d'une requête, et vous pouvez exécuter jusqu'à 50 requêtes simultanées (les requêtes mises en cache ne sont pas comptabilisées).

Si plusieurs équipes coexistent dans votre organisation, il vous faut un moyen de savoir ce qui s'exécute à un instant donné. Aucune solution native ne permet de visualiser les requêtes en cours : c'est là qu'intervient bqtop.

75cce 1qv99kz0h12i8ea5lc7rhrq

Nous voulions disposer d'un utilitaire en ligne de commande, mais aussi d'une application web, pour consulter les requêtes en cours d'exécution ainsi qu'un historique. Pour récupérer les informations nécessaires, nous avons construit un pipeline entièrement serverless qui les met à disposition de notre application.

Commençons par le côté serveur

Première étape : créer plusieurs Stackdriver Logs Sinks pour exporter les logs BigQuery vers Google Pub/Sub. Nous allons créer deux sinks ; le premier filtre les messages de log signalant le démarrage d'une requête :

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

et le second concerne les requêtes terminées :

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

Chaque sink écrit ses données dans un topic Pub/Sub différent — bqtop-running-jobs et bqtop-finished-jobs.

Maintenant que les données circulent des logs vers Pub/Sub, il nous faut les écrire dans une base qui pourra ensuite être lue depuis l'application web ou la CLI. Pour cet usage, nous voulions une solution simple mais puissante, capable de lire directement depuis le client (afin d'éviter de construire un backend complet) et de notifier les ajouts ou mises à jour, pour ne pas avoir à interroger la base périodiquement. Firebase de Google s'est imposé comme un choix évident.

Pour acheminer les données de Pub/Sub vers la base Firebase, nous utilisons Firebase Cloud Functions. Nous écoutons les nouveaux événements sur les topics Pub/Sub et les insérons dans la base.

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

Les données sont stockées dans deux tables distinctes : l'une pour les jobs en cours, l'autre pour les tâches terminées. Lorsqu'un job s'achève, il faut le retirer de la table des jobs en cours. Enfin, nous avons créé quelques fonctions supplémentaires qui écoutent les modifications de données.

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

Dès qu'un événement signale de nouvelles données dans la référence des jobs terminés, nous cherchons un événement portant le même jobId dans la référence des jobs en cours pour le supprimer.

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

Pour gagner en performance, nous avons créé un index (cela se configure dans le fichier database.rules.json).

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

Place au client

La partie serveur bouclée, passons au client. Nous voulions à la fois un outil en ligne de commande pour les ingénieurs et une web-app à afficher sur le dashboard TV du bureau.

L'application en ligne de commande est un petit programme Python qui s'appuie sur curses pour toute la gestion de l'UI. Nous utilisons pyrebase comme wrapper de l'API Firebase. Comme évoqué plus haut, nous ne voulons pas interroger la base en permanence : nous préférons être notifiés lorsqu'une donnée change. Pour cela, nous nous appuyons sur deux flux de base de données déclenchés à chaque modification.

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

Lorsque la fonction de gestion est appelée, nous récupérons les données et les affichons à l'utilisateur.

Pour l'application web, nous nous appuyons sur le framework React et le SDK JavaScript de Firebase pour lire les données depuis la base et les visualiser dans la page.

En résumé, nous avons mis en place un pipeline élégant pour envoyer les logs BigQuery vers Google Pub/Sub, les traiter via Cloud Functions et les stocker dans Firebase Realtime Database — le tout sans déployer le moindre serveur et avec un effort de développement minimal.