J'ai toujours eu un excellent contact avec les bases de données relationnelles et plus tard avec les systèmes distribués comme Spark. Dans un premier temps, j'ai approfondi le SGBD, à la fois pour mettre en place des requêtes complexes, l'administration et surtout comment mettre en place un script performatif pour le SGBD. Lorsque j'ai commencé à travailler davantage avec Spark et plus tard avec Databricks, au départ je n'avais pas de problèmes de performances pour les scénarios que je devais créer, mais à mesure que le domaine du bigdata devenait vraiment du bigdata, j'ai commencé à avoir des problèmes de performances dans les routines qui augmentaient de 30 % chaque semaine et cela m'a fait chercher comment Spark fonctionne « sous le capot », principalement parce que je savais déjà comment fonctionnait un SGBD et cela m'a aidé à comprendre certains concepts que j'apporterai ici.
Soyons brefs car je souhaite que cet article se concentre sur les scénarios, les techniques et les meilleures pratiques d'analyse des performances.
Ce composant est la base de Spark, il est responsable de la gestion de la mémoire, des tâches, de la reprise après incident, de la gestion des E/S, autrement dit, il manipule le RDD. C'est donc un gars qui possède une grande partie du cluster.
Ce composant est le véritable travailleur de l'écosystème spark (cluster), c'est celui qui reçoit les ordres d'écriture ou de lecture (tâches), qui peuvent être sur disque, en mémoire ou les deux (j'expliquerai plus tard pourquoi cela entre en jeu jouer). scénarios de performance).
Les travailleurs sont littéralement ce qu'ils sont pour ceux qui sont déjà familiers avec l'informatique distribuée, ce sont les nœuds du cluster, c'est donc ce qui « héberge » les exécuteurs que j'ai mentionnés ci-dessus, chaque travailleur peut contenir un ou plusieurs exécuteurs. Il est chargé de gérer les ressources allouées aux exécuteurs testamentaires, comme si l'exécuteur testamentaire était un assistant et l'ouvrier un magasinier. Et s'il était l'entrepôt dont il relève ?
C'est le manager, il gère les ressources (Mémoire et CPU) pour les travailleurs, c'est lui qui décide du nombre d'exécuteurs pour chaque application et de la quantité de ressources qui sera allouée, il gère les tâches envoyées par son ' boss' que j'expliquerai plus loin, et comme il s'agit d'un poste de responsabilité plus élevé, il surveille également l'état du cluster pour se remettre des pannes, en redistribuant les tâches si nécessaire. (REMARQUE : il existe plusieurs types de gestionnaires de cluster : Yarn, mesos, kubernetes et le plus simple qui est autonome).
Eh bien, c'est le patron ou la passerelle, je dis passerelle car toute application Spark va passer par elle, c'est ce qui permet à l'application d'interagir avec le cluster, c'est à dire les Workers et les exécuteurs, c'est lui qui permet et gère tâches entre les travailleurs et gère ainsi l'ensemble de l'application en termes de configuration, de nombre d'exécuteurs et de ressources telles que la mémoire. Avez-vous besoin de savoir comment les tâches sont exécutées ? parlez à ce patron ici.
Donc, de manière illustrative :
Lorsque je travaillais du côté de la banque relationnelle et qu'il y avait des problèmes de performances, principalement au niveau des procédures ou des fonctions ou d'une requête dans une application, j'ai analysé les aspects suivants :
Eh bien, je pense que c'est tout, maintenant qu'est-ce que ces points ont en commun avec Apache Spark ?
Pour résumer ce qu'est chacun, malgré le nom, vous pouvez déjà vous faire une idée :
Plan logique :
Représente la requête d'origine sous la forme d'une série d'opérations logiques. Il s’agit de la forme abstraite de la requête, sans tenir compte de la manière dont elle sera réellement exécutée. Comprend des informations sur les opérations qui seront effectuées, telles que le filtrage, la sélection, la jointure, l'agrégation et les mauvaises « petites choses » aussi mdr.
Plan physique :
Détaille comment Spark exécutera réellement la requête. Cela inclut l'ordre des opérations et les algorithmes qui seront utilisés (comme les algorithmes du SGBD). Il peut inclure des détails sur la façon dont les données seront partitionnées et distribuées entre les exécuteurs testamentaires.
Stratégies d'exécution :
Le plan physique peut afficher différentes stratégies d'exécution que Spark peut utiliser, telles que « Broadcast Join » ou « Shuffle Hash Join », en fonction de l'opération et de la taille des données. Je vais également vous expliquer les principaux algorithmes du plan d'exécution, calmez-vous...
Coût estimé :
Bien qu'ils ne soient pas toujours affichés, certains plans peuvent inclure des estimations de coûts pour différentes parties du plan, vous aidant ainsi à comprendre quelle partie du traitement peut être la plus coûteuse.
Nous avons le formulaire 'racine' qui serait textuel, en utilisant la commande expliquer() et il aura une sortie similaire à celle ci-dessous montrant un simple filtre et un dataframe :
== Plan Physique ==
*(2) Filtre (Valeur > 1)
- *(2) Projet [Nom#0, Valeur#1]
- *(1) Analyser le RDD existant[Nom#0, Valeur#1]
Et objectivement, on peut l'analyser via l'interface, via l'UI Spark, dans Databricks on peut y accéder, que ce soit dans les exécutions de cellules, dans le job ou dans le cluster. Dans Apache Spark c'est directement l'IP sur le port par défaut 4040.
Spark UI est divisé en plusieurs sections utiles :
Tâches : affiche une liste de toutes les tâches exécutées dans l'application. Chaque job correspond à une action dans votre code.
Étapes : Affiche les étapes qui composent chaque tâche. Les étapes sont des subdivisions de travail qui peuvent être effectuées en parallèle.
Tâches : détaille les tâches individuelles au sein de chaque étape, y compris des informations sur le temps et l'état d'exécution des tâches.
Stockage : fournit des informations sur l'utilisation de la mémoire et du stockage des RDD (Resilient Distributed Datasets).
Environnement : affiche les propriétés de l'environnement d'exécution, y compris les configurations Spark et les variables système.
Exécuteurs : affiche des informations sur les exécuteurs créés pour l'application, y compris l'utilisation de la mémoire, l'utilisation du disque et les statistiques de performances.
Ici, j'étais hiérarchique, d'accord ? C'est l'ordre dans lequel les choses fonctionnent.
Je veux que les images soient mises à l'écran !!
Tout d'abord, j'expliquerai les principaux algorithmes qui sont démontrés à la fois dans l'interface Spark UI et dans le plan d'exécution, qu'il s'agisse du plan logique ou physique :
REMARQUE : N'oubliez pas que les ensembles de données sont ici les mêmes qu'une table Spark ;)
1. Commençons par le Scan le plus connu :
2. Rejoignez (Celui-ci donne du B.O) :
Broadcast Hash Join : utilisé lorsqu'un des ensembles de données est suffisamment petit pour être transmis à tous les nœuds du cluster, évitant ainsi Shuffle (j'expliquerai plus à ce sujet, mais en bref, c'est une opération de brassage de données pour jointure finale).
Shuffle Hash Join : les deux ensembles de données (les tables si vous préférez) sont mélangés afin que les clés correspondantes soient dans la même partition. Il est utilisé lorsque les ensembles de données sont volumineux et ne peuvent pas être transmis à d'autres nœuds.
Trier la jointure par fusion : nécessite que les deux ensembles de données soient triés avant la jointure. Il est efficace pour les grands ensembles de données déjà partitionnés et ordonnés, c'est-à-dire que la jointure est effectuée par colonnes partitionnées et également ordonnées (par exemple df.write.partitionBy("coluna1").sortBy("coluna2").parquet(" chemin /vers/enregistrer/partitionné")
3. Agrégation (somme, décompte, regrouper par etc...) :
HashAggregate : utilise une table de hachage pour agréger les données. Il est efficace pour les grands ensembles de données qui tiennent en mémoire.
TrierAggregate. Agrége les données après les avoir triées. Il est utilisé lorsque les données ne tiennent pas en mémoire.
4. Shuffle (Attention à ce type) :
5. Échange :
6. Projet :
7. Filtre :
8. Trier :
Tous ces algorithmes ci-dessus peuvent être observés comme je l'ai dit précédemment via la commande expliquer().
1. Rejoindre et opérations GroupBy
Des opérations telles que join() et groupByKey() déclenchent souvent un shuffle, qui redistribue les données entre les partitions. Cela peut entraîner :
Utilisation élevée des E/S disque : Shuffle génère de nombreux fichiers intermédiaires, qui peuvent saturer le disque local des exécuteurs.
Charge réseau élevée : La quantité de données transférées entre les exécuteurs peut être importante, en fonction du nombre de connexions requises (nombre de mappeurs multiplié par le nombre de réducteurs)
Atténuation
Mélanger les métriques dans Spark UI :
Comment fonctionne le mélange et pourquoi il est coûteux :
La grande majorité travaille avec des notebooks en raison de la grande popularité de Databricks, Jupyter notebook et Google Colab. Par conséquent, divisez chaque requête ou transformation en cellules distinctes, cela permet d'identifier plus facilement quelle partie pose problème de performances. En mettant tout ensemble, il y a plusieurs travaux et il est difficile de savoir à quelle étape en est.
Utilisez Fusion au lieu d'Écraser, je sais que c'est plus de travail, mais c'est plus logique et plus performant, car La fusion utilisera moins d'E/S qu'un écrasement de « vidage » de la table entière à nouveau dans le lac de données.
Utilisez cache() ou persist() pour stocker les données intermédiaires en mémoire, surtout si elles seront réutilisées lors de plusieurs opérations. Cela peut réduire le temps de recalcul et améliorer les performances.
Au cas où vous ne le sauriez pas, Spark fonctionne sur une JVM donc c'est nativement Java, lorsque vous créez le fameux UDF - User Definition Function avec Python vous laissez une sorte de "boîte noire" pour Spark, empêchant optimisations automatiques. Dans la mesure du possible, utilisez les fonctions Spark SQL intégrées, optimisées pour les performances.
Eh bien, je pense avoir écrit tout ce que j'avais en tête, j'aime écrire des articles car cela m'aide à me souvenir de certains scénarios. J'ai l'intention d'enregistrer une vidéo montrant tout cela, en pratique avec quelques données publiques, je l'aurai probablement sur Kaggle alors suivez-moi sur LinkedIn pour suivre tout ce qui touche au monde de la donnée, de l'intelligence artificielle et du développement logiciel
--> https://www.linkedin.com/in/airton-lira-junior-6b81a661
Suivez-moi sur LinkedIn, donnez-moi un coup de pouce, j'aime les retours et je suis également totalement ouvert à l'amélioration du partage des connaissances.
Si vous avez lu jusqu'ici, félicitations !!! J'espère que cela résoudra tous les problèmes de performances. Dans le prochain article, j'aborderai les avantages de Databricks, alors suivez-moi sur LinkedIn pour le découvrir. Merci !!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!