Cet article fait suite à la première partie, dans laquelle nous avons vu comment intégrer en toute sécurité une flotte d'appareils IoT à grande échelle qui diffusent des données de télémétrie vers votre environnement Google Cloud via IoT Core et Pub/Sub.
Félicitations ! Vous avez enregistré plusieurs appareils IoT — et maintenant ?
L'objectif suivant : concevoir un système qui permette le stockage, l'analyse et la visualisation/dashboarding de vos données à grande échelle.

Pour y parvenir, il faut anticiper en concevant une architecture de flux de données capable de soutenir de telles opérations à grande échelle. Cet article propose une démonstration pratique pas à pas.
Vue d'ensemble
Cet article s'articule autour des sections suivantes :
- Chargement par lots vers les data sinks
- Stockage et analyse des données
- Visualisation des données entreposées
Contrairement à la première partie, tout ce qui est présenté ici peut se faire entièrement depuis la console web GCP. Seules des connaissances SQL de base sont requises.
Les services Google Cloud entièrement gérés et auto-scalables suivants seront abordés :
- Pub/Sub — une file de messages serverless
- Dataflow — un moteur de traitement de données en streaming et par lots
- BigQuery — un entrepôt de données serverless
- Data Studio — un service de visualisation de données et de création de dashboards
Chargement par lots vers les data sinks
Vérifier la bonne arrivée des messages
Si vous avez correctement intégré vos appareils dans le registre IoT et lancé la diffusion des données vers IoT Core, un flux régulier de messages devrait apparaître depuis le dashboard principal IoT de GCP :

Trois appareils connectés diffusant des données de température toutes les cinq secondes
Comme indiqué dans la première partie, ces messages arrivent également dans votre topic Pub/Sub temperature :

