Vous êtes sur la page 1sur 32

APACHE SPARK : SPARK SQL PRINCIPES ET FONCTIONS

DR MUSTAPHA MICHRAFY

CONTACT : DATASCIENCE.KM@GMAIL.COM
CONTEXTE M.MICHRAFY

Cette étude a été menée dans le cadre des


rencontres de travail organisées au Laboratoire
CERMSEM, Centre d'Économie de la Sorbonne (CES).
Il vise à présenter Spark SQL:
• Architecture
• API de Spark SQL
• Opérations sur DataFrames
• Opérations sur DataSet
• Opérations relationnelles

2
PLAN M.MICHRAFY

1. Contexte
2. Objectif et prérequis
3. Spark SQL, Motivations
4. Spark SqL et introduction de Catalyst Optimizer
5. Aperçu sur les objets du module Spark SQL
6. Nouvelle architecture Spark ( 2.x)
7. DataWorkflow et Catalyst Optimizer
8. Zoom sur SParkSESSION
9. DataSet et DataFrame
10.DataFrame, caractéristiques, formats supportés, création
11.Chargement et persistance des données
12.DataFrameNaFunctions et Préparation des données
13.Graphe de conversion entre Collection, RDD, DataFrame et DataSet
14.Opérations sur les DataSets et les DataFrames

3
OBJECTIF ET PRÉREQUIS M.MICHRAFY

Objectif Prérequis
Cette étude porte sur la brique Spark SQL de • Connaissance de l’approche objet
la plateforme Apache Spark. Il vise à • Connaissance de la programmation
présenter les concepts et les fonctionnalités fonctionnelle
de spark SQL. • Connaissance du langage Scala
• Connaissance de Spark

4
SPARK SQL : DÉFINITION ET MOTIVATIONS ? M.MICHRAFY

SPARK SQL ? Fonctionnalités


• SPARK SQL est une brique logiciel incontournable • Pour formater les données
de la plate forme Apache Spark. • Pour extraire des caractéristiques des données
• Cette brique est dédiée au traitement de • Pour enrichir les données
données structurées et semi structurées via l’API • Pour transformer les données
DataSet/DataFrame. • Pour appliquer des opérations relationnelles
• Spark SQL permet d’effectuer des requêtes sur les
données avec une syntaxe similaire à SQL.
• Spark SQL permet de s’interfacer à diverses
sources de données.
• Les opérations de SPARK SQL sont optimisées à
travers l’utilisation de Catalyst Optimizer.

Cas d’utilisation
• S’interfacer avec un tableau de bord en utilisant
tableau, Qlik
• Réaliser des requêtes SQL sans faire appel à la
sémantique RDD
• Préparation et Analyse des données à travers l’utilisation
de l’API DataFrame/DataSet avec opérations optimisées
et riches à l’image du package dplyr de R
5
SPARK SQL ET INTRODUCTION DE CATALYST OPTIMIZER
1
Constat 1 Un besoin pour des opérations ETL vers et
La popularité des systèmes à partir de diverses sources de données,
Limite
relationnels montre que les (semi) structurée, nécessitant un code
L’approche relationnelle
utilisateurs favorisent l’écriture des personnalisé.
est insuffisante pour la
requêtes déclaratives. 2
majorité des applications
Constat 2 BigData, car : L’analyse avancée -basée sur des
algorithmes complexes- ne peut être
Les workflows de données
réalisée par l’approche relationnelle
peuvent être exprimés par une À noter …
combinaison de requêtes
Ces deux systèmes - relationnel et procédural – sont restés jusqu'à la
relationnelles et d’algorithmes
version 1.0.2 de Spark largement disjointes, forçant les utilisateurs à
complexes.
choisir un paradigme ou l'autre.

Intérêt de SPARK SQL


