Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Data Streaming sur AWS : trop de choix

By Matthew PorterSep 21, 202117 min read

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

Si vous avez déjà été confronté à un cas d'usage de data streaming dans le cloud, vous avez probablement ouvert plus d'onglets de navigateur que vous n'oseriez l'avouer, à éplucher les différentes options proposées par AWS et leurs FAQ, disons-le, interminables.

Qui a le temps de lire cinquante pages de documentation juste pour savoir quel service choisir ?

Voici une liste des services AWS les plus en vue pour ingérer, transformer, stocker et analyser des données en streaming. Au moment où vous lisez ces lignes, elle ne sera peut-être déjà plus exhaustive :

  • Kinesis Data Streams
  • Kinesis Firehose avec intégration Lambda en option
  • Kinesis Data Analytics
  • Managed Streaming for Apache Kafka (MSK)
  • Spark Streaming avec Elastic MapReduce (EMR)
  • Glue Streaming ETL
  • IoT Analytics au sein d'IoT Core

Si vous êtes frustré ou si vous passez trop de temps à choisir l'option qui vous convient, suivez-moi : je vais lever le voile sur ces zones d'ombre en couvrant les fondamentaux et le cas d'usage idéal de chaque service.

Un récapitulatif rapide des contextes dans lesquels privilégier chaque service est proposé en fin d'article.

Kinesis : le choix par défaut

Le service phare d'Amazon pour le data streaming, et celui à retenir comme choix par défaut pour la plupart des cas d'usage, c'est Kinesis. Kinesis regroupe toutefois toute une série de sous-services aux noms parfois ésotériques. Les plus pertinents sont :

  • Kinesis Data Streams (souvent appelé Streams)
  • Kinesis Firehose (ou simplement Firehose)
  • Kinesis Data Analytics (ou simplement Analytics)

Examinons chacun d'eux en détail.

Kinesis Data Streams vs Kinesis Firehose

Streams vs Firehose : aperçu des fonctionnalités

Data Streams comme Firehose ingèrent des données et les déversent dans un sink. Pourquoi alors deux services différents qui semblent remplir la même fonction ?

La principale différence : Streams est conçu pour envoyer des données vers des services de calcul dotés de consommateurs personnalisés, comme des applications tournant sur EC2, EMR ou Lambda, qui prendront en charge la transformation et le traitement des données en quasi temps réel avec une latence pouvant descendre à environ 70 ms. Streams est donc particulièrement utile pour alimenter des dashboards en temps réel, faire de la détection d'anomalies et d'autres applications sensibles au temps. Streams s'intègre très bien avec Apache Spark, ce qui simplifie la manipulation de données en temps réel via des Data Frames en streaming dès lors que les analyses se complexifient.

Firehose, en revanche, n'est pas pensé pour la livraison en quasi temps réel. Il regroupe les messages entrants par batches, les compresse et/ou les transforme éventuellement avec AWS Lambda, puis les déverse, généralement dans un service AWS — typiquement S3, Redshift ou Elasticsearch.

Si les messages Streams sont en général consommés par des applications personnalisées, vous pouvez aussi configurer Streams pour faire transiter les données vers un flux Firehose, et ainsi cumuler analyses temps réel d'un côté, batching et stockage long terme de l'autre.

Si votre cas d'usage n'exige pas de traitement en quasi temps réel, Firehose sera probablement le choix le plus adapté, et également plus simple à manipuler directement.

Firehose : généralement le meilleur choix

Pourquoi Firehose est-il généralement le choix le plus pertinent entre les deux ?

D'abord : Kinesis Streams demande davantage d'efforts de développement via des programmes écrits avec sa Kinesis Producer Library (KPL) et sa Kinesis Consumer Library (KCL), centrées sur Java. Firehose, à l'inverse, est essentiellement conçu pour déverser des données dans des services AWS spécifiques, ce qui élimine tout effort de codage côté sink. Publier des messages vers Firehose est par ailleurs très simple :

import boto3firehose_client = boto3.client('firehose')
response = firehose_client.put_record(
    DeliveryStreamName='string',
    Record={'Data': b'bytes'} # base64-encoded
)

