Si alguna vez tuviste que lidiar con un caso de uso de data streaming en la nube, lo más probable es que hayas abierto más pestañas del navegador de las que te gustaría reconocer mientras investigabas las distintas opciones de AWS y sus, digamos, FAQs kilométricas.

¿Quién tiene tiempo de leer cincuenta páginas de documentación solo para entender qué servicio elegir?
A continuación se enumeran varios de los servicios de AWS más relevantes para ingerir, transformar, almacenar y analizar datos en streaming. Para cuando estés leyendo este post, puede que la lista ya no sea exhaustiva:
- Kinesis Data Streams
- Kinesis Firehose con integración opcional con Lambda
- Kinesis Data Analytics
- Managed Streaming for Apache Kafka (MSK)
- Spark Streaming con Elastic MapReduce (EMR)
- Glue Streaming ETL
- IoT Analytics dentro de IoT Core
Si te sientes frustrado o estás invirtiendo demasiado tiempo en decidir qué opción tomar, acompáñame: voy a despejar la confusión cubriendo los fundamentos y el caso de uso ideal de cada servicio.
Al final del artículo encontrarás un breve resumen de cuál elegir según cada situación.
Kinesis: la opción por defecto
La apuesta estrella de Amazon para data streaming, y la que deberías considerar como opción por defecto en la mayoría de los casos de uso, es Kinesis. Sin embargo, dentro de Kinesis hay varios subservicios con nombres algo crípticos; los más relevantes son:
- Kinesis Data Streams (a menudo llamado simplemente Streams)
- Kinesis Firehose (o solo Firehose), y
- Kinesis Data Analytics (o solo Analytics)
Veamos cada uno en detalle.
Kinesis Data Streams vs. Kinesis Firehose
Streams vs. Firehose: panorama de funcionalidades
Tanto Data Streams como Firehose ingieren datos y los descargan en un sink. Entonces, ¿por qué existen dos servicios distintos que parecen cumplir la misma función?
La diferencia principal es que Streams está pensado para enviar datos a servicios de cómputo con consumidores personalizados —como aplicaciones que corren sobre EC2, EMR o Lambda— que se encargan de transformar y procesar los datos en tiempo casi real con una latencia de apenas ~70 ms. Esto hace que Streams sea ideal para soportar dashboards en tiempo real, detección de anomalías y aplicaciones similares sensibles al tiempo. Streams se integra muy bien con Apache Spark, lo que simplifica la manipulación de datos en tiempo real mediante streaming Data Frames cuando se requiere analítica más compleja.
Por su parte, Firehose no está pensado para entregas en tiempo casi real. En su lugar, agrupa los mensajes entrantes en lotes, opcionalmente los comprime o los transforma con AWS Lambda y luego envía los datos, normalmente a un servicio de AWS. Suele ser S3, Redshift o Elasticsearch.
Si bien los mensajes de Stream suelen ser consumidos por aplicaciones personalizadas, también se puede configurar Streams para que envíe datos hacia un stream de Firehose, habilitando así tanto la analítica en tiempo real como el almacenamiento por lotes con retención a largo plazo.
Si tu caso de uso no exige procesamiento en tiempo casi real, Firehose probablemente sea más adecuado y, además, más fácil de operar directamente.
Firehose: por lo general, la mejor opción
¿Por qué exactamente Firehose es la opción más conveniente entre estos dos servicios?
Primero: Kinesis Streams requiere un esfuerzo de codificación más extenso mediante programas escritos con su Kinesis Producer Library (KPL) y Kinesis Consumer Library (KCL), centradas en Java. Firehose, en cambio, está diseñado principalmente para volcar datos en servicios específicos de AWS, lo que significa que no hay que escribir código para el componente de sink. Publicar mensajes en Firehose también es sencillo:
import boto3firehose_client = boto3.client('firehose')
response = firehose_client.put_record(
DeliveryStreamName='string',
Record={'Data': b'bytes'} # base64-encoded
)
Si te resulta aceptable que Kinesis Streams probablemente sufra una merma de rendimiento tanto del lado del productor como del consumidor, además de perder otros beneficios, puedes usar los AWS SDKs para publicar mensajes de forma más simple en lugar de meterte en un desarrollo más extenso basado en KPL:
import boto3kinesis_client = boto3.client('kinesis')
response = kinesis_client.put_record(
StreamName='string',
Data=b'bytes', # base64-encoded
PartitionKey='string'
)
Segundo: tanto Streams como Firehose son totalmente gestionados y con auto-scaling, pero Streams hace "menos" auto-scaling y no es del todo serverless.
El auto-scaling de Firehose te permite escalar de inmediato y sin fricciones desde pruebas en desarrollo hasta GBs de datos por segundo sin sobresaltos, siempre que no estés alcanzando los límites de throughput de Firehose en AWS.
El escalado de Streams es más complejo. Aunque no gestionas directamente la infraestructura subyacente, sí debes definir para un Kinesis Stream una cantidad de "shards" que se traduce en el throughput soportado por ese stream. Un shard puede equivaler como máximo a 1 MB/s o 1.000 registros/s de throughput de escritura, y 2 MB/s de throughput de lectura. Por lo tanto, hay que pre-aprovisionar una cierta cantidad de "shards" para soportar un nivel determinado de throughput. Puedes cambiar manualmente la cantidad de shards de un stream o configurar auto-scaling, aunque este último proceso es más enredado de lo que debería.
Así, para lograr mayor throughput, escalas la cantidad de shards del stream. Sin embargo, hay un detalle importante: añadir o eliminar un shard de un stream toma en promedio unos 30 segundos, y solo se puede añadir o quitar un shard a la vez.
Veamos cómo esto puede impactar en un caso real: si tienes un stream con 1.000 shards (~1 GiB/s de throughput de escritura) y prevés que tendrás que duplicar tu throughput en el futuro cercano, tu stream tardará más de 8 horas en escalar por completo añadiendo 1.000 shards adicionales.
Si tienes razones para creer que algún día podrías enfrentar un pico repentino e inesperado de volumen de datos, Kinesis Data Streams no podrá escalar lo suficientemente rápido.
Con esto en mente, Streams no es adecuado para casos de uso con alta variabilidad en el throughput de streaming, a menos que estés dispuesto a aceptar el sobreaprovisionamiento y pagar de más para esas ocasiones, o que confíes en tu capacidad de anticipar picos de escalado y planificar en consecuencia. Firehose, simplemente, es más fácil de escalar, más fácil de desarrollar y, como pronto veremos, más fácil de presupuestar. Kinesis Streams debería usarse solo cuando se requiera analítica en tiempo real.
Streams vs. Firehose: comparación de complejidad de Precios
El enfoque serverless y con auto-scaling de Firehose para data streaming significa que también tiene un esquema de Precios pay-as-you-go directo, basado en:
- GBs de datos ingeridos por mes y, para los casos de uso pertinentes:
- GBs de conversiones de formato de datos realizadas
- GBs de datos entregados a una VPC
Los Precios de Data Streams son más complejos de pronosticar, ya que se basan en:
- La cantidad de shard-horas aprovisionadas, que puede variar con el auto-scaling. Lo más probable es que tengas que sobreaprovisionar para asegurar uptime confiable.
- La cantidad de payloads PUT de 25 KB enviados
- Cargos opcionales por retención de datos a largo plazo
- Activación opcional de enhanced fan-out, una funcionalidad que mejora el throughput cuando muchos consumidores leen del mismo shard
Streams vs. Firehose: resumen
Si tu objetivo es realizar transformaciones básicas y carga por lotes de tus datos en streaming hacia un data store, y no tienes un requisito de procesamiento en tiempo real, deberías publicar tus datos directamente en Firehose. También conviene elegir Firehose si quieres minimizar el tiempo dedicado al desarrollo de la app o las preocupaciones por la escalabilidad rápida de la infraestructura.
Si necesitas procesar datos en tiempo real, envíalos a través de Streams, pero ten presente que incluso con auto-scaling activado puede no manejar bien los aumentos de throughput con picos pronunciados.
Si necesitas procesar datos en tiempo real y además almacenarlos para analítica posterior, puedes enviar tus datos primero a Streams y luego, desde la consola web de Kinesis, configurar fácilmente que Streams reenvíe esos datos a Firehose sin necesidad de código (a menos que se quiera aplicar pasos opcionales de transformación con Lambda).
Puede ayudar pensar en Streams como algo funcionalmente similar a Apache Kafka, pero con almacenamiento persistente temporal de mensajes que pueden reenviarse a muchos consumidores. Los consumidores pueden ser aplicaciones personalizadas (EC2 o EMR) o servicios gestionados de AWS (Firehose). A Firehose se le suele tratar como un cargador por lotes para servicios específicos, normalmente del entorno AWS (S3, Redshift, Elasticsearch), con transformaciones de datos serverless opcionales potenciadas por Lambda.
Kinesis Data Analytics: analítica de ventanas serverless
Streams y Firehose cubren bastante bien la ingesta, la transformación y el traslado de datos en streaming hacia aplicaciones de análisis en tiempo real (Streams) y sinks de almacenamiento a largo plazo (Firehose). Entonces, ¿qué rol cumple Analytics?
Data Analytics, la oferta totalmente gestionada y serverless de Apache Flink de Amazon:
- Se integra con Data Streams o con Firehose
- Ejecuta consultas SQL contra esos datos en streaming, y
- Envía los resultados a un servicio de AWS, como otro Data Stream, un stream de Firehose o Lambda
- Data Analytics también puede tratar archivos estáticos CSV o JSON ubicados en S3 como tablas SQL, lo que habilita JOINs entre datos de referencia y datos en streaming.
Data Analytics se usa principalmente para calcular continuamente agregaciones de datos en streaming, anotadas con datos de referencia estáticos, sobre ventanas de tiempo —normalmente con fines de alertado en tiempo real— sin ningún código ni infraestructura aprovisionada, solo SQL directo. Podrías escribir código en Flink y desplegarlo en lugar de SQL, pero por facilidad de mantenimiento yo me quedaría con SQL, dado que Scala y Java son menos comunes en el mundo de la ciencia de datos.
La documentación de AWS muestra un ejemplo de analítica con ventanas deslizantes usando datos de cotización de acciones, pero yo te recomendaría más bien estudiar este ejemplo del mundo real, mucho más interesante, donde se ingieren las velocidades de tráfico de toda Bélgica en un stream de Firehose, se usa Data Analytics para comparar las velocidades de tráfico actuales vs. las pasadas con la ayuda de datos de referencia en S3, se determina la presencia de embotellamientos con SQL y se envían alertas en tiempo real con Lambda.
Managed Streaming for Apache Kafka (MSK)
Tanto Kinesis Data Streams como MSK, la oferta gestionada por AWS para Apache Kafka, son sistemas "pub-sub" eficaces que permiten la publicación y el consumo de mensajes con alto throughput, baja latencia, alta disponibilidad y tolerancia a fallos. En términos generales de escalabilidad y confiabilidad como plataforma de ingesta y entrega de datos, no hay demasiada diferencia entre ambos, al menos en la superficie.
Sin embargo, las diferencias críticas están en los detalles, y por lo general favorecen a Kinesis:
- Solo puedes aumentar la cantidad de message brokers. Es decir, no puedes escalar hacia abajo un despliegue de MSK.
- Si bien MSK es totalmente gestionado, no es Kafka serverless. Por lo tanto, MSK requiere algo de configuración del cluster. Debes definir las zonas y subnets en las que se lanzarán tus brokers, la cantidad de brokers por zona, el tipo de instancia que los soporta, y así sucesivamente.
- Dado que MSK no es serverless, también pagas por el almacenamiento basado en EBS que respalda las instancias. Esto tampoco se puede escalar hacia abajo.
- No puedes cambiar el tipo de instancia tras la configuración inicial del cluster. Tu única opción para escalar hacia arriba es aumentar la cantidad de instancias.
- Kinesis es el servicio de streaming totalmente gestionado y serverless propio de AWS, así que naturalmente tendrá una mejor integración con los servicios de AWS. Algunos consumidores de Kinesis se pueden conectar sin código, mientras que MSK exige que todas las aplicaciones consumidoras se construyan a medida, por ejemplo en EC2, EKS, EMR o con código Flink desplegado en Kinesis Data Analytics.
- Solo puedes tener un consumidor de Kafka dentro de un mismo "grupo" de consumidores leyendo de una partición a la vez. Kinesis, en cambio, soporta múltiples consumidores por shard.
La configuración inicial y continua del cluster, sumada a la imposibilidad de escalar despliegues hacia abajo, implica que habrá más sobrecarga de DevOps a corto y largo plazo al usar MSK en comparación con Kinesis.
Los Precios también son diferentes entre ambos y, de nuevo, generalmente favorecen a Kinesis.
Como mencioné antes, los Precios de Kinesis Data Streams son en gran medida bajo demanda. Se basan principalmente en la cantidad de payloads PUT de 25 KB enviados y en la cantidad de shard-horas aprovisionadas para habilitar el throughput de PUT y GET deseado. La cantidad de shards puede configurarse con auto-scaling para simular Precios bajo demanda, aunque la implementación es algo torpe.
MSK, en cambio, se cobra según la cantidad de instancias del tamaño elegido que estén corriendo, así como por los tamaños de volumen EBS que las respaldan. Ni la cantidad de instancias ni el tamaño del volumen EBS se pueden reducir; si sobreaprovisionas, te quedas con la factura a menos que termines el cluster. El almacenamiento se puede configurar con auto-scaling, pero los tamaños y la cantidad de instancias no. En su lugar, tendrás que monitorear continuamente las métricas de CloudWatch de las instancias, cuántas particiones se usan por broker y otros indicadores de rendimiento, y luego escalar el servicio manualmente en respuesta. Por si fuera poco, se "recomienda fuertemente" que el uso de CPU en el cluster se mantenga por debajo del 60%, así que inevitablemente vas a pagar de más por capacidad de cómputo.
Hay una ventaja importante al usar MSK: Kinesis ofrece entrega de mensajes at-least-once, mientras que Kafka garantiza entrega exactly-once. En general, sin embargo, lidiar con la deduplicación de mensajes es mucho más sencillo que enfrentar los desafíos de escalabilidad de infraestructura con buen costo-eficiencia.
Incluso si logras operar con éxito un cluster de MSK a una escala muy alta, optimizado en costo y gestionado para que el despliegue resulte más barato que Kinesis, apuesto a que probablemente seguirías ahorrando más usando Kinesis debido a la reducción en horas-hombre de DevOps (de salario alto) dedicadas a mantener funcionando un servicio pub-sub crítico para el negocio, cuando un equivalente totalmente gestionado lo habría hecho igual de bien con prácticamente cero esfuerzo.
Personalmente solo recomiendo AWS MSK para empresas que tienen una aplicación basada en Kafka existente que, por restricciones de tiempo, costo de refactor o recursos de personal, debe migrarse mediante lift-and-shift sin cambios arquitectónicos.
Si te interesa profundizar, te recomiendo leer este "honest AWS MSK review". Los comentarios del artículo también son muy esclarecedores y se enfocan en ejemplos de Precios de MSK vs. Kinesis.
Spark Streaming con EMR
AWS EMR es la oferta totalmente gestionada y con auto-scaling (pero no serverless) de Amazon que permite la ejecución basada en cluster de scripts escritos para herramientas open-source de procesamiento de big data. Entre estas herramientas se incluye Apache Spark.
Spark habilita analítica basada en DataFrames que puede ejecutarse tanto sobre datasets estáticos como en streaming. Puedes ejecutar analítica sobre DataFrames con llamadas programáticas típicas a funciones, o correr Spark SQL compatible con ANSI SQL. Trabajar con Spark SQL sobre datos en streaming es similar a usar SQL con Apache Flink / Kinesis Data Analytics. Spark puede tomar como fuente de ingesta en streaming monitoreada Apache Kafka y Apache Flume, además de AWS S3 y AWS Kinesis Data Streams.
Dadas las excelentes integraciones nativas de Spark con Streams y S3, así como su baja curva de aprendizaje con PySpark, recomiendo usar Spark Streaming con DataFrames sobre EMR cuando necesites:
- Realizar analítica en tiempo real sobre Kinesis Data Streams o S3, y
- Cuando la escala o complejidad de la analítica supere algunas de las muchas limitaciones de Kinesis Data Analytics.
Lo más crítico que debes saber es que con Data Analytics:
- Ninguna fila de datos puede superar los 512 KB. El límite de Spark es mucho mayor: 2 GB.
- Tu dataset de referencia supera 1 GB de tamaño. Spark no tiene límite.
- Cada aplicación debe tener exactamente una fuente de streaming y como máximo una fuente de datos de referencia. Con Spark puedes unir múltiples fuentes en streaming y múltiples fuentes de datos de referencia estáticos.
- Las consultas con ventanas no deberían superar los 60 minutos, ya que los datos se almacenan en almacenamiento volátil desde el cual se podría reconstruir el stream si hay interrupciones inesperadas de la aplicación. Spark no tiene límite de ventana de tiempo.
Glue Streaming ETL
Glue Streaming es una oferta totalmente gestionada, con auto-scaling y serverless de Spark Streaming DataFrames. Lo usarías si tienes experiencia con Spark y quieres realizar transformaciones y analítica personalizadas sobre datos en streaming desde Kinesis con este servicio en lugar de con un cluster de EMR autogestionado o funciones Lambda. Glue Streaming puede volcar datos a los sinks habituales como S3, Redshift y DynamoDB.
Glue puede, hasta cierto punto, autogenerar código Spark por ti basándose en una lista de transformaciones que solicitas en la consola web, así que no necesariamente se requiere mucha experiencia en Spark, aunque ayuda dominar lo básico.
Personalmente he encontrado que este servicio es algo caprichoso. Aunque "Spark serverless" suene conveniente, viene con algunas limitaciones:
- Cuando se usa detección de esquema, no puedes realizar joins de datos en streaming.
- No puedes cambiar la cantidad de shards de Kinesis Streams mientras se está ejecutando un job de Glue Streaming ETL. Tienes que detener el job, cambiar la cantidad de shards de Data Streams, esperar a que esa operación se complete y luego reiniciar el job.
Solo por la escalabilidad upstream, personalmente preferiría correr un cluster Spark autogestionado con auto-scaling activado en lugar de Glue Streaming ETL, pero en tus pruebas puede que descubras que la naturaleza serverless y con auto-scaling de Glue Streaming ETL pesa más que sus desventajas.
IoT Analytics dentro de IoT Core
Lo que hacen los componentes de IoT Analytics no es tan transparente como debería ser, ¡así que escribí un artículo entero sobre eso! Production-Scale IoT Best Practices: Implementation with AWS (part 2). Cubramos lo básico aquí y dejemos muchos de los detalles para ese artículo.
Los dispositivos IoT que envían datos en streaming a AWS llegan al IoT Core. Desde aquí, esos mensajes pueden enviarse a otros servicios para analítica personalizada. Por ejemplo, con IoT Rules puedes reenviar fácilmente datos del IoT Core a:
- DynamoDB
- Firehose, que luego vuelca datos a DynamoDB, S3, Redshift o Elasticsearch
- Data Streams, que puede enviar datos a EC2, EMR, Lambda o Firehose
Como ves, hay un amplio abanico de flujos de datos IoT que puedes configurar.
Sin embargo, si quieres procesar todos tus datos IoT —desde el streaming hacia tu plataforma pasando por el almacenamiento y la analítica— completamente dentro de una plataforma unificada centrada en IoT que sea totalmente serverless, con auto-scaling y totalmente gestionada, y que tenga múltiples integraciones de analítica con otros servicios de AWS como Sagemaker y Quicksight, ahí es cuando convendría quedarse con IoT Analytics. El IoT Core te permite procesar datos IoT dentro de un único servicio en lugar de armar un mosaico de servicios.
Recorrer el asistente de IoT Analytics configurará lo siguiente:
- Un IoT Channel es donde llegan los datos IoT
- Un IoT Pipeline que toma los datos del Channel y te permite, opcionalmente, enriquecer, transformar y filtrar mensajes según sus atributos
- Un IoT Data Store, donde los datos en streaming se almacenan, ya sea de forma indefinida o por un periodo de tiempo determinado. Detrás de escena, estos datos se guardan en un bucket de S3 gestionado por AWS.
- Un IoT Data Set se puede crear a partir de un Data Store. Es un subconjunto de un IoT Data Store creado con IoT SQL que tiene su propio periodo de retención de datos, así como la capacidad de recrearse a sí mismo bajo demanda o según una programación recurrente. Al igual que los Data Stores, los Data Sets se almacenan como archivos CSV en un bucket gestionado. Los Data Sets implican, en última instancia, que puedes crear un dataset estático basado en un filtro personalizado (por ejemplo, seleccionar todos los datos de temperatura de un periodo acotado pero interesante), generar ese dataset bajo demanda una sola vez y conservarlo indefinidamente para analítica downstream, mientras dejas que los mensajes originales y crudos del data store expiren según un periodo de retención que tu organización considere el balance más eficaz entre retención de datos crudos y costo-eficiencia.
- Algunos servicios de AWS que se integran con IoT Analytics, como Quicksight, solo se nutrirán de data sets, mientras que otros como SageMaker pueden hacerlo tanto de data stores como de data sets. En general, todos los servicios deberían poder consumir data sets. Debido a la conectividad más limitada con los data stores y a las implicaciones de costo de almacenar datos crudos indefinidamente en IoT Analytics, en un caso de uso productivo deberías considerar acostumbrarte a la metodología de crear datasets discretos y filtrados para usar en analítica o generación de modelos de ML, mientras el data store crudo expira con el tiempo, a menos que tu organización considere aceptable pagar por el almacenamiento del historial completo de datos IoT.
¿Qué servicio uso?
En mi intento por explicar de forma concisa las distintas opciones de streaming de AWS, ¡me temo que escribí demasiado! Aquí va un resumen rápido de cuándo elegir cada servicio:
- Kinesis Data Streams: cuando necesitas realizar analítica en tiempo real en EC2, EMR o Lambda y no te importa algo de complejidad adicional de desarrollo ni su incapacidad para escalar throughput rápidamente.
- Kinesis Firehose: cuando necesitas agrupar por lotes datos en streaming, opcionalmente transformarlos o comprimirlos, y colocarlos en almacenamiento a largo plazo en S3, Redshift o Elasticsearch. Cuando quieres una plataforma de ingesta de datos en streaming fácil de usar, serverless y con auto-scaling inmediato y no te molesta que escriba por lotes en vez de enviar mensajes a los consumidores en tiempo real.
- Kinesis Data Analytics: cuando quieres realizar analítica básica con ventanas sobre datos de Data Streams o Firehose, normalmente para alertado en tiempo real, con SQL sobre una plataforma simple, serverless y con auto-scaling.
- Managed Streaming for Apache Kafka (MSK): cuando tienes una aplicación basada en Kafka existente y buscas hacer un lift-and-shift hacia AWS. Las restricciones de tiempo o recursos te impiden rediseñar la aplicación para usar Kinesis.
- Spark Streaming con EMR: cuando necesitas realizar analítica avanzada con ventanas sobre Kinesis Data Streams mediante operaciones JOIN que involucran múltiples fuentes en streaming o datasets de referencia estáticos.
- Glue Streaming ETL: similar a Spark Streaming con EMR, salvo que puedes correr workloads de Spark dentro de un entorno serverless y con auto-scaling. No permite escalar shards upstream de Data Streams sin detener y reiniciar los jobs de streaming de Glue conectados.
- IoT Analytics dentro de IoT Core: una plataforma todo-en-uno de ingesta, almacenamiento y analítica para datos IoT en streaming, totalmente gestionada, serverless y con auto-scaling. El IoT Core te permite evitar tener que armar un mosaico de servicios separados de AWS para lograr la misma funcionalidad.
¡Gracias por leer! Para mantenerte en contacto, síguenos en el DoiT Engineering Blog , el DoiT Linkedin Channel y el DoiT Twitter Channel . Para explorar oportunidades de carrera, visita https://careers.doit-intl.com .