
Este artículo es la continuación de la Parte Uno, donde vimos cómo incorporar de forma segura una flota de dispositivos IoT a escala productiva que envían telemetría a tu entorno de Google Cloud mediante IoT Core y Pub/Sub.
¡Felicitaciones! Ya registraste varios dispositivos IoT… ¿y ahora qué?
El siguiente paso es diseñar un sistema que te dé capacidades de almacenamiento, analítica y visualización/dashboarding a gran escala sobre esos datos.
Para lograrlo, conviene definir con anticipación una arquitectura de flujo de datos que soporte operaciones de esta magnitud. Este artículo te lleva paso a paso por ese proceso.
Visión general
Este recorrido se divide en las siguientes secciones:
- Carga por lotes hacia los data sinks
- Almacenamiento y análisis de datos
- Visualización de los datos almacenados
A diferencia de la primera parte, todo lo que veremos aquí se puede hacer desde la consola web de GCP. Solo se requiere experiencia básica con SQL.
Vamos a usar los siguientes servicios de Google Cloud, totalmente administrados y con auto-escalamiento:
- Pub/Sub: una cola de mensajes serverless
- Dataflow: un motor de procesamiento de datos en streaming y por lotes
- BigQuery: un data warehouse serverless
- Data Studio: un servicio para visualizar datos y crear dashboards
Carga por lotes hacia los data sinks
Verifica que los mensajes estén llegando
Si ya incorporaste dispositivos al registro de IoT y están enviando datos al IoT core, deberías ver un flujo constante de mensajes en el dashboard principal de IoT en GCP:
Tres dispositivos conectados correctamente que envían datos de temperatura cada cinco segundos
Como se mostró en la Parte Uno, esos mensajes también llegan a tu topic de Pub/Sub llamado "temperature":
Mensajes de Pub/Sub llegando al topic "temperature"
Streaming hacia BigQuery
Bien: los mensajes ya están llegando a Google Cloud. El siguiente paso es mover esos mensajes de Pub/Sub a un data warehouse donde puedan quedar almacenados a largo plazo de forma rentable y, además, permitir analítica fácilmente escalable. Aquí entra BigQuery.
BigQuery, el data warehouse totalmente administrado, serverless y con auto-escalamiento de Google Cloud, te permite pagar tanto por cómputo como por almacenamiento bajo un modelo de precios on-demand, lo que lo convierte en un excelente data sink para almacenar y analizar nuestros datos de IoT.
Pero ¿cómo movemos los mensajes de Pub/Sub a BigQuery? Con Dataflow.
Dataflow, la versión totalmente administrada y con auto-escalamiento de Apache Beam que ofrece Google Cloud, está pensado para mover datos de un servicio a otro. Te da la opción de filtrar y transformar datos, así como cargarlos por lotes de forma óptima en servicios con limitaciones en sus operaciones de carga, como bases de datos y soluciones de data warehousing.
Dataflow incluye varias plantillas predeterminadas creadas por Google Cloud, entre ellas una de Pub/Sub a BigQuery, así que no hace falta escribir código para conectar la ingesta de datos con los servicios de almacenamiento y analítica.
Como Pub/Sub, Dataflow y BigQuery son servicios totalmente administrados y con auto-escalamiento (y, salvo Dataflow, también serverless), se puede construir un sistema integral de gestión de datos IoT que escale con facilidad desde pruebas de desarrollo hasta operaciones a escala de petabytes, prácticamente sin tener que gestionar infraestructura a medida que crece.
¡Veamos todos estos servicios funcionando juntos!
Configuración de la suscripción a Pub/Sub
Antes de empezar a mover datos de Pub/Sub a Dataflow, conviene crear una suscripción de Pub/Sub asociada al topic.
¿Por qué? Los mensajes que llegan a un topic de Pub/Sub se envían de inmediato a sus suscriptores (mediante una estrategia Push) y luego se eliminan del topic. En cambio, los suscriptores pueden retener los mensajes hasta que un proceso los solicite (mediante una estrategia Pull). Es posible conectar Dataflow directamente a un topic en lugar de a una suscripción, pero si ese job de Dataflow llegara a quedar fuera de servicio, los mensajes que lleguen al topic durante esa caída se perderían.
En cambio, al conectar Dataflow a una suscripción de Pub/Sub asociada al topic, evitas perder mensajes durante una caída. Si el job de Dataflow se interrumpe temporalmente, todos los mensajes IoT que aún no se hayan procesado quedarán en la suscripción de Pub/Sub esperando a que el job retome la lectura.
Una suscripción de Pub/Sub a un topic genera una arquitectura de datos resiliente ante interrupciones del servicio de ingesta downstream.
Para crear una suscripción dentro de Pub/Sub:
- Ve a Suscripciones,
- Haz clic en "Crear suscripción" y ponle de nombre "temperature_sub"
- Asóciala al topic de Pub/Sub "temperature"
- Deja las demás opciones con sus valores predeterminados
Creación de la suscripción "temperature_sub" al topic de Pub/Sub "temperature"
Una vez creada, si haces clic en la suscripción y luego en " Pull", deberías ver mensajes empezando a llegar:
Ejemplo de mensajes llegando a la suscripción de Pub/Sub
Almacenamiento y análisis de datos
Ahora que tenemos una suscripción de Pub/Sub recibiendo mensajes, ya casi estamos listos para crear un job de Dataflow que los mueva a BigQuery. Antes de configurarlo, hay que crear en BigQuery una tabla donde aterrizarán los datos provenientes de Dataflow.
Configuración de la tabla en BigQuery
Ve a BigQuery, haz clic en "Crear conjunto de datos" y ponle de nombre "sensordata", dejando las demás opciones con sus valores predeterminados:
Asistente para crear el conjunto de datos en BigQuery
Una vez creado el dataset, selecciónalo, haz clic en " Crear tabla" y ponle de nombre "temperature". Asegúrate de incluir las opciones de esquema, particionado y clustering que se muestran en las capturas de abajo, ya que soportan los patrones de consulta más comunes:
Esquema de la nueva tabla "temperature" en BigQuery
Opciones de particionado y clustering para la tabla "temperature"
Si la creaste correctamente, la nueva tabla vacía se verá así:
Una tabla "temperature" vacía en BigQuery, dentro del dataset "sensordata"
Cuando ya tengamos datos en la tabla, mostraremos un patrón de consulta típico de IoT: ejecutar analítica sobre datos que correspondan a un rango de tiempo específico (por ejemplo, una ventana de una hora del día actual) y a un dispositivo en particular.
El diseño de tabla mostrado arriba es ideal para este tipo de consultas porque:
- Particionar por el campo de timestamp UTC permite que las consultas filtradas por fecha eviten escanear particiones DateTime de días que no coinciden.
- Dentro de una partición, el clustering (ordenamiento) por deviceId y por el timestamp epoch permite recuperar de forma más óptima los datos de un dispositivo y rango de tiempo específicos dentro de esa partición.
Para escribir esas consultas necesitamos datos en la tabla. ¡Pongamos en marcha ese job de Dataflow!
Configuración de Dataflow
Tenemos mensajes esperando en una suscripción de Pub/Sub para ser movidos a otro lugar y una tabla en BigQuery lista para recibirlos. Lo que falta es el "pegamento" ETL que conecte ambos. Como Pub/Sub y BigQuery son servicios totalmente administrados, con auto-escalamiento y serverless, lo ideal es contar con una herramienta ETL con esas mismas características.
Dataflow cumple (en su mayoría) con esos requisitos. Su marketing asegura que tiene los tres atributos, pero, a decir verdad, no es completamente serverless. Sí debes especificar los tipos y tamaños de instancia que se usarán, los recuentos mínimo y máximo entre los que puede oscilar el auto-escalamiento, y cuánto espacio temporal en disco necesitará cada instancia. Nunca administras esas instancias ni decides cuándo escalar, pero sí debes definir esas especificaciones. Algo distinto a Pub/Sub y BigQuery, que escalan automáticamente sin configuración de infraestructura.
A pesar de no ser totalmente serverless, Dataflow encaja perfecto para nuestro requisito de ETL de Pub/Sub a BigQuery. Además, es fácil de usar, sobre todo porque GCP ofrece muchas plantillas predeterminadas, incluida una que soporta el flujo de Pub/Sub a BigQuery. Salvo por la necesidad de subir el límite máximo de instancias del auto-escalamiento conforme crezca con el tiempo el throughput de tus datos IoT, en teoría nunca vas a tener que preocuparte por administrar la infraestructura que respalda Dataflow.
Con esto claro, vamos a implementar un job de Dataflow. Ve a Dataflow, haz clic en " Crear job desde plantilla" y sigue estos pasos:
- Ponle al job el nombre "pubsub-temp-to-bq"
- Usa la plantilla de streaming predeterminada "Pub/Sub Subscription to BigQuery"
- Ingresa el nombre completo de la suscripción de Pub/Sub
- Ingresa el ID completo de la tabla de BigQuery
- Indica una ubicación de bucket en Cloud Storage donde se puedan guardar datos temporales como parte del proceso de Dataflow para la carga por lotes hacia BigQuery
- Deja el resto de las opciones con sus valores predeterminados. Lo habitual sería expandir las Opciones avanzadas y definir parámetros como un tipo y tamaño de máquina específicos, los valores mínimo/máximo de auto-escalamiento y el tamaño de disco por máquina. Pero, para fines de prueba, pueden quedar con los valores predeterminados.
Tu pantalla de creación del job de Dataflow debería verse así:

