[JAVA] Fatigué de gérer des requêtes SQL complexes! C'est au tour de Spark

Premier Spark SQL

Il est difficile de dire ce qu'est Apache Spark en un mot, mais cet article décrit Spark (probablement la fonctionnalité la plus importante) ** Spark SQL **. Si vous ne le savez pas, vous ne pourrez pas comprendre les autres parties de Spark, et Spark SQL à lui seul dispose d'une très large gamme d'applications dans des applications du monde réel.

Quand utiliser

C'est le but de Spark SQL en quelques mots.

En utilisant plusieurs données tabulaires comme matériaux, traitez et agrégez et sortez différentes données tabulaires

Par exemple

S'il s'agit des données de vente du magasin →
Représentation graphique de la différence entre les ventes par date ou par produit,
Si vous exécutez un site Web →
Quel type de mot-clé de recherche le visiteur a-t-il entré, quel type de transition de page a chaque visite et quel type de transition de page a / n'a pas atteint?
Pour le développement logiciel →
Regroupez la manière dont le nombre d'exécutions de test et le nombre d'échecs ont changé,

Il y a plusieurs choses. Je pense que chaque entreprise le fait, même si elle a des compétences dans la méthode.

Eh bien, lorsque les données sont petites, ** Excel ou Google Spreadsheet suffit **, mais à mesure que la taille augmente, cela devient progressivement ingérable.

S'il s'agit d'un système ancien et énorme, ce sera une catégorie de traitement appelée "traitement par lots", mais ce genre de chose donne envie de changer de manière flexible le mode de traitement des données. Je pense que c'est une histoire commune d'essayer de diviser ce que vous regardiez simplement par date par heure de la journée ou de prendre la météo en considération.

De plus, il arrive souvent que le traitement soit ** multi-étapes **. Il s'agit d'un modèle tel que la création de données quotidiennes à partir de données de vente détaillées, leur traitement en données mensuelles et enfin la création d'un graphique par rapport au même mois de l'année précédente.

Bien qu'il s'agisse d'un diagramme en images, il semble que le traitement des données soit en plusieurs étapes.

DataFlow.jpg

La bonne chose à propos de Spark

Maintenant, quand j'ai besoin de ce type de traitement de données et que la taille des données est trop grande pour qu'Excel puisse suivre, j'en suis venu à croire en Spark. Surtout si le processus actuel s'applique ensuite.

Ensuite, je vais vous expliquer un peu plus en détail.

Si vous le faites de force avec SQL

C'est un cas où les données cibles sont sorties en utilisant pleinement SQL VIEW, JOIN, GROUP BY et les soi-disant procédures stockées. Je pense que tout le monde est conscient de la faible maintenabilité dans ce cas.

SELECT
  C.CustomerID, C.CustomerName,
  C.CustomerType, C.Address1, C.City,
  C.State, S.TotalSales
FROM
  Customers C
INNER JOIN
  (SELECT CustomerID, SUM(Sales) as TotalSales FROM Sales GROUP BY CustomerID) S
ON
  C.CustomerID = S.CustomerID

Ce niveau est facile à trouver sur le Web, mais je suis sûr qu'il existe d'innombrables SQL plus horribles. De plus, comme je veux changer la façon dont les données sont coupées, il y a de nombreux cas où je finis souvent par maintenir un SQL aussi étrange. Je vous serais reconnaissant de bien vouloir commenter si vous estimez que ce n’est plus possible de le maintenir.

Par rapport à SQL, Spark présente ces avantages.

Lorsque les données sont récupérées par SQL puis agrégées par un programme normal