• Il vise à combiner l’approche relationnelle et procédurale dans la brique spark SQL.
o API DATASET/DataFrame permet d’effectuer des opérations relationnelles sur des sources de
données externes et les collections intégrées de Spark
o Divers formats de données et algorithmes distribués supportés via l’introduction de l’optimiseur6
Catalyst
APERÇU SUR LES OBJETS DU MODULE SPARK SQL
SQLImplicits SparkSession
Collection des méthodes Point d’entrée pour l’API
implicites pour convertir DataSet et l’API DataFrame
des Objets Scala en
DataSets DataSet & DataFrame
DataSet est une collection
distribuée immutable, disposant
SQLContext
d’opérations de type action et
Point d’entrée pour le module
Spark SQL de la version 1.0.1 à Objets transformation. DataFrame est
un DataSet de Type Row
la version 1.6 de Spark
Spark SQL DataFrameReader
Row Interface pour charger des
Trait qui représente DataSet à partir d’un stockage
une ligne externe (TXT, CSV, JSON,
PARQUET, Cle/Valeur, JDBC)
Column
Trait qui représente DataFrameWriter
une colonne Interface pour persister les
données d’une DataSet vers un
système de stockage externe

7
NOUVELLE ARCHITECTURE SPARK ( 2.X)

o La nouvelle architecture s’appuie sur le


module Catalyst Optimizer permettant
ML Pipelines Structured GraphFrame d’unifier les APIs et optimiser davantage le
Streaming traitement .
SQL DataSet/DataFrame Spark
o DataSet = DataFrame[Row]
Catalyst Optimizer
SQL
o DataSet, DataFrame et SQL partagent les
Spark Core (RDD) mêmes étapes d’optimisation et
d’exécution grâce à Catalyst Optimizer

Storage

8
DATAWORKFLOW ET CATALYST OPTIMIZER

SQL AST

Catalyst Optimizer

DataFrame RDDs
Query Plan Optimization
Query

DataSet

Transformation Génération du code

9
SPARKSESSION
Point d’entrée Fonctionnalités
• SparkSession est le point d’entrée de l’API • Accéder à SparkContext
DataSet/Dataframe, depuis la version 2.0.0 • Accéder à SparkSql pour garantir la cohérence des versions
• SparkSession est une classe qui peut être créée à de Spark SQL
partir du Builder. • Créer des DataFrames à partir des RDD ou des collections
• Elle appartient au package org.apache.spark.sql • Créer des DataSet
• Créer une DataFrame ou une DataSet vide
• Créer une DataSet avec une seule colonne
Builder • Exécuter une requête Sql et retourner une dataframe.
• Builder est une classe interne pour SparkSession. • Accéder à des Interfaces permettant de charger une
• Cette dernière permet de gérér, créer et DataSet, en mode batch ou flux continu, à partir de
configurer une session spark SQL systèmes de stockage externes (TEXT, CSV, JSON, ORC,
• Il dispose de : PARQUET, Cle/valeur, JDBC)
• Constructeur sans argument
• appName pour fixer le nom de l’application
• Config pour fixer les options de la conf.
• getOrCreate pour retourner une session

À noter bien
• La majorité des méthodes sont au stade expérimental et sont disponibles à partir de la version 2.
• D’autres méthodes sont dédiés aux développeurs de l’API Spark
• Avant la version 2.0.0, la classe utilisée est SparkSql
10
DATASET ET DATAFRAME
DataSet DataFrame
• DataSet est une collection distribuée de données • DataFrame est une DataSet avec des éléments
• L’Api DataSet a été introduit dans Spark à partir de type Row.
de la version 1.6. • Une DataFrame est l’équivalent d’une table dans
• La dataSet est fortement typée. une base de données ou une dataFrame dans R
• DataSet supporte des transformations basées sur ou Python.
des paradigmes fonctionnels ou relationnels • Une DataFrame est non typée.
• À l’image de la RDD, une DataSet dispose des • Une DataFrame peut être construite à partir
opérations de type transformation et Action. d’une source de données structurées, des tables
• Une DataSet est paresseuse, par conséquent le Hive, des BD ou des RDDs.
calcul se déclenche pour des opérations de type • L’API DataFrame est disponible en Scala, Java,
action. Python et R.
• L’API DataSet est disponible pour le langage
Scala et Java, pas pour Python