Si vous acceptez que Kinesis Streams perde probablement en performance côté producteur comme côté consommateur, et que vous renonciez à d'autres avantages, vous pouvez utiliser les SDK AWS pour publier des messages plus simplement, plutôt que de vous lancer dans un développement plus poussé basé sur la KPL :

import boto3kinesis_client = boto3.client('kinesis')
response = kinesis_client.put_record(
    StreamName='string',
    Data=b'bytes', # base64-encoded
    PartitionKey='string'
)

Ensuite : Streams comme Firehose sont entièrement gérés et auto-scalables, mais Streams l'est moins, et n'est pas tout à fait serverless.

L'auto-scaling de Firehose vous permet de monter immédiatement et sans accroc en débit, du test en développement jusqu'à plusieurs Go de données par seconde, à condition de ne pas atteindre les limites AWS de débit Firehose.

La mise à l'échelle de Streams est plus complexe. Bien que vous ne gériez pas directement l'infrastructure sous-jacente, vous devez définir pour un Kinesis Stream un nombre de shards qui détermine son débit pris en charge. Un shard correspond au maximum à 1 Mo/s ou 1 000 enregistrements/s en écriture, et 2 Mo/s en lecture. Il faut donc préprovisionner un certain nombre de shards pour atteindre un niveau de débit donné. Vous pouvez modifier manuellement le nombre de shards d'un stream ou mettre en place un auto-scaling, mais ce dernier processus est plus alambiqué qu'il ne devrait l'être.

Pour atteindre un débit plus élevé, vous augmentez donc le nombre de shards d'un stream. Mais il y a un sérieux bémol : ajouter ou retirer un shard d'un stream prend en moyenne environ 30 secondes, et un seul shard peut être ajouté ou retiré à la fois.

Voyons concrètement l'impact : si vous disposez d'un stream avec 1 000 shards (~1 Gio/s en écriture) et que vous prévoyez un doublement prochain de votre débit, il faudra plus de 8 heures pour mettre à l'échelle votre stream avec 1 000 shards supplémentaires.

Si vous avez des raisons de penser qu'un pic soudain et imprévu de volume de données peut survenir un jour, Kinesis Data Streams ne pourra pas monter en charge assez vite.

Streams n'est donc pas adapté aux cas d'usage à forte variabilité de débit, sauf si vous acceptez de surprovisionner et de surpayer pour ces moments-là, ou si vous êtes confiant dans votre capacité à anticiper les pics et à planifier en conséquence. Firehose est tout simplement plus facile à dimensionner, plus facile à développer et, comme nous le verrons, plus simple à chiffrer. Kinesis Streams ne devrait être utilisé que lorsque des analyses temps réel sont indispensables.

Streams vs Firehose : comparaison de la complexité tarifaire

L'approche serverless et auto-scaling de Firehose se traduit aussi par une tarification à l'usage simple et lisible, basée sur :

  • les Go de données ingérés par mois, et selon les cas :
  • les Go de conversions de format de données effectuées
  • les Go de données livrés vers un VPC

La tarification de Data Streams est plus complexe à anticiper, puisqu'elle repose sur :

  • le nombre d'heures-shards provisionnées, qui peut varier avec l'auto-scaling. Vous devrez probablement surprovisionner pour garantir une disponibilité fiable.
  • le nombre de payloads PUT de 25 Ko envoyés
  • les changements optionnels de rétention des données à long terme
  • l'activation optionnelle de l'enhanced fan-out, une fonctionnalité qui améliore le débit lorsque de nombreux consommateurs lisent depuis un même shard

Streams vs Firehose : récapitulatif

Si votre objectif est d'effectuer des transformations basiques et de charger par batches vos données streaming dans un data store, sans exigence de traitement temps réel, publiez vos données directement vers Firehose. Choisissez aussi Firehose si vous voulez minimiser le temps consacré au développement applicatif ou les contraintes liées à une mise à l'échelle rapide de l'infrastructure.

Si vous devez traiter les données en temps réel, faites-les passer par Streams, en gardant à l'esprit que, même avec l'auto-scaling activé, il pourrait ne pas absorber correctement des hausses brutales de débit.

