Upload
alexis-seigneurin
View
1.351
Download
3
Embed Size (px)
Citation preview
Alexis Seigneurin@aseigneurin @ippontech
Spark
● Traitement de larges volumes de données● Traitement distribué (commodity hardware)● Ecrit en Scala, bindings Java et Python
Histoire
● 2009 : AMPLab de l'Université de Berkeley● Juin 2013 : "Top-level project" de la
fondation Apache● Mai 2014 : version 1.0.0● Actuellement : version 1.2.0
Use cases
● Analyse de logs● Traitement de fichiers texte● Analytics● Recherche distribuée (Google, avant)● Détection de fraude● Recommendation (articles, produits...)
Proximité avec Hadoop
● Mêmes use cases● Même modèle de
développement : MapReduce
● Intégration dans l'écosystème
Plus simple qu’Hadoop
● API plus simple à prendre en main● Modèle MapReduce "relâché"● Spark Shell : traitement interactif
Plus rapide qu’Hadoop
Spark officially sets a new record in large-scale sorting (5 novembre 2014)
● Tri de 100 To de données● Hadoop MR : 72 minutes
○ Avec 2100 noeuds (50400 cores)
● Spark : 23 minutes○ Avec 206 noeuds (6592 cores)
Écosystème Spark
● Spark● Spark Shell● Spark Streaming● Spark SQL● Spark ML● GraphX
brownbaglunch.fr
Intégration
● Yarn, Zookeeper, Mesos● HDFS● Cassandra● Elasticsearch● MongoDB
Fonctionnement de Spark
● Resilient Distributed Dataset● Abstraction, collection traitée en parallèle● Tolérant à la panne● Manipulation de tuples :
○ Clé - Valeur○ Tuples indépendants les uns des autres
RDD
Sources
● Fichier sur HDFS● Fichier local● Collection en mémoire● Amazon S3● Base NoSQL● ...● Ou une implémentation custom de
InputFormat
Transformations
● Manipule un RDD, retourne un autre RDD● Lazy !● Exemples :
○ map() : une valeur → une valeur○ mapToPair() : une valeur → un tuple○ filter() : filtre les valeurs/tuples○ groupByKey() : regroupe la valeurs par clés○ reduceByKey() : aggrège les valeurs par clés○ join(), cogroup()... : jointure entre deux RDD
Actions finales
● Ne retournent pas un RDD● Exemples :
○ count() : compte les valeurs/tuples○ saveAsHadoopFile() : sauve les résultats au
format Hadoop○ foreach() : exécute une fonction sur chaque
valeur/tuple○ collect() : récupère les valeurs dans une liste
(List<T>)
Exemple
● Arbres de Paris : fichier CSV en Open Data● Comptage d’arbres par espèce
Spark - Exemple
geom_x_y;circonfere;adresse;hauteurenm;espece;varieteouc;dateplanta48.8648454814, 2.3094155344;140.0;COURS ALBERT 1ER;10.0;Aesculus hippocastanum;;48.8782668139, 2.29806967519;100.0;PLACE DES TERNES;15.0;Tilia platyphyllos;;48.889306184, 2.30400164126;38.0;BOULEVARD MALESHERBES;0.0;Platanus x hispanica;;48.8599934405, 2.29504883623;65.0;QUAI BRANLY;10.0;Paulownia tomentosa;;1996-02-29...
Spark - ExempleJavaSparkContext sc = new JavaSparkContext("local", "arbres");
sc.textFile("data/arbresalignementparis2010.csv") .filter(line -> !line.startsWith("geom")) .map(line -> line.split(";")) .mapToPair(fields -> new Tuple2<String, Integer>(fields[4], 1)) .reduceByKey((x, y) -> x + y) .sortByKey() .foreach(t -> System.out.println(t._1 + " : " + t._2));
[... ; … ; …]
[... ; … ; …]
[... ; … ; …]
[... ; … ; …]
[... ; … ; …]
[... ; … ; …]
u
m
k
m
a
a
textFile mapToPairmap
reduceByKey
foreach
1
1
1
1
1
u
m
k
1
2
1
2a
...
...
...
...
filter
...
...
sortByKey
a
m
2
1
2
1u
...
...
...
...
...
...
geom;...
1 k
Spark - ExempleAcacia dealbata : 2
Acer acerifolius : 39
Acer buergerianum : 14
Acer campestre : 452
...
Spark en cluster
Topologie & Terminologie
● Un master / des workers○ (+ un master en standby)
● On soumet une application● Exécution pilotée par un driver
Spark en cluster
Plusieurs options
● YARN● Mesos● Standalone
○ Workers démarrés individuellement○ Workers démarrés par le master
MapReduce● Spark (API)● Traitement distribué● Tolérant à la panne
Stockage● HDFS, base NoSQL...● Stockage distribué● Tolérant à la panne
Stockage & traitements
Colocation données & traitement
● “Data locality”● Traiter la donnée là où elle se trouve● Eviter les network I/Os
Colocation données & traitement
Spark Worker
HDFS Datanode
Spark Worker
HDFS Datanode
Spark Worker
HDFS Datanode
Spark Master
HDFS Namenode
HDFS Namenode (Standby)
SparkMaster
(Standby)
DémoSpark en cluster
Démo$ $SPARK_HOME/sbin/start-master.sh
$ $SPARK_HOME/bin/spark-class org.apache.spark.deploy.worker.Worker spark://MacBook-Pro-de-Alexis.local:7077 --cores 2 --memory 2G
$ mvn clean package$ $SPARK_HOME/bin/spark-submit --master spark://MBP-de-Alexis:7077 --class com.seigneurin.spark.WikipediaMapReduceByKey --deploy-mode cluster target/pres-spark-0.0.1-SNAPSHOT.jar
Spark sur un cas pratique
[Event "BL 0809 Hamburger SK - TV Tegernsee"][Site "?"][Date "2008.10.04"][Round "1.3"][White "Sokolov, Andrei"][Black "Kempinski, Robert"][Result "1-0"][ECO "B85"][WhiteElo "2561"][BlackElo "2613"][PlyCount "101"][EventDate "2008.??.??"]
1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. f4 e6 7. Be2 Be7 8. O-OO-O 9. Kh1 Qc7 10. a4 Nc6 11. Be3 Re8 12. Bf3 Rb8 13. g4 Nd7 14. g5 b6 15. Bg2...
Statistiques de parties d’échecs
● Expérimentation de Tom Hayden sur Hadoop○ 1,75 Go de données○ 7 machines c1.medium sur AWS○ 26 minutes !○ 1,14 Mo/seconde
Hadoop
● Command-line tools can be 235x faster than your Hadoop cluster - Adam Drakehttp://aadrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html
○ 3,46 Go de données○ Shell : find, xargs, mawk○ 12 secondes○ 260 Mo/seconde
Hadoop vs Command line tools
$ find . -type f -name '*.pgn' -print0 | xargs -0 -n4 -P4 mawk '/Result/ { split($0, a, "-"); res = substr(a[1], length(a[1]), 1); if (res == 1) white++; if (res == 0) black++; if (res == 2) draw++ } END { print white+black+draw, white, black, draw }' | mawk '{games += $1; white += $2; black += $3; draw += $4; } END { print games, white, black, draw }'
package com.seigneurin.spark;import org.apache.spark.api.java.JavaSparkContext;public class Chess {
public static void main(String[] args) {
JavaSparkContext sc = new JavaSparkContext("local[16]", "chess");
long start = System.currentTimeMillis();
sc.textFile("ChessData-master/*/*.pgn") .filter(line -> line.startsWith("[Result ") && line.contains("-")) .map(res -> res.substring(res.indexOf("\"") + 1, res.indexOf("-"))) .filter(res -> res.equals("0") || res.equals("1") || res.equals("1/2")) .countByValue() .entrySet() .stream() .forEach(s -> System.out.println(s.getKey() + " -> " + s.getValue()));
long duration = System.currentTimeMillis() - start; System.out.println("Duration: " + duration + " ms");
sc.close(); }}
Spark
● 4,6 Go de données● Shell
○ 10 secondes○ 460 Mo/seconde
● Spark 1.2.0○ 1 worker avec 16 threads○ 16 secondes○ 287 Mo/seconde
Expérimentation
● 6 machines sur Google Compute Engine○ n1-highcpu-4 : 4 vCPU et 3,6 Go de mémoire○ 1 master, 5 workers
● 230 Go de données sur HDFS○ Fichiers agrégés (4,6 Go chacun)
● Respect de la data locality○ Worker Spark = Datanode HDFS
Spark, ça scale vraiment ?
● 4,6 Go : Shell plus rapide● 46 Go : Spark plus rapide● HDFS ~= disque local● 230 Go + 5 workers ~= 46 Go + 1 worker
Durée de traitement
● Spark : se maintient quand le volume augmente● Spark : plus de workers = plus de débit
○ “Impossible” avec le Shell
Débit de traitement
● Efficace sur données de taille moyenne● Scalabilité horizontale efficace● Stockage :
○ gros fichiers : OK sur HDFS○ petits fichiers : Cassandra ?
Spark sur GCE - Conclusions
@aseigneurin
aseigneurin.github.io
@ippontech
blog.ippon.fr
brownbaglunch.fr