L’API SPARK SQL s’articule autour de


de la notion de DataSet/DataFrame

11
M.MICHRAFY
DATAFRAME, CARACTÉRISTIQUES, FORMATS SUPPORTÉS, CRÉATION

Immutable
In-Memory Lazy
evaluated

Resilient DataFrame Parallele

Cacheable unTyped
Partitioned

Caractéristique Formats fichiers Création


La dataFrame supporte :  Spark SQL supporte de charger ou  Cinq manières de créer une DataFrame
 des opérations de type transformation et d’enregistrer des fichiers dans 1. A partir d’une source de données
action. divers formats : non structuré, semi- 2. À partir d’une RDD
 des opérateurs relationnels : select, where, structuré, structuré. 3. À partir d’une table BD
join, groupby.  Les formats sont : 4. A partir d’une table Hive
 les langages Scala, Java, Python, R o Text 5. Via une opération de
Elle est : o Json transformation
 Orientée colonne o CSV
 Partionnée o Parquet
 d’une évaluation paresseuse o Orc
 DataSet = DataFrame[Row]

12
CHARGEMENT ET PERSISTANCES DES DONNÉES 1/2
DataFrameReader DataFrameWriter
• DataFrameReader a pour objectif de charger des • DataFrameWriter permet de persister des DataSet
DataSet à partir d’un système de stockage externe dans un système de stockage externe tels qu’un
tels qu’un système de fichier, une table relationnelle, système de fichier, JDBS, HIVE, Stockage clé-valeur,
un stockage clé-valeur, etc. etc.
• L’accès à cette classe se fait à partir d’une session • L’accès à cette classe se fait à partir d’une session
sparkSession via le membre read. sparkSession via le membre write.
• Elle dispose des méthodes dédiées à des formats • Cette classe dispose des méthodes :
de type TXT, JSON, Parquet, Orc, CSV. Pour cela, • format : spécifier le format de données (json, txt,
utiliser les méthodes txt, json, orc, csv, parquet, parquet, orc, csv)
textFiles, jdbc… • modeSave : préciser le comportement lorsque
• Elle dispose aussi d’une méthode générique, notée la donnée ou la table existe.
load, nécessitant la spécification du format, du • Option(s) : ajouter une ou plusieurs options
schéma et des options. relative la source de données de sortie
• La majorité des méthodes de chargement • save : enregistrer le contenu de la dataFrame
retournent des dataFrames à l’exception de la • jdbc, csv, parquet, orc, txt : sont des méthodes
méthode textFiles retourne une DataSet[String] pour enregistrer le contenu dans un format
spécifique.

Dans la classe DataFrameReader (resp. DataFrameWriter), les méthodes csv, json,


orc, parquet, txt sont des cas particuliers de la méthodes load (resp. save).
13
DATAFRAMENAFUNCTIONS ET PRÉPARATION DES DONNÉES

Caractéristiques Fonctionnalités
• Il offre des fonctionnalités pour gérer les valeurs • Méthodes de type drop : elles permettent de
manquantes dans une dataFrame. supprimer des lignes ou des colonnes contenant
null or NaN, selon certains critères et retournent
• Une instance de cette classe peut être créée en une nouvelle dataFrame
faisant appel à la méthode na de la dataSet.
• Méthodes de type fill : elles permettent de
• C’est une classe «final». Par conséquent, elle substituer certaines valeurs (nulles ou NaN) et
n’est pas extensible retournent une nouvelle DataFrame

• Il fait partie du package org.apache.spark.sql • Méthodes de type replace : elles permettent de