Si vous avez besoin à la fois de traiter les données en temps réel et de les stocker pour des analyses ultérieures, envoyez-les d'abord vers Streams, puis configurez facilement Streams via la console web Kinesis pour les transmettre à Firehose, sans aucun code (sauf si vous souhaitez exécuter des étapes de transformation optionnelles sur Lambda).

Il peut être utile de voir Streams comme l'équivalent fonctionnel d'Apache Kafka, avec un stockage persistant temporaire des messages pouvant être transmis à de nombreux consommateurs. Ces consommateurs peuvent être des applications personnalisées (EC2 ou EMR), ou des services AWS managés (Firehose). Firehose est souvent utilisé comme chargeur en batch pour des services spécifiques, généralement AWS (S3, Redshift, Elasticsearch), avec des transformations serverless optionnelles via Lambda.

Kinesis Data Analytics : analyses en fenêtre, en mode serverless

Streams et Firehose couvrent assez bien l'ingestion, la transformation et l'acheminement de données streaming vers des applications d'analyse temps réel (Streams) et des stockages long terme (Firehose). Quel est alors le rôle d'Analytics ?

Data Analytics, l'offre Apache Flink entièrement managée et serverless d'Amazon :

  • s'intègre avec Data Streams ou Firehose
  • exécute des requêtes SQL sur les données streamées
  • diffuse les résultats vers un service AWS, comme un autre Data Stream, un flux Firehose ou Lambda
  • Data Analytics peut également traiter des fichiers CSV ou JSON statiques stockés dans S3 comme des tables SQL, ce qui permet des JOIN entre données de référence et données streamées.

Data Analytics sert principalement à calculer en continu des agrégations de données streamées, enrichies de données de référence statiques, sur des fenêtres temporelles — généralement à des fins d'alerting temps réel — sans aucun code ni infrastructure provisionnée, juste du SQL classique. Vous pourriez écrire du code Flink et le déployer à la place du SQL, mais pour la facilité de maintenance, je m'en tiendrais au SQL, Scala et Java étant moins répandus dans le monde de la data science.

La doc AWS présente un exemple d'analyses en fenêtre glissante avec des données boursières, mais je recommanderais plutôt d'étudier cet exemple plus parlant tiré du monde réel, où les vitesses de circulation à travers la Belgique sont ingérées dans un flux Firehose, Data Analytics compare les vitesses actuelles à celles passées à l'aide de données de référence dans S3, la présence d'embouteillages est déterminée en SQL, et des alertes temps réel sont envoyées via Lambda.

Managed Streaming for Apache Kafka (MSK)

Kinesis Data Streams et MSK, l'offre AWS managée pour Apache Kafka, sont tous deux des systèmes pub-sub efficaces, qui permettent de publier et de consommer des messages avec un haut débit, une faible latence, une haute disponibilité et une tolérance aux pannes. En termes globaux de scalabilité et de fiabilité comme plateforme d'ingestion et de livraison de données, il n'y a pas de différence majeure entre les deux, du moins en surface.

Les différences critiques se nichent dans les détails, et elles favorisent généralement Kinesis :

  • Vous ne pouvez qu'augmenter le nombre de brokers de messages. Autrement dit, vous ne pouvez pas réduire un déploiement MSK.
  • MSK est entièrement managé, mais ce n'est pas un Kafka serverless. MSK implique donc une certaine configuration de cluster. Vous devez définir les zones et sous-réseaux dans lesquels lancer vos brokers, le nombre de brokers par zone, le type d'instance qui les fait tourner, etc.
  • MSK n'étant pas serverless, vous payez aussi pour le stockage EBS associé aux instances. Lui non plus ne peut être réduit.
  • Vous ne pouvez pas changer le type d'instance après la configuration initiale du cluster. Pour monter en charge, votre seule option est d'augmenter le nombre d'instances.
  • Kinesis est le service de streaming maison d'AWS, entièrement managé et serverless ; il s'intègre donc naturellement mieux avec les services AWS. Certains consommateurs Kinesis peuvent être branchés sans une ligne de code, alors que MSK exige que toutes les applications consommatrices soient développées sur mesure, par exemple sur EC2, EKS, EMR, ou via du code Flink déployé sur Kinesis Data Analytics.
  • Avec Kafka, un seul consommateur d'un même groupe peut lire à la fois depuis une partition. Kinesis, en revanche, prend en charge plusieurs consommateurs par shard.