Messages Pub/Sub arrivant dans le topic temperature
Streaming vers BigQuery
Parfait — les messages arrivent bien dans Google Cloud. L'étape suivante consiste à transférer les messages Pub/Sub vers un entrepôt de données capable d'assurer une rétention long terme à coût maîtrisé et des analyses facilement scalables. C'est là qu'intervient BigQuery.
BigQuery, l'entrepôt de données entièrement géré, serverless et auto-scalable de Google Cloud, vous permet de payer le compute comme le stockage selon un modèle à la demande, ce qui en fait un excellent data sink pour stocker et analyser nos données IoT.
Mais comment acheminer les messages Pub/Sub vers BigQuery ? Avec Dataflow.
Dataflow, la version entièrement gérée et auto-scalable d'Apache Beam proposée par Google Cloud, est conçue pour acheminer des données d'un service à un autre. Vous pouvez, en option, filtrer et transformer les données, et les charger par lots de manière optimale dans des services soumis à des limites d'opérations de chargement, comme les bases de données et les solutions d'entreposage.
Dataflow inclut plusieurs templates par défaut créés par Google Cloud, dont un template Pub/Sub vers BigQuery, ce qui évite tout effort de développement pour relier les services d'ingestion et les services de stockage/analyse.
Pub/Sub, Dataflow et BigQuery étant tous des services entièrement gérés et auto-scalables, et (à l'exception de Dataflow) serverless, il est possible de bâtir un système de gestion de données IoT de bout en bout qui passe sans effort des tests de développement à des opérations à l'échelle du pétaoctet — quasiment sans gestion d'infrastructure à mesure que le système monte en charge.
Voyons tous ces services à l'œuvre, reliés entre eux !
Configuration de la subscription Pub/Sub
Avant de transférer des données de Pub/Sub vers Dataflow, créons une subscription Pub/Sub abonnée au topic.
Pourquoi ? Les messages reçus par un topic Pub/Sub sont envoyés immédiatement à ses abonnés (via une stratégie Push), puis supprimés du topic. À l'inverse, les abonnés peuvent conserver les messages jusqu'à ce qu'un processus en fasse la demande (via une stratégie Pull). Il est possible de connecter Dataflow directement à un topic plutôt qu'à une subscription, mais en cas d'interruption du job Dataflow, tous les messages reçus pendant la coupure seraient perdus.
En connectant Dataflow à une subscription Pub/Sub abonnée au topic, vous évitez cette perte. Si le job Dataflow venait à être temporairement interrompu, tous les messages IoT non encore traités resteraient dans la subscription Pub/Sub, en attente de la reprise du pull par Dataflow.
Une subscription Pub/Sub rattachée à un topic crée une architecture de données résiliente face aux interruptions des services d'ingestion en aval.
Pour créer une subscription dans Pub/Sub :
- Rendez-vous dans Subscriptions,
- Cliquez sur Create Subscription et nommez votre subscription temperature_sub
- Abonnez-la au topic Pub/Sub temperature
- Laissez les autres options à leurs valeurs par défaut

Création de la subscription Pub/Sub temperature_sub rattachée au topic Pub/Sub temperature
Une fois créée, cliquez sur la subscription puis sur Pull : les messages devraient commencer à arriver :

Exemples de messages arrivant dans la subscription Pub/Sub
Stockage et analyse des données
Maintenant que la subscription Pub/Sub reçoit des messages, nous sommes presque prêts à créer un job Dataflow pour les acheminer vers BigQuery. Avant cela, créons une table BigQuery où ces données viendront atterrir.
Création de la table BigQuery
Rendez-vous dans BigQuery, cliquez sur Create Dataset et nommez votre dataset sensordata, en laissant les autres options par défaut :

Fenêtre de création d'un dataset BigQuery
Une fois le dataset créé, sélectionnez-le, cliquez sur Create table et nommez votre nouvelle table temperature. Veillez à reproduire le schéma ainsi que les options de partitionnement et de clustering présentés dans les captures ci-dessous, car ils favorisent les schémas de requêtes courants :

Schéma de la nouvelle table BigQuery temperature

Options de partitionnement et de clustering pour la table temperature
Si tout est correct, votre nouvelle table vide ressemblera à ceci :

Une table BigQuery temperature vide dans le dataset sensordata
Une fois les données chargées, nous illustrerons un schéma de requête IoT courant : exécuter des analyses sur des données correspondant à une fenêtre temporelle précise (par exemple une plage d'une heure pour la journée en cours) et pour un appareil donné.
Cette conception de table est idéale pour ce type de requêtes, et ce pour deux raisons :
- Le partitionnement sur le champ timestamp UTC permet aux requêtes ciblant une date précise d'éviter de scanner les partitions DateTime des journées non concernées
- Au sein d'une partition, le clustering (tri) sur deviceId et le timestamp epoch permet une récupération plus efficace des données pour un appareil et une fenêtre temporelle précis dans la partition de date concernée.
Pour écrire ces requêtes, il nous faut des données dans la table. Lançons donc ce job Dataflow !
Configuration de Dataflow
Nous avons des messages dans une subscription Pub/Sub, en attente d'être transférés ailleurs, et une table BigQuery prête à les recevoir. Il nous manque la " colle " ETL qui relie les deux. Pub/Sub et BigQuery étant tous deux entièrement gérés, auto-scalables et serverless, l'idéal est de choisir un outil ETL doté des mêmes qualités.
Dataflow répond (presque) à ces critères. Le marketing autour de Dataflow affirme qu'il coche les trois cases, mais en réalité il n'est pas totalement serverless. Vous devez spécifier les types et tailles d'instances utilisés, le nombre minimum et maximum d'instances entre lesquels l'auto-scaling peut osciller, ainsi que la quantité d'espace disque temporaire nécessaire à chaque instance. Vous ne gérez jamais ces instances ni les décisions de mise à l'échelle, mais vous devez fournir ces spécifications. À l'inverse, Pub/Sub et BigQuery passent à l'échelle automatiquement sans aucune configuration d'infrastructure.
Bien qu'il ne soit pas totalement serverless, Dataflow s'avère parfaitement adapté à notre besoin ETL Pub/Sub vers BigQuery. Il est également simple à utiliser, d'autant plus que GCP propose de nombreux templates de jobs Dataflow par défaut, dont un qui prend en charge un workflow Pub/Sub vers BigQuery. À part devoir augmenter le nombre maximal d'instances autorisées par l'auto-scaling à mesure que votre débit de données IoT croît, vous n'aurez en théorie jamais à vous soucier de la gestion de l'infrastructure qui alimente Dataflow.
Les bases étant posées, mettons en place un job Dataflow. Rendez-vous dans Dataflow, cliquez sur Create Job from Template et suivez ces étapes :
- Nommez le job pubsub-temp-to-bq
- Utilisez le template streaming par défaut Pub/Sub Subscription to BigQuery
- Saisissez le nom complet de la subscription Pub/Sub
- Saisissez l'ID complet de la table BigQuery
- Indiquez l'emplacement d'un bucket Cloud Storage où les données temporaires pourront être stockées dans le cadre du processus de chargement par lots de Dataflow vers BigQuery
- Laissez les autres options à leurs valeurs par défaut. En production, vous étendriez les Advanced Options pour spécifier des paramètres comme le type et la taille de machine, les valeurs min/max d'auto-scaling et la taille de disque par machine. Pour des tests, les valeurs par défaut suffisent.
Votre écran de création de job Dataflow devrait ressembler à ceci :

Après avoir cliqué sur Create et patienté quelques minutes le temps que l'infrastructure sous-jacente démarre, vous verrez les données circuler depuis la subscription Pub/Sub vers la table BigQuery de destination.
Le script Python de streaming de température fourni dans la première partie diffuse à raison d'un enregistrement par seconde. Ainsi, dans le DAG (Directed Acyclic Graph) Dataflow présenté ci-dessous, vous devriez voir x éléments diffusés par seconde, où x correspond au nombre d'appareils utilisés pour vos tests. Dans mon cas, trois appareils diffusent :

Messages diffusés depuis Pub/Sub vers BigQuery via un job Dataflow
Une fois le job Dataflow actif et en train de diffuser correctement les données de la subscription Pub/Sub vers BigQuery, exécutez une requête au format suivant dans BigQuery pour observer les données arriver en temps réel dans la table :
SELECT *
FROM `iottempstreaming.sensordata.temperature`
WHERE DATE(timestamp_utc) = "2020-12-18"
ORDER BY timestamp_epoch DESC
LIMIT 10

On constate que le filtrage par partition opère bien : un volume total de données plus important est scanné lorsque la clause WHERE de filtrage par jour est retirée.
Dans mon dataset d'exemple, 1,1 Mo de données filtrées sont scannés (comme on le voit ci-dessus) contre 1,7 Mo sans filtre (illustré ci-dessous) :
SELECT *
FROM `iottempstreaming.sensordata.temperature`
ORDER BY timestamp_epoch DESC
LIMIT 10

Voyons maintenant les valeurs moyenne, minimale et maximale de température relevées par chaque capteur au cours de la dernière heure :
SELECT
device_id,
ROUND(AVG(temp_f), 1) AS temp_f_avg,
MIN(temp_f) AS temp_f_min,
MAX(temp_f) AS temp_f_max
FROM `iottempstreaming.sensordata.temperature`
WHERE timestamp_utc > DATETIME_ADD(CURRENT_DATETIME(), INTERVAL -60 MINUTE)
GROUP BY device_id

Diverses statistiques pour chaque appareil de streaming de température
Félicitations ! Vous venez de mettre en place un workflow de données entièrement géré de bout en bout, depuis l'ingestion jusqu'au backend analytique. Avant de conclure, voyons rapidement à quel point ces données se visualisent facilement avec Data Studio.
Visualisation des données entreposées
Commencez par exécuter dans BigQuery une requête semblable à la suivante, qui récupère toutes les lignes de données d'une journée donnée :
SELECT *
FROM `iottempstreaming.sensordata.temperature`
WHERE DATE(timestamp_utc) = "2020-12-18"
ORDER BY timestamp_epoch DESC
À droite de Query Results, cliquez sur Explore Data, puis sur Explore with Data Studio :

Cela charge un tableau récapitulant les données qui viennent d'être requêtées. Par défaut, il affiche toutefois un tableau peu parlant qui résume le nombre total d'enregistrements diffusés par seconde.
Modifions quelques valeurs sous la section Data, à droite, pour rendre cela plus exploitable :
- Sélectionnez Line Chart comme type de visualisation, plutôt que Table
- Retirez Record Count comme métrique affichée et remplacez-la par temp_f. Veillez à passer la métrique par défaut SUM à AVG.
- Ajoutez device_id comme dimension de ventilation
Vos choix devraient produire des paramètres de mise en page de dashboard semblables à ceci :

Le graphique généré affichera les valeurs de température de chaque appareil dans le temps, mais l'échelle automatique risque d'être inadaptée, la valeur minimale par défaut de l'axe Y étant zéro. Pour y remédier, cliquez sur l'onglet Style, descendez jusqu'à l'option Left Y-Axis et ajustez ces valeurs pour qu'elles soient plus pertinentes :

Vous voudrez peut-être aussi augmenter le nombre de points de données pouvant figurer sur le graphique :

Avec ces ajustements, vous obtenez un graphique élégant et interactif qui permet de parcourir les valeurs de température des appareils au fil de leurs fluctuations dans le temps :

Prochaine étape : le Machine Learning
Rendez-vous dans la troisième partie, où nous construirons un modèle de machine learning fonctionnel sur ce dataset BigQuery et l'utiliserons pour générer des prédictions en temps réel.