remplacer des occurrences de certaines
colonnes par d’autres.

Une instance de cette classe est utile dans la


phase de préparation des données.

14
GRAPHE DE CONVERSION ENTRE LA RDD, DATAFRAME, DATASET

 Une RDD peut etre transformée en DataSet en


utilisant la méthode toDS()

 Une RDD peut être transformée en DataFrame en


RDD DataFrame utilisant la méthode toDF()

 Une Collection peut être transformée en RDD en


utilisant la méthode parallelize du sparkContext

 Une Collection peut être transformée en DataSet


en utilisant toDS()

 Une collection peut être transformée en


DataFrame en utilisant toDF()
Collection DataSet
 Une DataFrame peut être transformée en DataSet
en utilisant as[U](encoder)

 Le contenu d’une DataSet/DataFrame peut être


représentée par une RDD en utilisant le membre
rdd de la DataSet.

15
M.MICHRAFY

Opérations sur les DataSet/DataFrame

• Cette section présente les différentes opérations relatives à une


DataFrame/DataSet :
1. Opération de type Action/transformations sur DataFrame/DataSet
2. Construction d’une DataFrame/DataSet
3. Conversion entre DataSet/DataFrame/RDD/Collection
4. Opérations SQL
5. Opérations de nettoyage de données

(*) : Les exemple du code ont été exécutés avec spark-shell, version 2.0.2 16
DONNÉES UTILISÉES

people.txt people.json

Michael, {"name":"Michael"}
29Andy, {"name":"Andy","age":30}
30Justin, 19 {"name":"Justin", "age":19}

 Les deux fichiers people.txt et people.json sont livrés avec la distribution d’Apache
spark.

 Le chemin pour accéder aux fichiers est :


PathSpark/examples/src/main/resources

 Pour ne pas alourdir le code, nous notons “VotrPathSpark/people.json“ qui fait


référence à “ PathSpark/examples/src/main/resources/people.json”

17
SPARKSESSION : CREATION ET CONFIGURATION M.MICHRAFY

Objectif Exemple
 SparkSession est le point d’entrée // importer sparkSession
pour le module Spark Sql
 La création d’un objet SparkSession se import org.apache.spark.sql.SparkSession
fait via l’objet builder qui est une
classe interne de SparkSession /***
 package : org.apache.spark.sql Créer sparkSession
Nommer l’application
Configurer l’application
Importer le package SparkSession en enfin retourner la session crée.
****/
// retour > spark: org.apache.spark.sql.SparkSession =
org.apache.spark.sql.SparkSession@5fd8dd66
Créer la session SparkSession val spark = SparkSession .builder()
.appName("Spark SQL")
.config("spark.some.config.option", "value")
.getOrCreate()

Afficher la version de spark // afficher la version de spark


// retour > res1: String = 2.0.2
spark.version

18
CRÉATION D’UNE DATAFRAME À PARTIR D’UNE SÉQUENCE M.MICHRAFY

Objectif Exemple
 createDataFrame est une méthode
de la classe SparkSession permettant
import org.apache.spark.sql.SparkSession // importer sparkSession
de créer une dataFrame à partir val spark = SparkSession .builder().getOrCreate() // créer une session
d’une collection. // créer des sequences : seqVilles
val seqVilles = Seq(("Paris", 2015, 8),("Paris", 2015, 8),("Lyon", 2016, 7),("Lyon",
2017, 1),("Lyon", 2016, 7))

// créer une dataFrame à partir de la séquence seqVilles


Importer le package SparkSession val dfVilles = spark.createDataFrame(seqVilles).toDF("ville", "annee", "mois")
// dfVilles: org.apache.spark.sql.DataFrame = [ville: string, annee: int ... 1 more field]

dfVilles.printSchema // afficher le schéma de la dataFrame dfVille