Después de hacer clic en " Crear" y esperar unos minutos a que la infraestructura subyacente arranque y se ponga en marcha, verás los datos fluyendo desde la suscripción de Pub/Sub hacia la tabla de BigQuery de destino.
El script de Python que transmite la temperatura, incluido en la Parte Uno, envía un registro por segundo. Por eso, en el grafo acíclico dirigido (DAG) de Dataflow que se muestra abajo, deberías ver x elementos por segundo, donde x es la cantidad de dispositivos con los que estés probando. En mi caso son tres:
Mensajes transmitiéndose correctamente desde Pub/Sub a BigQuery a través de un job de Dataflow
Cuando veas que el job de Dataflow está activo y enviando correctamente los datos de la suscripción de Pub/Sub a BigQuery, puedes ejecutar una consulta con el siguiente formato y ver los datos llegando en tiempo real a la tabla:
SELECT *FROM `iottempstreaming.sensordata.temperature`WHERE DATE(timestamp_utc) = "2020-12-18"ORDER BY timestamp_epoch DESCLIMIT 10
Vemos que el filtrado por partición está funcionando: cuando se quita la cláusula WHERE que filtra por día, se escanea más cantidad de datos en total.
En mi conjunto de datos de ejemplo se escanean 1.1 MB con el filtro (como se ve arriba) y 1.7 MB sin filtrar (como se muestra abajo):
SELECT *FROM `iottempstreaming.sensordata.temperature`ORDER BY timestamp_epoch DESCLIMIT 10
Veamos cuáles son los valores promedio, mínimo y máximo de temperatura de cada sensor en la última hora:
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_maxFROM `iottempstreaming.sensordata.temperature`WHERE timestamp_utc > DATETIME_ADD(CURRENT_DATETIME(), INTERVAL -60 MINUTE)GROUP BY device_id
Distintas estadísticas para cada dispositivo que envía temperatura
¡Felicitaciones! Acabas de armar un flujo de datos totalmente administrado de extremo a extremo, desde la ingesta hasta el backend de analítica. Antes de cerrar este recorrido, veamos rápidamente lo fácil que es visualizar estos datos con Data Studio.
Visualización de los datos almacenados
Empieza ejecutando en BigQuery una consulta similar a la siguiente, que toma todas las filas de un día en particular:
SELECT *FROM `iottempstreaming.sensordata.temperature`WHERE DATE(timestamp_utc) = "2020-12-18"ORDER BY timestamp_epoch DESCA la derecha de " Resultados de consulta", haz clic en " Explorar datos" y luego en " Explorar con Data Studio":

