Post on 06-Jul-2015
description
transcript
Hadoop performances
YOUR HUMBLE PRESENTER
Sofian DJAMAA
• Ex-consultant OCTO#expert-performance
#expert-NoSQL
#expert-babyfoot
• Co-fondateur du PerfUG#performance
#presentations #usi #devoxxfr
• Développeur Hadoop @ Criteo
• Amateur de films de requins#avalanche-shark
#sharknado
#mega-shark-vs-giant-octopus
#sharktopus
2
QU’EST-CE QU’HADOOP?
• Stockage: HDFS
– Haute disponibilité
– Large volumétrie
• Traitement: MapReduce
– Divide & conquer
– Parallélisation sur des grosses volumétries (>> PB)
• Stockage + Traitement = « Big Data »
3Copyright © 2013 Criteo.
Confidential
ADAPTER LA CONFIGURATION DU CLUSTER
Le plus simple est dans un premier temps de configurer correctement son cluster Hadoop !
• Eviter les accès disques lents sur les datanodes et les tasktrackers
• RAID
• NAS
• LVM
• Un VLAN dédié au cluster pour éviter les problèmes de réseau
• Un ensemble de machines locales dédiées à Hadoop est l’idéal
• Les machines servant au MR doivent être homogènes au niveau hardware (pour une meilleure parallélisation)
Monitorer l’usage CPU, RAM et les I/O (disques et réseau) via des outils de monitoring
Beaucoup de littérature disponible sur les tailles de machines
Terasort to tune the cluster :)
4
MAP REDUCE
5
MAP REDUCE
6
MAP REDUCE
7
PHASE MAP
• Les fichiers d’entrée sont contenus dans des « input
splits »
• Chaque fichier est assigné à un mapper
• Le mapper effectue la tâche assignée (job)
• Les résultats sont stockés dans un buffer mémoire
temporaire
• Les résultats sont ensuite partitionnés, triés et écrits sur
disque
• Les fichiers sont ensuite envoyés aux reducers
8
PHASE MAP: OPTIMISER LA LECTURE DES FICHIERSTAILLE DES BLOCKS
• Les fichiers d’entrée sont stockés sur HDFS dans des blocks
– Chaque fichier est séparé en input split
– Chaque input split est stocké dans 1 ou plusieurs blocks
• En général, un input split est assigné à un mapper
taille de l’input d’un mapper = taille du fichier / facteur de compression
Considérations de performance :
• Si les input splits sont plus grands que les blocks HDFS : I/O réseau
pour récupérer d’autres blocs sur d’autres DataNodes
• Si les input splits sont plus petits que les blocks HDFS :
fragmentation
• Si les input splits sont trop petits : trop de mappers alloués pour des
petites tâches (overhead de création des mappers)
• dfs.block.size est un paramètre global au cluster !
9
PHASE MAP: OPTIMISER LA LECTURE DES FICHIERSCOMPRESSION
Rappel:
• taille de l’input d’un mapper = taille du fichier / facteur de compression
• Il existe plusieurs formats de compression utilisables dans Hadoop:
– GZIP : utilise le moins de mémoire mais le plus de CPU et n’est pas splittable
– LZO : propose la taille de compression la plus optimale mais gourmand en CPU et mémoire
– Snappy : est le plus rapide mais moins efficient que LZO sur la taille de compression
• Principes généraux des algorithmes de compression
– Algorithmes sans perte
• Utilisation de la redondance : deflate (remplacement de symboles, utilisation de pointeurs), compression par dictionnaire
(stockage d’occurrences à remplacer par un indice)…
– Algorithmes avec perte : JPEG
• Le curseur est à placer entre les ressources du cluster (CPU, I/Os, RAM…) et la taille des input splits :
monitoring !
• Il est possible de combiner la compression à la sérialisation des données : Avro, ProtoBuf, Thrift
10
PHASE MAP: OPTIMISER LA LECTURE DES FICHIERSFORMATS DE FICHIER
• Les fichiers d’entrée sont stockés selon un format :
– Texte (plain, CSV, TSV, JSON…)
– Binaire KV (SequenceFile)
– Binaire Columnar (RCFile, Parquet, ORC)
• taille input record en mémoire = taille de l’input record stocké sur HDFS/
“largeur” du tuple d’entrée
• Pour optimiser la mémoire et le CPU il est possible de ne récupérer qu’un sous-
ensemble des records stockés sur les DataNode : format columnar
• Il existe plusieurs formats columnar :
– RCFile
– Parquet
– ORCFile
• Plus d’informations sur ma présentation au dernier meetup ParisDataGeek
11
PHASE MAP: OPTIMISER LA COLLECTE DES DONNÉES TRAITÉES
• Lorsque les données ont été traitées par la fonction map,
elles sont stockées dans un buffer temporaire avant
d’être écrites sur disque
– Les données sur disque doivent être préparées pour les
reducers : partitionnées, triées et potentiellement compressées.
– Pour éviter des I/O inutiles, ces traitements se font en mémoire
• Si le buffer est trop petit pour recevoir l’ensemble du
dataset, les données sont flushées partiellement sur le
disque
– Selon un ratio : io.sort.factor=10
– Selon la taille du buffer : io.sort.mb=256
• Solutions
– Augmenter la taille du buffer
– Réduire le ratio des meta-data
– Augmenter le nombre de mappers
• Ces paramètres sont à modifier suite à l’exécution de vos
jobs
12
SPILLING EN DÉTAIL
• En réalité le Spilling est un
Partition/Sort/Merge sur disque
13
PHASE MAP: OPTIMISER L’ENVOI DES DONNÉES AUX REDUCERS
• Compression– mapred.compress.map.output : spécifier si les fichiers intermédiaires, résultats de
map, doivent être compressés.
• Combiners– Lorsque les mappers ont traité les différents tuples, les résultats sont stockés en
mémoire avant d’être écrits sur disque
– En prenant pour exemple « WordCount », les mappers ne génèrent qu’une série de tuples du type (« clef » -> 1), (« clef » -> 1), (« clef » -> 1)…
– Si la clef en question est présente de nombreuses fois, le tuple est dupliqué et la taille (et le nombre) des fichiers augmentent impact sur les I/O réseau
– Solution : utiliser un combiner
• Peut être la fonction reduce (dans le cas de WordCount)
• Ou un autre aggrégat
• Partitionnement– Pour que les reducers puissent traiter des données de manière performante
(algorithmes linéaires), les données sont triées et partitionnées par clef aux reducers
– Il est donc important de choisir sa clef de partitionnement afin d’avoir une distribution uniforme des données aux reducers
• Des reducers ou mappers en wait = des ressources bloquées sur le cluster = des jobs en retard !!!!!
• REDUIRE LES I/O
14
PHASE REDUCE
• Les fichiers d’entrées sont partitionnés pour les reducers
– Une clef est assignée à chaque reducer (pour travailler avec des fichiers
provenant de différents mappers)
– C’est pour cela que les combiners et la compression de fichiers sont
importants : ils permettent de réduire le trafic réseau
Etapes :
• Shuffle : récupérer les fichiers produits par les mappers (en réalité
c’est ce sens là)
• Merge : fusionner les fichiers d’entrée déjà triés afin de produire
l’ensemble de données d’entrée
• Reduce : appliquer la fonction de réduction (ex : group by,
somme, moyenne…)
• Write : écrire les résultats finaux sur disque
15
PHASE REDUCE : OPTIMISER LA LECTURE DES FICHIERS D’ENTRÉE
• Les fichiers d’entrée sont récupérés depuis les emplacements
locaux aux mappers charge réseau à prévoir
– Combiners
– Compression
– Partitionnement
• Pour accélérer la récupération des fichiers pouvant être sur
plusieurs mappers (donc machines) différents : multithreading
16
PHASE REDUCE : OPTIMISER LE MERGE DES FICHIERS D’ENTRÉE
• Les fichiers d’entrée sont récupérés et lus par le reducer
• Chaque input est traitée
– Soit en mémoire si le dataset tient
– Soit sur disque si le dataset est supérieur
• Les fichiers sont lus de telle manière à garder l’ordre afin
d’appliquer la fonction de reduce de manière linéaire (Big-O(n))
• De la même manière que lors de l’étape de map, le reducer peut
faire du spilling
– Lorsque la mémoire est trop chargée, les données sont flushées sur
disque et mergées entre elles
• Pour éviter le spilling : io.sort.factor
17
PHASE REDUCE : OPTIMISER L’ECRITURE DES FICHIERS FINAUX
• Partition key (distribute by xxx in Hive)
– pour les reducers
• Car les data sont distribuées par clefs dans les reducers
– si un reducer travaille sur plusieurs partitions
• plusieurs RecordWriters problème de performance
• L’idée est donc de dédier les reducer à l’écriture sur une seule
partition
18
TUNING JVM
• Réutiliser la JVM
– Temps d’initialisation de la JVM à prendre en compte
• Heap
• JIT
• …
• Heap management
– Dimensionner correctement la heap
• Attention au GC
19
OPTIMISATIONS HIVE/CASCADING
• Mapjoins/Hashjoins :
– S’assurer que l’ensemble utilisé pour la jointure tient effectivement en mémoire
• UNION ALL/GROUP BY plutôt que d’utiliser des LEFT JOIN : moins de jobs générés
– Hive peut lancer plusieurs jobs pour une requête
• Sacrifier le temps d’exécution d’un job pour améliorer le temps de requêtage dans Hive
20
RAPPEL
21
mapred.min.split.size
mapred.max.split.size
dfs.block.size (cluster wide)
hive.merge.mapredfiles
hive.merge.smallfiles.avgsize
+ compression
+ input format
mapred.compress.map.output
io.sort.mbio.sort.splill.percentio.sort.factor
mapred.combiner.classmapred.reduce.parallel.copies
mapred.reduce.child.java.optsmapred.map.child.java.opts
CLUSTER MANAGEMENTMRV1
• Utiliser des pools de jobs
22
CLUSTER MANAGEMENTYARN
• La partie stockage ne bouge pas mais le
JobTracker disparaît au profit d’une nouvelle
architecture
Composants :
• Resource Manager
• Application Manager
• Scheduler
• Embarqué dans Hadoop 2
– Possibilité de l’utiliser hors d’Hadoop mais quelques
fonctions sont manquantes (ex : API de communication
avec les executors)
23
CLUSTER MANAGEMENTAPACHE MESOS
• « Resource offer » : CPU, RAM…
• Le master Mesos propose une quantité de
ressources à un framework à exécuter en fonction
de :
– Politiques d’organisation
– Fair scheduling
– Priorité
• Il est aussi possible d’étendre via plugins (à
développer) le système de mise à disponibilité de
ressources
• Côté développeur : définir les tasks et leurs
ressources nécessaire pour le framework scheduler
– API : JAVA/Scala, Python, C++…
• Utilisable avec Hadoop mais aussi avec n’importe
quel type de frameworks (ex : Spark)
24
LE PLUS IMPORTANT : LE MONITORING/PROFILING
• JobTracker
– Possibilité de définir ses propres compteurs pour
debug
• Ganglia
• Nagios/Centreon : monitoring bas niveau (CPU,
RAM, I/O disque, I/O réseau…)
• Starfish : optimisation de la configuration
Hadoop (ex : mapred-site.xml) après analyse
des logs de jobs
25
PETITS CONSEILS
• Si vos data tiennent en RAM… EVITEZ HADOOP !!!!
• Si vos data peuvent tenir en RAM sur peu de machines… EVITEZ HADOOP
– Spark
– Gigaspaces (lol… go Spark)
• En gros… tant que vous pouvez, évitez Hadoop
• Pour des requêtes qui ne prennent que peu de temps, évitez de lancer des jobs MR ou Hive ou autre…
– Le temps d’initialisation des mappers et reducers est très long…
• Et surtout : ME-SU-REZ !!!!
– Il est très difficile d’anticiper les paramètres de configuration du cluster
– Chaque job est différent si le dataset d’entrée n’est pas le même (ou si le job créé des data supplémentaires, cf. EXPLODE)
26
QUESTIONS ?
We can talk about…
#hadoop
27
#scalding
#scala#sharks
#summingbird
#performance
#mechanical-sympathy
#hive #cascading
#JVM