root
Créer la session SparkSession |-- ville: string (nullable = true)
|-- annee: integer (nullable = false)
|-- mois: integer (nullable = false)
Créer la séquence
dfVilles.show() // afficher le contenu de la dataframe
Créer la DataFrame à partir de la |ville|annee|mois|
|Paris| 2015 | 8|
séquence
|Paris| 2015 | 8|
Afficher le schema de la dataFrame | Lyon| 2016| 7|
| Lyon| 2017| 1|
Afficher le contenu de la dataFrame | Lyon| 2016| 7|
19
DATAFRAME/DATAFRAMEREADER : CREATION À PARTIR D’UNE DATASOURCE M.MICHRAFY

DataFrameReader Exemple
 SparkSession dispose d’un membre import org.apache.spark.sql.SparkSession // importer sparkSession
noté read de type DataFrameReader
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
 DataFrameReader permet de
charger une dataFrame ou une
val dfReader = spark.read //Pointer la DataFrameReader
DataSet via : // Retour > org.apache.spark.sql.DataFrameReader@a323a5b
• Un fichier format CSV // Créer des dataFrames via des fichier Json,
• Un fichier format TXT val dfJSON = dfReader.json("VotrPathSpark/people.json")
• Un fichier format JSON // retour > df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]
• Un fichier format Parquet val dfCSV = dfReader.cvs("VotrPathSpark/people.txt")
• Un fichier format ORC // retour > dfcsv: org.apache.spark.sql.DataFrame = [_c0: string, _c1: string]
• Une table JDBC val dfparquet = dfReader.parquet("VotrPathSpark/users.parquet")
 DataFrameReader permet aussi de //retour > dfparquet: org.apache.spark.sql.DataFrame = [_c0: string, _c1: string ... 1 more field]
spécifier le shéma. val dfTEXT = dfReader.txt("VotrPathSpark/people.txt")
// retour > dfTXT: org.apache.spark.sql.DataFrame = [value: string]
Créer la session
// afficher le contenu des dataframes avec la methode show()
SparkSession
dfJSON.show()
Pointer le membre dfCSV.show()
DataFrameReader dfTEXT.show()

Charger le fichier JSON

20
LANCER DES REQUÊTES SQL SUR UNE VUE TEMPORAIRE M.MICHRAFY

Requête SQL Exemple


 createOrReplaceTempView import org.apache.spark.sql.SparkSession // importer sparkSession
est une méthode de DataSet
permettant de créer une vue val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
pour exécuter des requêtes
SQL. // Créer des dataFrames à partir d’un fichier Json,
 La méthode sql de DataSet val dfJSON = spark.read.json("VotrPathSpark/people.json")
permet d’interroger une vue // retour > df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]
temporaire et retourne une /*****
DataFrame créer une vue temporaire,
 La vue temporaire est puis lancer des requetes sur la vue
accessible tant que la session
Spark SQL est disponible. ****/
val sqlDfJson = dfJSON.createOrReplaceTempView("people") // créer la vue temp.
Créer la session SparkSession val sqlDF = spark.sql("SELECT * FROM people where age > 18") // interroger la vue
//retour > sqlDF: org.apache.spark.sql.DataFrame = [age: bigint, name: string]

Charger le fichier Json // afficher le contentu de la dataFrame sqlDF


sqlDF.show()
Créer une vue temporaire Retour > |age| name|
| 30 | Andy |
| 19 |Justin |
Lancer une requête sur la vue

Afficher le résultat
de la requête 21
CONVERSION D’UNE COLLECTION EN UNE DATASET M.MICHRAFY

Requête SQL Exemple


 Spark SQL dispose des services
import org.apache.spark.sql.SparkSession // importer sparkSession
permettant de convertir une
collection en DataSet val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
 Ce mécanisme s’appuie sur
les encoders. //créer une classe case
 la méthode toDS() permet de Case class Person(name:String, age:Int)
