Ce blog a été co-écrit avec Shradha Ambekar, ingénieur logiciel chez Intuit et Ariel Weisberg, ingénieur logiciel chez Facebook.
Aperçu
Presto a été conçu à l’origine pour exécuter des requêtes interactives sur des entrepôts de données, mais il a maintenant évolué vers un moteur SQL unifié au-dessus des analyses de lac de données ouvertes pour les charges de travail interactives et par lots. Les charges de travail courantes sur les lacs de données incluent :
1. Rapports et tableaux de bord
Cela inclut la fourniture de rapports personnalisés aux développeurs internes et externes pour des informations commerciales, ainsi qu’à de nombreuses organisations utilisant Presto pour des analyses de test A/B interactives. Une caractéristique déterminante de ce cas d’utilisation est l’exigence d’une faible latence. Cela nécessite des dizaines à des centaines de millisecondes à un QPS très élevé, et il n’est pas surprenant que ce cas d’utilisation utilise presque exclusivement Presto et c’est pour cela que Presto est conçu.
2. Science des données avec les blocs-notes SQL
Ce cas d’utilisation est un cas d’analyse ad hoc et nécessite généralement une latence modérée allant de quelques secondes à quelques minutes. Ce sont les requêtes des scientifiques des données et des analystes commerciaux qui souhaitent effectuer une analyse ad hoc compacte pour comprendre l’utilisation du produit, par exemple, les tendances des utilisateurs et la manière d’améliorer le produit. Le QPS est relativement inférieur car les utilisateurs doivent lancer manuellement ces requêtes.
3. Traitement par lots pour les grands pipelines de données
Il s’agit de tâches planifiées qui s’exécutent tous les jours, toutes les heures ou chaque fois que les données sont prêtes. Ils contiennent souvent des requêtes sur de très gros volumes de données et la latence peut aller jusqu’à des dizaines d’heures et le traitement peut aller de jours CPU à des années et de téraoctets à pétaoctets de données.
Presto fonctionne aujourd’hui de manière exceptionnellement efficace pour les requêtes ad-hoc ou interactives, et même pour certaines requêtes par lots, avec la contrainte que toute la requête doit tenir en mémoire et s’exécuter suffisamment rapidement pour que la tolérance aux pannes ne soit pas requise. La plupart des charges de travail par lots ETL qui ne rentrent pas dans cette case s’exécutent sur des moteurs de calcul de « très grandes données » comme Apache Spark. Le fait d’avoir plusieurs moteurs de calcul avec différents dialectes SQL et API complique la gestion et la mise à l’échelle de ces charges de travail pour les équipes de plateforme de données. Par conséquent, Facebook a décidé de simplifier et de construire Presto sur Spark comme moyen de faire évoluer Presto. Avant d’entrer dans Presto sur Spark, laissez-moi vous expliquer un peu plus l’architecture de chacun de ces deux moteurs populaires.
L’architecture de Presto
Presto est conçu pour une faible latence et suit l’architecture MPP classique ; il utilise le flux aléatoire en mémoire pour obtenir une faible latence. Presto a un seul coordinateur partagé par cluster avec un pool de travailleurs associé. Presto essaie de planifier autant de requêtes que possible sur le même travailleur Presto (exécuteur partagé), afin de prendre en charge la multi-location.
Cette architecture fournit une planification des tâches à très faible latence et permet le traitement simultané de plusieurs étapes d’une requête, mais le compromis est que le coordinateur est un SPOF et un goulot d’étranglement, et les requêtes sont mal isolées dans l’ensemble du cluster.
De plus, le streaming shuffle ne permet pas une grande tolérance aux pannes, ce qui a un impact supplémentaire sur la fiabilité des requêtes de longue durée.
L’architecture de Spark
D’autre part, Apache Spark est conçu pour l’évolutivité dès le début et il implémente une architecture Map-Reduce. Shuffle est entièrement matérialisé sur le disque entre les étapes d’exécution avec la possibilité de préempter ou de redémarrer n’importe quelle tâche. Spark maintient un pilote isolé pour coordonner chaque requête et exécute des tâches dans des conteneurs isolés planifiés à la demande. Ces différences améliorent la fiabilité et réduisent les frais généraux d’exploitation.
Pourquoi Presto seul n’est-il pas adapté aux charges de travail par lots ?
La mise à l’échelle d’une base de données d’architecture MPP pour le traitement de données par lots sur des ensembles de données à l’échelle d’Internet est connue pour être un problème extrêmement difficile [1]. Pour simplifier cela, examinons la requête d’agrégation ci-dessous. Essentiellement, cette requête passe en revue la table des commandes dans TPCH et effectue le regroupement d’agrégats sur des clés personnalisées et additionne le prix total. Presto exploite la lecture aléatoire en mémoire et exécute la lecture aléatoire sur la clé personnalisée, après avoir lu les données et effectué l’agrégation pour la même clé, sur chaque travailleur.
Faire du brassage en mémoire signifie que le producteur mettra en mémoire tampon les données et attendra que les données soient récupérées par le consommateur en conséquence. Nous devons exécuter toutes les tâches, avant et après l’échange en même temps. Donc, en pensant au monde mapreduce, tous les mappeurs et le réducteur doivent être exécutés simultanément. Cela fait du mélange en mémoire un modèle d’exclusion tout ou rien.
Cela entraîne une planification inflexible et la mise à l’échelle de la taille des requêtes devient plus difficile car tout s’exécute simultanément. Dans la phase d’agrégation, la requête peut dépasser la limite de mémoire car tout doit être conservé en mémoire dans des tables de hachage afin de suivre chaque groupe (clé client).
De plus, nous sommes limités par la taille d’un cluster dans le nombre de nœuds sur lesquels nous pouvons partitionner les données par hachage pour éviter d’avoir à tout mettre en mémoire. En utilisant un disque distribué (Presto-on-Spark, Presto Unlimited), nous pouvons partitionner davantage les données et ne sommes limités que par le nombre de fichiers ouverts et même c’est une limite qui peut être considérablement augmentée par un service de lecture aléatoire.
Pour cette raison, il est difficile d’adapter Presto à des pipelines par lots très volumineux et complexes. De tels pipelines restent en cours d’exécution pendant des heures, tous pour se joindre et agréger sur une énorme quantité de données. Cela a motivé le développement de Presto Unlimited qui adapte la conception MPP de Presto aux charges de travail ETL volumineuses et améliore l’expérience utilisateur à grande échelle.
Alors que Presto Unlimited a résolu une partie du problème en autorisant le partitionnement du shuffle sur un disque distribué, il n’a pas totalement résolu la tolérance aux pannes et n’a rien fait pour améliorer l’isolation et la gestion des ressources.
Bientôt sur Spark
Presto sur Spark est une intégration entre Presto et Spark qui exploite le compilateur/l’évaluation de Presto en tant que bibliothèque avec l’API RDD de Spark utilisée pour gérer l’exécution de l’évaluation intégrée de Presto. Ceci est similaire à la façon dont Google a choisi d’intégrer la requête F1 dans son framework MapReduce.
L’objectif de haut niveau est d’apporter un remaniement entièrement désagrégé au temps d’exécution du MPP de Presto et nous y sommes parvenus en ajoutant une étape de matérialisation juste après le remaniement. Le shuffle matérialisé est modélisé comme une table de partition temporaire, ce qui apporte une exécution plus flexible après le shuffle et permet de partitionner les nouvelles tentatives. Avec Presto sur Spark, nous pouvons effectuer un mélange entièrement désagrégé sur les clés personnalisées pour la requête ci-dessus à la fois du côté du mappeur et du réducteur, cela signifie que tous les mappeurs et réducteurs peuvent être programmés indépendamment et peuvent être réessayés indépendamment.
Presto sur Spark chez Intuit
Superglue est un outil développé par Intuit qui aide les utilisateurs à créer, gérer et surveiller des pipelines de données. Superglue a été conçu pour démocratiser les données pour les analystes et les data scientists. Superglue minimise le temps consacré au développement et au débogage des pipelines de données, et maximise le temps consacré à la création d’informations commerciales et à l’IA/ML.
De nombreux analystes d’Intuit utilisent Presto (AWS Athena) pour explorer les données dans le Data Lake/S3. Ces analystes passeraient plusieurs heures à convertir ces SQL d’exploration écrits pour Presto en Spark SQL afin de les opérationnaliser/planifier en tant que pipelines de données dans Superglue. Pour minimiser les problèmes de conversion du dialecte SQL et la perte de productivité associée pour les analystes, l’équipe d’Intuit a commencé à explorer diverses options, notamment la traduction des requêtes, la virtualisation des requêtes et presto on Spark. Après un rapide POC, Intuit a décidé d’opter pour Presto sur Spark car il exploite le compilateur/l’évaluation de Presto en tant que bibliothèque (aucune conversion de requête n’est requise) et les capacités de traitement de données évolutives de Spark.
Presto sur Spark est maintenant en production chez Intuit. En trois mois, il existe des centaines de pipelines critiques qui exécutent des milliers de tâches sur Presto On Spark via Superglue.
Presto sur Spark s’exécute en tant que bibliothèque soumise avec spark-submit ou Jar Task sur le cluster Spark. Des pipelines de données par lots planifiés sont lancés sur des clusters éphémères pour tirer parti de l’isolement des ressources, gérer les coûts et minimiser les frais généraux d’exploitation. Les instructions DDL sont exécutées sur Hive et les instructions DML sont exécutées sur Presto. Cela permet aux analystes d’écrire du DDL compatible Hive et l’expérience utilisateur reste inchangée.
Cette solution a permis de créer une plate-forme performante et évolutive avec expérience de bout en bout transparente pour les analystes d’explorer et de traiter les données. Il a ainsi amélioré la productivité des analystes et leur a permis de fournir des informations à grande vitesse.
Quand utiliser le moteur d’exécution de Spark avec Presto
Spark est l’outil de choix dans l’industrie pour l’exécution de pipelines ETL par lots complexes à grande échelle. Presto sur Spark profite grandement aux pipelines écrits dans Presto qui fonctionnent sur des téraoctets/pétaoctets de données, car il tire parti des capacités de traitement à grande échelle de Spark. Le plus gros avantage ici est qu’aucune conversion de requête n’est requise et vous pouvez tirer parti de Spark pour
- Évolutivité vers des volumes de données plus importants
- Mise à l’échelle de la gestion des ressources de Presto vers des clusters plus importants
- Augmenter la fiabilité et l’élasticité de Presto en tant que moteur de calcul
Pourquoi « Presto sur Spark » est important
Nous avons essayé d’atteindre les objectifs suivants pour adapter « Presto sur Spark » aux charges de travail par lots à l’échelle d’Internet [2]:
- Mélanges entièrement désagrégés
- Exécuteurs isolés
- Gestion des ressources Presto, Scheduler différent, Exécution spéculative, etc.
Une option unifiée pour le traitement des données par lots et ad hoc est très importante pour créer l’expérience de requêtes qui évoluent au lieu d’échouer sans nécessiter de réécritures entre différents dialectes SQL. Nous pensons que ce n’est que une première étape vers plus de confluence entre les communautés Spark et Presto, et une étape majeure vers l’activation d’une expérience SQL unifiée entre les cas d’utilisation interactifs et batch. Aujourd’hui, de nombreux géants de l’Internet comme Facebook, etc. sont passés à Presto sur Spark et nous avons vu de nombreuses organisations, dont Intuit, commencer à exécuter leurs pipelines de données complexes en production avec Presto sur Spark.
« Presto on Spark » est l’un des domaines de développement les plus actifs de Presto, n’hésitez pas à le vérifier et à lui donner une étoile. Si vous avez des questions, n’hésitez pas à les poser sur le canal PrestoDB Slack.
Référence
[1] MapReduce : traitement de données simplifié sur de grands clusters [2] Presto-on-Spark : l’histoire de deux moteurs de calcul