Je pense que c'est aussi un modèle courant. C'est un type qui récupère doucement les données avec un SQL très simple, puis effectue des boucles pour récupérer les données et utilise pleinement ʻArray, HashMap`, etc. pour les agréger. Une simple agrégation convient, mais cette méthode augmente également la consommation de mémoire et le temps d'exécution à mesure que la quantité de données augmente, et un flux d'analyse compliqué (il existe de nombreuses données intermédiaires dans la figure ci-dessus et les branches de flux). S'il y a plusieurs données finales), le code sera compliqué.

Dans le cas de Spark, la répartition de la charge est facile car ** les clusters peuvent être formés ** assez facilement. Bien sûr, il est impossible d'agréger des données qui nécessitent essentiellement de voir toutes les données, mais si vous comprenez les habitudes, c'est un gros point que vous pouvez prendre en charge les clusters de la même manière que lors du développement et des tests avec un seul nœud.

En tant qu'image,

C'est un flux. C'est très utile pour la table JOIN.

Langues utilisables

Scala semble être l'implémentation originale de Spark,

Est disponible. Est-ce Java ou Python en termes d'affinité avec les applications générales?

Exemple de requête

Avec Spark SQL, vous pouvez facilement écrire du code agrégé comme si vous vous concentriez sur des mots-clés et des fonctions SQL. Voici un exemple qui supprime rapidement ** «Spark SQL-like suinting out» ** en Java. Veuillez lire tout en imaginant quel type de style de codage il s'agira.

withColumn

withColumn crée dynamiquement une nouvelle colonne en utilisant les données d'une colonne existante. Cela crée une nouvelle colonne, datetime, qui est une chaîne de millisecondes de temps entiers dans la colonne timestamp au format yyyy-MM-dd HH: mm: ss.

python


        data = data.withColumn("datetime", date_format(
            col("timestamp")
                .divide(1000)
                .cast(DataTypes.TimestampType), "yyyy-MM-dd HH:mm:ss")
        ));

groupBy

groupBy divise l'enregistrement cible en groupes avec la même valeur de clé et s'agrège au sein de ce groupe pour créer une nouvelle table, similaire à celle de SQL.

Cela regroupe tous les enregistrements avec la même colonne name

Pour créer une nouvelle table.

python


            Dataset<Row> data = data.groupBy("name").agg(
                        sum("score").as("totalScore"),
                        avg("duration").as("durationAvg"),
                        stddev("duration").as("durationStddev"),
                        count("*").as("count"));

De cette façon, un traitement commun peut être effectué avec celui fourni par Spark, et s'il n'est pas à temps, vous pouvez écrire le traitement avec la puissance de Java.

Ne serait-ce pas mieux que d'essayer de maintenir le douloureux SQL?

Si vous écrivez en Java de cette manière, le JAR après la construction sera déployé dans le cluster et le traitement distribué sera possible! Ou, bien sûr, vous ne pouvez payer les frais que lorsque vous les mettez sur AWS Lambda et effectuez le processus d'agrégation.

RDD et ensemble de données

C'est là qu'il est facile de trébucher lors de l'apprentissage de Spark SQL. Les deux sont des classes pour gérer d'énormes données de table "comme", et je ne suis pas sûr au début de ce qui est différent (j'étais le même), mais gardez à l'esprit:

Si vous recherchez des informations relatives à Spark, vous verrez souvent DataFrame, qui est un alias pour Dataset \ <Row >. Row est une classe qui peut être utilisée pour les données de ligne à usage général sans spécifier de type.

Relation avec Hadoop

Hadoop est à l'origine de ce type de cadre de traitement distribué plutôt que Spark, et Spark utilise également le système de fichiers Hadoop en arrière-plan. Cependant, alors que Hadoop continue tout en enregistrant le résultat sur le disque pour chaque série de traitement, dans le cas de Spark, les données ne sont en mémoire qu'à moins d'être explicitement enregistrées, donc si vous enregistrez uniquement les données intermédiaires vraiment importantes pendant le traitement Vous pouvez gagner beaucoup de vitesse rien qu'en le faisant. Cependant, il peut ne pas être possible pour Spark d'analyser une énorme quantité de données qui ne peuvent pas être surmontées même si la mémoire totale de tous les nœuds du cluster est totalisée.

Mauvais endroit

J'ai seulement fait l'éloge de Spark jusqu'à présent, mais bien sûr, il y a des choses qui ne fonctionnent pas. Le plus ennuyeux est que le message d'erreur n'est pas convivial, particulièrement vulnérable aux erreurs de type (essayer de le lire comme int mais les données réelles étaient des chaînes, etc.). Dans un tel cas, soyez prudent car vous obtiendrez un message d'erreur douteux auquel vous ne pouvez pas penser avec bon sens.

Ceci est un exemple de message d'erreur lorsque vous faites une légère erreur dans le type. Vous générez un code source appelé generated.java et le compilez ... Je n'ai pas l'intention d'écrire un processus qui nécessite une technique aussi compliquée, mais je pense qu'il y a une raison.

python


Caused by: org.codehaus.commons.compiler.CompileException: File 'generated.java', Line 562, Column 35: 
failed to compile: org.codehaus.commons.compiler.CompileException: File 'generated.java', Line 562, Column 35:
A method named "toString" is not declared in any enclosing class nor any supertype, nor through a static import at
 org.apache.spark.sql.catalyst.expressions.codegen.CodeGenerator$.org$apache$spark$sql$catalyst$expressions$codegen$CodeGenerator$$doCompile(CodeGenerator.scala:1304) at 
org.apache.spark.sql.catalyst.expressions.codegen.CodeGenerator$$anon$1.load(CodeGenerator.scala:1376) at 
org.apache.spark.sql.catalyst.expressions.codegen.CodeGenerator$$anon$1.load(CodeGenerator.scala:1373) at 
org.spark_project.guava.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3599) at

Avant de m'y habituer, j'ai tendance à penser que "Spark qui ne peut pas donner un message d'erreur décent est de la merde", mais j'y suis habitué. Spark est plus précieux que pour compenser ces lacunes. Ce sera peut-être un peu mieux si la mise à jour de la version progresse, mais dans certains cas, je pense essayer de le réparer moi-même et de contribuer.

Vous qui êtes fatigués des requêtes SQL complexes! Spark est bon!

Recommended Posts

Fatigué de gérer des requêtes SQL complexes! C'est au tour de Spark