convertir un Collection vers //créer une dataSet
une DataSet. val ps = Seq(Person(”Alain", 30), Person("Stef", 19), Person("Sam", 25)).toDS()
//retour > ps: org.apache.spark.sql.Dataset[Person] = [name: string, age: bigint]

Créer la session SparkSession // afficher les noms des colonnes


ps. Columns
// retour > res1: Array[String] = Array(name, age)
Créer la classe case
// afficher le schèma de la dataSet
Créer la dataSet
ps.schema
//Retour > res2: org.apache.spark.sql.types.StructType =
Afficher les nom des colonnes StructType(StructField(name,StringType,true), StructField(age,LongType,false))

Afficher le schéma // afficher le contenu de la dataSet dans un tableau


ps.collect()
Afficher le contenu
// Retour >res3: Array[Person] = Array(Person(Andy,32), Person(Stef,19), Person(Sam,25))
de la dataSet
22
CONVERSION UNE DATAFRAME EN UNE DATASET M.MICHRAFY

Requête SQL Exemple


 En Spark SQL, il est possible de
import org.apache.spark.sql.SparkSession // importer sparkSession
convertir une DataFrame vers
une DataSet val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
 Pour cela, il suffit d’utiliser la
méthode as de la Dataframe // Créer la dataFrame à partir d’un fichier Json,
avec le nom de la classe. val dfjson = spark.read .json ("VotrPathSpark/people.json")
// retour > org.apache.spark.sql.DataFrame = [age: bigint, name: string]

dfjson.printSchema // afficher le schema de dfjson


// root
|-- age: long (nullable = true)
Créer la session SparkSession |-- name: string (nullable = true)

case class Person(name:String, age:Long) //créer une classe case


Créer la dataFrame
val DfTODS = dfjson.as[Person] //Convertir la DataFrame en une DataSet
Créer la classe case //DfTODS: org.apache.spark.sql.Dataset[Personne] = [age: bigint, name: string]

Convertir la DataFrame DfTODS .schema


en DataSet //Retour > org.apache.spark.sql.types.StructType =
StructType(StructField(age,LongType,true), StructField(name,StringType,true))
Afficher le schéma de
la DataSet
23
CONVERSION D’UNE RDD EN DATAFRAME M.MICHRAFY

Requête SQL Exemple


 En Spark SQL, il est possible de
convertir une RDD en une
import org.apache.spark.sql.SparkSession // importer sparkSession
DataFrame val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
 Pour ce faire, il suffit d’utiliser // Créer une RDD à partir du fichier txt
la méthode toDF de la RDD val peopleRDD = spark.sparkContext
.textFile("VotrePathSpark/people.txt")
.map(_.split(","))
.map(attributes => Person(attributes(0), attributes(1).trim.toInt))
// retour > peopleRDD: org.apache.spark.rdd.RDD[Person] = MapPartitionsRDD[79]

Créer la session SparkSession peopleRDD.cache() // persister la RDD en mémoire


// retour > peopleRDD.type = MapPartitionsRDD[94] at map at <console>:31
Créer la RDD
//Convertir la RDD en DataFrame
Persister la RDD en mémoire val peopleDS = peopleRDD.toDF()
//retour > peopleDS: org.apache.spark.sql.DataFrame = [name: string, age: bigint]
Convertir la RDD en
DataFrame peopleDS .show() // afficher le contenu de la dataFrame
| name |age|
Afficher la DataFrame |Michael| 29 |
| Andy | 30 |
| Justin | 19 |
24
CONVERSION D’UNE RDD EN DATAFRAME : SPÉCIFIER LE SCHÉMA M.MICHRAFY

Requête SQL Exemple


 En Spark SQL, il est aussi import org.apache.spark.sql.{SparkSession, Row} // importer sparkSession, Row
possible de convertir une RDD
de type Row en une import org.apache.spark.sql.types._
DataFrame en spécifiant le
schéma. val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
 createDataFrame est une // Créer une RDD de type Row à partir du fichier txt
méthode de sparkSession val peopleRDD = spark.sparkContext
permettant de créer une .textFile("VotrePathSpark/people.txt")
DataFrame à partir d’une
.map(_.split(","))
RDD[Row] et le schéma
associé à Row .map(attributes => Row(attributes(0), attributes(1).trim.toInt))
// retour > peopleRDD: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] =
Importer les packages
MapPartitionsRDD[111]
Créer la session
SparkSession val schemaString = "name age"
val fields = schemaString.split(" ").map(w => StructField(w, StringType, nullable = true))
Créer la RDD[Row] //retour > fields: Array[org.apache.spark.sql.types.StructField] =
Array(StructField(name,StringType,true), StructField(age,StringType,true))
Créer le schéma val schema = StructType(fields)

Convertir la RDD en //Convertir la RDD en DataFrame


DataFrame val peopleDF = spark.createDataFrame(peopleRDD, schema)
// peopleDF: org.apache.spark.sql.DataFrame = [name: string, age: string]
25
FONCTIONS GÉNÉRIQUES POUR LA CHARGEMENT ET LA PERSISTANCE M.MICHRAFY

Load / Save Exemple


 Spark SQL dispose de deux import org.apache.spark.sql.SparkSession // importer sparkSession
fonctions génériques pour le
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
chargement ou la persistance
des données vers ou à partir
d’un système de stockage // charger le fichier people.json en utilisant la méthode generique load
externe. val fgl = spark.read.format("json").load("VotrePathSpark/people.json")
 load (Resp. save) est une //retour > org.apache.spark.sql.DataFrame = [age: bigint, name: string]
méthode de la classe
DataFrameReader(resp //afficher le contenu sous forme d’un tableau
DataSet) pour charger (resp.
flg.collect()
Persister ) des données.
 La méthode load nécessite // retour > Array[org.apache.spark.sql.Row] = Array([null,Michael], [30,Andy], [19,Justin])
de préciser le format des
données, alors que la // importer SaveMode
méthode save nécessite de import org.apache.spark.sql.SaveMode
spécifier le mode de
sauvegarde. //Persister le contenu de la dataframe en utilisant save
 mode est une méthode de la val fgs = fgl.write.format("parquet").mode(SaveMode.ErrorIfExists).save("people.parquet")
calsse DataFrameWriter,
permettant de spécifier le
comportement si le fichier ou
la table existe.

26
PERSISTER LE CONTENU D’UNE DATAFRAME M.MICHRAFY

Persister un DF Exemple
 En Spark SQL, il est possible de import org.apache.spark.sql.SparkSession // importer sparkSession
persister le contenu d’une
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
dataFrame en different
format : format JSON, CSV,
PARQUET, …. // créer une dataFrame
 La classe DataFrameWriter val villes = spark.createDataFrame(Seq(("Paris",2015,8),("Lyon",2015,8)
dispose des méthodes json, ,("Toulon",2016,7))).toDF("ville","annee","mois")
csv, parquet pour persister les //villes: org.apache.spark.sql.DataFrame = [ville: string, annee: int ... 1 more field]
données.
 Le membre write de la // Persister le contenu en format json, csv et parquet
dataframe pointe sur un objet
de type DataFrameWriter. villes.write.json("villes.json")
villes.write.csv("villes.csv")
villes.write.parquet("villes.parquet")

27
EXÉCUTER UNE REQUÊTE SQL SUR UN FICHIER SOURCE M.MICHRAFY

Requête SQL Exemple


 En Spark SQL, il est possible de import org.apache.spark.sql.SparkSession // importer sparkSession
lancer une requête sur un
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
fichier de format JSON, CSV,
PARQUET, ….
// Lancer une requête SQL sur un fichier json
 Pour ce faire, il suffit d’utiliser val sqlJSON = spark.sql("SELECT * FROM json.`VotrePathSpark/people.json`")
la méthode sql de la classe // retour > sqlJSON: org.apache.spark.sql.DataFrame = [age: bigint, name: string]
sparkSession.
// Lancer une requête SQL sur un fichier CSV
val sqlCSV = spark.sql("SELECT * FROM csv.`VotrePathSpark/people.txt`")
// retour > sqlCSV: org.apache.spark.sql.DataFrame = [_c0: string, _c1: string]

// Lancer une requête SQL sur un fichier parquet


val sqlParquet = spark.sql("SELECT * FROM parquet.`VotrePathSpark/users.parquet`")
// sqlParquet: org.apache.spark.sql.DataFrame = [name: string, favorite_color: string ... 1
more field]

28
TYPAGE D’UNE COLONNE D’UNE DATAFRAME M.MICHRAFY

Typage Exemple
 En Spark SQL dispose des outils import org.apache.spark.sql.SparkSession // importer sparkSession
pour accéder à une colonne
et typer ses valeurs
import org.apache.spark.sql.functions._ // pour la fonction udf
 withColumn est une méthode val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
d’une dataSet permettant de
remplacer une colonne. // Charger un fichier csv
 La fonction udf permet val dfcsv = spark.read.csv("VotrePathSpark/people.txt").toDF("nom", "age")
d’appliquer une opération sur // dfcsv: org.apache.spark.sql.DataFrame = [nom: string, age: string]
les éléments d’une colonne.
val toInt = udf[Int, String]( _.trim().toInt) // toInt : supprimer le blanc, et convertir en entier

// appliquer la fonction toInt sur la colonne age de dfcsv


val dft = dfcn.withColumn("age", toInt(dfcn("age")))
// dft: org.apache.spark.sql.DataFrame = [name: string, age: int]

Dft.printSchema // afficher le schema de la dataframe dft


root
|-- name: string (nullable = true)
|-- age: integer (nullable = true)

29
DATAFRAME, CORRIGER LES DONNÉES M.MICHRAFY

Typage Exemple
 DataFrameNaFunctions import org.apache.spark.sql.SparkSession // importer sparkSession
permet de gérer les valeurs
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
manquantes d’une
dataFrame via les fonctions :
drop, fill, replace case class Personne(ville:String, nom:String, score:Double) // case classe
val x = Seq(Personne("Paris", "Stefan", 9), Personne("Lyon", "Alain", 15), Personne("Pariss",
 na une méthode de la null, 12)) // Créer une séquence de personnes
DataFrame permet
d’accéder un objet de type val dfx = spark.createDataFrame(x) // Créer une dataFrame via la séquence x
DataFrameNaFunctions.
dfx.collect() // afficher le contenu de la dataframe dfx
// Array[org.apache.spark.sql.Row] = Array([Paris,Stefan,9.0], [Lyon,Alain,15], [Pariss,null,12.0])

// remplacer null de la colonne « nom » par inconnu en utilisant la fonction fill


Val dfy = dfx.na.fill(Map("nom" -> "inconnu"))
// remplacer « pariss » par « paris », colonne « ville »
val dfz = dfy.na.replace("ville", Map("Pariss" -> "Paris"))
dfz.show() // afficher le contenu de la dataframe dfz
|ville| nom|score|
|Paris| Stefan| 9.0|
| Lyon| Alain| 15 |
|Paris|inconnu| 12.0|

30
RÉFÉRENCES

 Guide de programmation Spark SQL (http://spark.apache.org/docs/2.0.2/sql-


programming-guide.html)

 API SPARK, langage Scala (http://spark.apache.org/docs/2.0.2/api/scala/index.html)

 Spark SQL: Relational Data Processing in Spark


(http://people.csail.mit.edu/matei/papers/2015/sigmod_spark_sql.pdf)

31
DR MUSTAPHA MICHRAFY

CONTACT : DATASCIENCE.KM@GMAIL.COM

Vous aimerez peut-être aussi