La configuration initiale et continue du cluster, combinée à l'impossibilité de réduire les déploiements, fait que MSK génère plus de surcharge DevOps à court et long terme que Kinesis.

La tarification diffère également entre les deux, et là encore Kinesis est généralement avantagé.

Comme évoqué plus haut, la tarification de Kinesis Data Streams est largement à la demande. Elle repose principalement sur le nombre de payloads PUT de 25 Ko envoyés et sur le nombre d'heures-shards provisionnées pour atteindre le débit PUT et GET souhaité. Le nombre de shards peut être configuré en auto-scaling pour simuler une tarification à la demande, même si l'implémentation reste un peu rugueuse.

MSK, à l'inverse, est facturé en fonction du nombre d'instances de la taille choisie qui tournent, ainsi que de la taille des volumes EBS qui les soutiennent. Ni le nombre d'instances, ni la taille des volumes EBS ne peuvent être réduits ; si vous surprovisionnez, vous êtes coincé avec la facture, à moins de terminer le cluster. Le stockage peut être configuré en auto-scaling, mais pas la taille ni le nombre d'instances. Vous devrez en permanence surveiller les métriques CloudWatch des instances, le nombre de partitions par broker et d'autres indicateurs de performance, puis dimensionner le service manuellement en conséquence. Pour couronner le tout, il est fortement recommandé de maintenir l'utilisation CPU du cluster sous 60 %, ce qui vous fera inévitablement surpayer la capacité de calcul.

MSK présente cependant un atout majeur : Kinesis offre une livraison de messages au moins une fois (at-least-once), tandis que Kafka garantit une livraison exactement une fois (exactly-once). Cela dit, dédupliquer des messages reste bien plus simple à gérer que les défis liés à une scalabilité d'infrastructure rentable.

Même en parvenant à exploiter un cluster MSK à très haut débit avec une optimisation des coûts permettant de descendre sous le prix de Kinesis, je parierais que vous économiseriez encore davantage avec Kinesis, du fait des heures DevOps (à fort salaire) en moins consacrées au maintien d'un service pub-sub critique pour le métier, là où un équivalent entièrement managé ferait tout aussi bien sans quasiment aucun effort.

Personnellement, je ne recommande AWS MSK qu'aux entreprises disposant d'une application Kafka existante qui, faute de temps, de budget de refactoring ou de ressources humaines, doit être migrée en lift-and-shift sans modification d'architecture.

Si le sujet vous intéresse, je vous recommande la lecture de cette honest AWS MSK review. Les commentaires de l'article sont également instructifs et se concentrent sur des comparaisons tarifaires entre MSK et Kinesis.

Spark Streaming avec EMR

AWS EMR est l'offre d'Amazon entièrement managée et auto-scalable (mais non serverless) qui permet l'exécution en cluster de scripts écrits pour des outils open source de big data — dont Apache Spark.

Spark permet des analyses basées sur les DataFrames, applicables à des jeux de données statiques comme à des données streamées. Vous pouvez analyser des DataFrames via les appels de fonction programmatiques classiques, ou exécuter du Spark SQL conforme à ANSI SQL. Travailler avec Spark SQL sur des données en streaming s'apparente à utiliser SQL avec Apache Flink / Kinesis Data Analytics. Spark peut prendre comme source d'ingestion en streaming Apache Kafka, Apache Flume, ainsi qu'AWS S3 et AWS Kinesis Data Streams.

Compte tenu des excellentes intégrations natives de Spark avec Streams et S3, et de la courbe d'apprentissage modérée de PySpark, je recommande d'utiliser Spark Streaming avec des DataFrames sur EMR lorsque vous devez :

