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.
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
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.
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.
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.
Utilisez la puissance du langage de programmation Il y a une limite à ce que vous pouvez faire avec SQL seul, mais ** vous pouvez utiliser n'importe quel nombre de bibliothèques de langage moderne pour l'agrégation et le traitement ** est extrêmement supérieur, et il est également bon de pouvoir couper la partie de traitement à UnitTest.
SQL ne détecte même pas les erreurs de syntaxe simples (telles que la correspondance entre parenthèses) tant que vous ne les transmettez pas à la base de données, mais Spark vous permet de ** laisser le compilateur faire beaucoup de vérification de syntaxe et de type **
Type de données flexible Il est également possible de mettre un tableau ou une structure dans le champ ** dans les données intermédiaires du processus d'agrégation comme après GROUP BY **.
DB peut se concentrer sur le stockage de données (SQL INSERT, UPDATE) et l'analyse et le traitement séparés du côté Spark. Vous n'avez pas à vous soucier de la dégradation des performances due à l'exécution de requêtes complexes. Ce serait bien si les données pouvaient être récupérées avec un seul index DB, mais ce serait bien si une instruction SQL LIKE apparaissait. C'est au tour de Spark.
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.
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?
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
score
: totalScore
duration
: durationAvg
duration
: durationStddev
count
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.
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.
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.
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