Esto cargará una tabla con un resumen de los datos que acabamos de consultar. Sin embargo, por defecto mostrará una tabla bastante poco interesante con el total de registros transmitidos por segundo.
Cambiemos algunos valores en la sección Datos, a la derecha, para que sea más útil:
- Selecciona "Gráfico de líneas" como tipo de visualización en lugar de "Tabla"
- Quita "Recuento de registros" como métrica visualizada y reemplázala por "temp_f". Asegúrate de cambiar la métrica predeterminada "SUM" por "AVG".
- Agrega "device_id" como dimensión de desglose
Con eso, la configuración del dashboard debería verse parecida a esta:

El gráfico resultante mostrará los valores de temperatura de cada dispositivo a lo largo del tiempo, pero puede que no se auto-escale bien, ya que el valor mínimo del eje Y por defecto será cero. Para corregirlo, haz clic en la pestaña "Estilo", baja hasta la opción "Eje Y izquierdo" y cámbiala por valores razonables:

Quizá también quieras aumentar la cantidad de puntos de datos que pueden aparecer en el gráfico:

Con estos ajustes, deberías obtener un gráfico atractivo e interactivo que te permita recorrer los valores de temperatura de los dispositivos a medida que fluctúan en el tiempo:

Lo que sigue: Machine Learning
Atento a la tercera parte, en la que construiremos un modelo funcional de machine learning sobre este dataset de BigQuery y lo usaremos para generar predicciones en tiempo real.