Les points les plus critiques à connaître sur Data Analytics :

  • Aucune ligne de données ne peut dépasser 512 Ko. La limite de Spark est bien plus élevée : 2 Go.
  • Votre dataset de référence dépasse 1 Go. Spark n'a pas de limite.
  • Chaque application doit avoir exactement une source de streaming et au plus une source de données de référence. Avec Spark, vous pouvez joindre plusieurs sources streaming et plusieurs sources statiques de référence.
  • Les requêtes en fenêtre ne devraient pas dépasser 60 minutes, les données étant stockées dans une mémoire volatile à partir de laquelle le flux peut être reconstruit en cas d'interruption inattendue. Spark n'a aucune limite de fenêtre temporelle.

Glue Streaming ETL

Glue Streaming est une offre Spark Streaming DataFrames entièrement managée, auto-scalable et serverless. Vous l'utiliserez donc si vous avez de l'expérience avec Spark et souhaitez réaliser des transformations et analyses personnalisées sur des données streamées depuis Kinesis avec ce service plutôt qu'avec un cluster EMR auto-géré ou des fonctions Lambda. Glue Streaming peut déverser ses résultats vers les sinks habituels : S3, Redshift, DynamoDB.

Glue peut, dans une certaine mesure, générer automatiquement le code Spark à partir d'une liste de transformations choisies dans la console web. Une vaste expérience Spark n'est donc pas indispensable, même s'il est utile d'en maîtriser les bases.

Personnellement, j'ai trouvé ce service un peu capricieux. Si du Spark serverless paraît séduisant, cela vient avec quelques limites :

  • Lorsque vous utilisez la détection de schéma, vous ne pouvez pas effectuer de jointures sur des données en streaming.
  • Vous ne pouvez pas modifier le nombre de shards d'un Kinesis Stream pendant qu'un job Glue Streaming ETL tourne. Vous devez arrêter le job, modifier le nombre de shards et attendre la fin de l'opération, puis relancer le job.

Pour la seule scalabilité en amont, je choisirais personnellement de faire tourner un cluster Spark auto-géré avec auto-scaling activé plutôt que Glue Streaming ETL. Mais à l'usage, vous pourriez constater que la nature serverless et auto-scalable de Glue Streaming ETL l'emporte sur ses inconvénients.

IoT Analytics au sein d'IoT Core

Le rôle des composants IoT Analytics n'est pas aussi limpide qu'il devrait l'être — j'y ai donc consacré un article entier ! Production-Scale IoT Best Practices: Implementation with AWS (part 2). Voyons ici les bases et laissons les détails à cet article.

Les appareils IoT qui streament vers AWS atterrissent dans IoT Core. De là, ces messages peuvent être envoyés à d'autres services pour des analyses personnalisées. Avec les IoT Rules, par exemple, vous pouvez facilement transmettre les données d'IoT Core vers :

  • DynamoDB
  • Firehose, qui déverse ensuite les données vers DynamoDB, S3, Redshift ou Elasticsearch
  • Data Streams, qui peut transmettre les données à EC2, EMR, Lambda ou Firehose

Vous le voyez : on peut mettre en place un large éventail de flux de données IoT.

Cependant, si vous souhaitez traiter l'ensemble de vos données IoT — du streaming vers votre plateforme jusqu'au stockage et à l'analyse — au sein d'une plateforme unifiée, centrée sur l'IoT, entièrement serverless, auto-scalable et managée, et qui s'intègre nativement à plusieurs services analytiques AWS comme Sagemaker et Quicksight, alors c'est IoT Analytics qu'il vous faut. IoT Core vous permet de traiter vos données IoT au sein d'un seul service, plutôt que d'assembler plusieurs services distincts.

Parcourir l'assistant IoT Analytics met en place les éléments suivants :

  • Un IoT Channel, où arrivent les données IoT
  • Un IoT Pipeline, qui prend les données du Channel et permet, en option, d'enrichir, transformer et filtrer les messages selon leurs attributs
  • Un IoT Data Store, où sont stockées les données streamées, soit indéfiniment, soit pendant une durée définie. En coulisses, ces données sont stockées dans un bucket S3 managé par AWS.
  • Un IoT Data Set peut être créé à partir d'un Data Store. C'est un sous-ensemble d'un IoT Data Store créé via IoT SQL, doté de sa propre durée de rétention et de la capacité de se régénérer à la demande ou selon un planning récurrent. Comme les Data Stores, les Data Sets sont stockés sous forme de fichiers CSV dans un bucket managé. Concrètement, les Data Sets vous permettent de créer un jeu de données statique basé sur un filtre personnalisé (par exemple, sélectionner toutes les données de température sur une plage de temps étroite mais intéressante), de générer ce jeu de données à la demande une seule fois, et de conserver ce dataset filtré indéfiniment pour des analyses en aval, tout en laissant les messages bruts du data store expirer selon une durée de rétention jugée par votre organisation comme l'équilibre le plus efficace entre conservation des données brutes et maîtrise des coûts.
  • Certains services AWS qui s'intègrent à IoT Analytics, comme Quicksight, ne tireront leurs données que des data sets, tandis que d'autres, comme SageMaker, peuvent puiser à la fois dans les data stores et les data sets. De manière générale, tous les services devraient pouvoir s'appuyer sur les data sets. Compte tenu de la connectivité plus limitée avec les data stores et des coûts d'un stockage indéfini de données brutes dans IoT Analytics, en production, vous devriez vous habituer à créer des datasets discrets et filtrés à utiliser dans vos analyses ou la génération de modèles ML, en laissant le data store brut expirer dans le temps — sauf si votre organisation accepte de payer pour conserver l'historique complet des données IoT.

Quel service utiliser ?

À force de vouloir expliquer de manière concise les différentes options de streaming AWS, je crains d'en avoir trop écrit ! Voici un récapitulatif rapide pour choisir un service :

  • Kinesis Data Streams : lorsque vous avez besoin d'effectuer des analyses temps réel sur EC2, EMR ou Lambda et que vous acceptez une certaine complexité de développement supplémentaire et son incapacité à monter rapidement en débit.
  • Kinesis Firehose : lorsque vous devez regrouper des données streaming par batches, éventuellement les transformer et/ou les compresser, et les placer dans un stockage long terme sur S3, Redshift ou Elasticsearch. Lorsque vous souhaitez une plateforme d'ingestion streaming simple à utiliser, serverless et auto-scalable immédiatement, et que l'écriture par batches plutôt qu'une livraison temps réel aux consommateurs ne vous pose pas de problème.
  • Kinesis Data Analytics : lorsque vous voulez réaliser des analyses en fenêtre basiques sur des données Data Streams ou Firehose, généralement pour de l'alerting temps réel, en SQL, sur une plateforme simple, serverless et auto-scalable.
  • Managed Streaming for Apache Kafka (MSK) : lorsque vous disposez d'une application existante basée sur Kafka et que vous souhaitez la migrer en lift-and-shift sur AWS. Le temps ou les ressources vous empêchent de redessiner l'application pour utiliser Kinesis.
  • Spark Streaming avec EMR : lorsque vous devez réaliser des analyses en fenêtre avancées sur Kinesis Data Streams via des opérations JOIN impliquant plusieurs sources streaming et/ou des datasets de référence statiques.
  • Glue Streaming ETL : similaire à Spark Streaming avec EMR, à ceci près que vous pouvez exécuter des workloads Spark dans un environnement serverless et auto-scalable. Ne permet pas de modifier le nombre de shards de Data Streams en amont sans arrêter et relancer les jobs Glue streaming connectés.
  • IoT Analytics au sein d'IoT Core : une plateforme tout-en-un d'ingestion, de stockage et d'analyse pour les données IoT en streaming, entièrement managée, serverless et auto-scalable. IoT Core vous évite d'assembler plusieurs services AWS distincts pour obtenir les mêmes fonctionnalités.

Merci de votre lecture ! Pour rester connecté, suivez-nous sur le DoiT Engineering Blog , le DoiT Linkedin Channel , et le DoiT Twitter Channel . Pour découvrir les opportunités de carrière, rendez-vous sur https://careers.doit-intl.com .