Vous êtes sur la page 1sur 105

Outils Hadoop pour le BigData

Pierre Nerzic - pierre.nerzic@univ-rennes1.fr

fvrier-mars 2016

Abstract

Il sagit des transparents du cours mis sous une forme plus facilement imprimable et lisible.
Ces documents ne sont pas totalement libres de droits. Ce sont des supports de cours
mis votre disposition pour vos tudes sous la licence Creative Commons Attribution - Pas
dUtilisation Commerciale - Partage dans les Mmes Conditions 4.0 International.

Version du 01/06/2017 10:49

Table des matires

1 Principes du Map-Reduce 11
1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.1.1 Pourquoi ce cours ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.1.2 Prfixes multiplicatifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.1.3 Mgadonnes ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.1.4 Prsentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.1.5 Hadoop ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.1.6 Un Data Center . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.1.7 Serveur lame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.2 Hadoop File System (HDFS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.2.1 Prsentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.2.2 Organisation des fichiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.2.3 Commande hdfs dfs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.2.4 changes entre HDFS et le monde . . . . . . . . . . . . . . . . . . . . . . . . 15
1.2.5 Comment fonctionne HDFS ? . . . . . . . . . . . . . . . . . . . . . . . . . . 15

1
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

1.2.6 Organisation des machines pour HDFS . . . . . . . . . . . . . . . . . . . . . 15


1.2.7 Un schma des nodes HDFS . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.2.8 Explications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.2.9 Mode high availability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.2.10 API Java pour HDFS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.2.11 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.2.12 Informations sur les fichiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.2.13 Lecture dun fichier HDFS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.2.14 Cration dun fichier HDFS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.2.15 Compilation et lancement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.3 Algorithmes Map-Reduce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.3.1 Principes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.3.2 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.3.3 Exemple (suite) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.3.4 Exemple en python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.3.5 Explications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.3.6 Paralllisation de Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.3.7 Paralllisation de Reduce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.3.8 Un schma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.4 YARN et MapReduce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.4.1 Quest-ce que YARN ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.4.2 Quest-ce que MapReduce ? . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.4.3 Paires cl-valeurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.4.4 Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.4.5 Schma de Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.4.6 Reduce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.4.7 Schma de Reduce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.4.8 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.4.9 Remarques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.4.10 tapes dun job MapReduce . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.4.11 Un schma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.4.12 Explication du schma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.4.13 Explication du schma (suite) . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.5 Mise en uvre dans Hadoop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

2
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

1.5.1 Prsentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.5.2 Squelette de Mapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.5.3 Explications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.5.4 Types de donnes MapReduce . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.5.5 Interface Writable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.5.6 Classe Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.5.7 Squelette de Reducer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.5.8 Explications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.5.9 Squelette de Traitement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.5.10 Squelette de Traitement (cur) . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.5.11 Explications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.5.12 Compilation et lancement dun traitement . . . . . . . . . . . . . . . . . . . 28

2 Approfondissement sur MapReduce 30


2.1 Jobs MapReduce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.1.1 Cration et lancement dun Job . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.1.2 Configuration dun Job . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.1.3 Spcification des entres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.1.4 Fichiers dentre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.1.5 Format des donnes dentre . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.1.6 Autres formats dentre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.1.7 Changement du sparateur de KeyValueTextInputFormat . . . . . . . . . . 32
2.1.8 Format des donnes intermdiaires . . . . . . . . . . . . . . . . . . . . . . . . 32
2.1.9 Format des donnes de sortie . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.1.10 Fichiers de sortie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.1.11 Post-traitement des rsultats . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.2 Types des cls et valeurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.2.1 Type Writable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.2.2 Classe ArrayWritable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.2.3 Emploi de cette classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.2.4 Mthodes supplmentaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.2.5 Interface Writable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.2.6 Exemple dun Writable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.2.7 Mthodes supplmentaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

3
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

2.2.8 Utilisation dans un Mapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36


2.2.9 Utilisation dans un Reducer . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.2.10 Configuration du Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.3 Efficacit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.3.1 Remarque importante sur lefficacit . . . . . . . . . . . . . . . . . . . . . . . 37
2.3.2 Allocation en dehors des mthodes . . . . . . . . . . . . . . . . . . . . . . . . 38
2.3.3 Pige viter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.4 Entre Map et Reduce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.4.1 Combiner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.4.2 Schma du Combiner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.4.3 Cas demploi dun Combiner . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.4.4 Cas de non-emploi dun Combiner . . . . . . . . . . . . . . . . . . . . . . . . 39
2.4.5 Diffrences entre un Combiner et un Reducer . . . . . . . . . . . . . . . . . . 39
2.4.6 Squelette de Combiner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.5 MapReduce dans dautres langages . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.5.1 Prsentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.5.2 Exemple de Mapper en Python . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.5.3 Algorithme du rducteur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.5.4 Exemple de Reducer en Python . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.5.5 Lancement de ce Job . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

3 tude de cas MapReduce 43


3.0.1 Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.1 Calcul de la variance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.1.1 Dfinition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.1.2 Autre criture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.1.3 criture MapReduce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.1.4 Classe Variance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.1.5 Classe Variance (entte) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.1.6 Classe Variance (constructeur) . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.1.7 Classe Variance (mthodes Writable) . . . . . . . . . . . . . . . . . . . . . 45
3.1.8 Classe Variance (mthode pour map) . . . . . . . . . . . . . . . . . . . . . . 46
3.1.9 Classe Variance (mthode pour combine) . . . . . . . . . . . . . . . . . . . . 46
3.1.10 Classe Variance (mthode pour reduce) . . . . . . . . . . . . . . . . . . . . . 47

4
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

3.1.11 Mapper pour la variance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47


3.1.12 Classe VarianceLongueurLignesMapper . . . . . . . . . . . . . . . . . . . . 47
3.1.13 Combiner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.1.14 Classe VarianceLongueurLignesCombiner . . . . . . . . . . . . . . . . . . . 48
3.1.15 Classe VarianceLongueurLignesReducer . . . . . . . . . . . . . . . . . . . . 48
3.1.16 VarianceLongueurLignesReducer (mthode reduce) . . . . . . . . . . . . . 49
3.1.17 Programme principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.1.18 Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.1.19 Classe VarianceLongueurLignesDriver (mthode run) . . . . . . . . . . . . 50
3.1.20 Classe VarianceLongueurLignesDriver (classes) . . . . . . . . . . . . . . . 50
3.1.21 Classe VarianceLongueurLignesDriver (entre) . . . . . . . . . . . . . . . . 50
3.1.22 Classe VarianceLongueurLignesDriver (sorties) . . . . . . . . . . . . . . . 51
3.1.23 Classe VarianceLongueurLignesDriver (lancement) . . . . . . . . . . . . . 51
3.1.24 Commandes de compilation de cet ensemble . . . . . . . . . . . . . . . . . . 51
3.1.25 Commandes de lancement de cet ensemble . . . . . . . . . . . . . . . . . . . 52
3.1.26 Bilan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3.2 Calcul dune mdiane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3.2.1 Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3.2.2 Principe du calcul en MapReduce . . . . . . . . . . . . . . . . . . . . . . . . 53
3.2.3 Histogramme des longueurs des lignes . . . . . . . . . . . . . . . . . . . . . . 53
3.2.4 Donnes calculer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.2.5 Premier MapReduce (le mapper) . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.2.6 Premier MapReduce (le reducer) . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.2.7 Premier MapReduce (le driver) . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.2.8 Format des fichiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.2.9 Second MapReduce (le mapper) . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.2.10 Second MapReduce (le reducer) . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.2.11 Le post-traitement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.2.12 Rcuprer le nombre de lignes total . . . . . . . . . . . . . . . . . . . . . . . 56
3.2.13 Parcourir lhistogramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.2.14 Calculer la mdiane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.2.15 Bilan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

5
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

4 Pig 58
4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.1.1 Prsentation de Pig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.1.2 Exemple de programme Pig . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.1.3 Comparaison entre SQL et Pig Latin . . . . . . . . . . . . . . . . . . . . . . 58
4.2 Langage Pig Latin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.2.1 Structure dun programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.2.2 Excution dun programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.2.3 Relations et alias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.2.4 Enchanement des instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.2.5 Relations et types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.2.6 Schma dune relation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.2.7 Schmas complexes (tuples) . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.2.8 Schmas complexes (bags) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.2.9 Schmas complexes (maps) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.2.10 Nommage des champs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.3 Instructions Pig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.3.2 Chargement et enregistrement de fichiers . . . . . . . . . . . . . . . . . . . . 62
4.3.3 Affichage de relations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.3.4 Instruction ORDER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.3.5 Instruction LIMIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.3.6 Instruction FILTER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.3.7 Instruction DISTINCT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.3.8 Instruction FOREACH GENERATE . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.3.9 numration de champs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.3.10 Instruction GROUP BY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.3.11 Remarque sur GROUP BY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.3.12 Instruction GROUP ALL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.3.13 Utilisation de GROUP BY et FOREACH . . . . . . . . . . . . . . . . . . . . . . . 66
4.3.14 Oprateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
4.3.15 Utilisation de GROUP et FOREACH . . . . . . . . . . . . . . . . . . . . . . . . . 66
4.3.16 Instruction FOREACH GENERATE complexe . . . . . . . . . . . . . . . . . . . . 67
4.3.17 Instruction FOREACH GENERATE complexe (suite) . . . . . . . . . . . . . . . . 67

6
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

4.3.18 DISTINCT sur certaines proprits . . . . . . . . . . . . . . . . . . . . . . . . 67


4.3.19 Instruction JOIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.3.20 Exemple de jointure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.3.21 Exemple de jointure (suite) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.3.22 Instruction UNION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
4.4 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
4.4.1 Comparaison entre SQL et Pig (le retour) . . . . . . . . . . . . . . . . . . . . 69
4.4.2 Affichage nom et total des achats . . . . . . . . . . . . . . . . . . . . . . . . 69

5 Spark 70
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.1.1 Prsentation de Spark . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.1.2 Intrts de Spark . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.1.3 Premier exemple Spark . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.1.4 Principe du traitement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
5.1.5 Programme pySpark . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
5.1.6 Remarques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
5.1.7 Lancement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.1.8 Commentaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.1.9 Fonction lambda ou fonction nomme ? . . . . . . . . . . . . . . . . . . . . . 72
5.1.10 Fonction lambda ou fonction nomme ? . . . . . . . . . . . . . . . . . . . . . 73
5.1.11 Fonction lambda ou fonction nomme ? . . . . . . . . . . . . . . . . . . . . . 73
5.1.12 Dernire remarque sur les fonctions . . . . . . . . . . . . . . . . . . . . . . . 73
5.2 lments de lAPI Spark . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
5.2.1 Principes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
5.2.2 Dbut dun programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
5.2.3 RDD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
5.2.4 RDD (suite) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
5.2.5 Lire et crire des SequenceFile . . . . . . . . . . . . . . . . . . . . . . . . . . 75
5.2.6 Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
5.2.7 Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
5.2.8 Transformations de type map . . . . . . . . . . . . . . . . . . . . . . . . . . 76
5.2.9 Transformations de type map (suite) . . . . . . . . . . . . . . . . . . . . . . 76
5.2.10 Transformations ensemblistes . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

7
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

5.2.11 Transformations ensemblistes (suite) . . . . . . . . . . . . . . . . . . . . . . . 77


5.2.12 Transformations sur des paires (cl, valeur) . . . . . . . . . . . . . . . . . . . 77
5.2.13 Transformations de type jointure . . . . . . . . . . . . . . . . . . . . . . . . . 78

6 SparkSQL 79
6.1 SparkSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
6.1.1 Prsentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
6.1.2 Dbut dun programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
6.1.3 Crer un DataFrame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
6.1.4 Crer un DataFrame partir dun fichier JSON . . . . . . . . . . . . . . . . 80
6.1.5 Crer un DataFrame partir dun RDD . . . . . . . . . . . . . . . . . . . . . 80
6.1.6 Extraction dinformations dun DataFrame . . . . . . . . . . . . . . . . . . . 80
6.1.7 Donner un nom de table SQL un DataFrame . . . . . . . . . . . . . . . . . 81
6.1.8 Exemple de requte SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
6.2 API SparkSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
6.2.1 Aperu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
6.2.2 Exemple de requte par lAPI . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.2.3 Classe DataFrame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.2.4 Mthodes de DataFrame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.2.5 Agrgation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
6.2.6 Classement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

7 HBase 84
7.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
7.1.1 Prsentation de HBase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
7.1.2 Structure interne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
7.1.3 Tables et rgions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
7.1.4 Diffrences entre HBase et SQL . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.1.5 Structure des donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.1.6 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.1.7 Nature des cls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.1.8 Ordre des cls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.1.9 Choix des cls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.1.10 viter le hotspotting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

8
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

7.2 Travail avec HBase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87


7.2.1 Shell de HBase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7.2.2 Commandes HBase de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.2.3 Cration dune table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.2.4 Destruction dune table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.2.5 Ajout et suppression de n-uplets . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.2.6 Affichage de n-uplets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.2.7 Recherche de n-uplets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.2.8 Filtres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.2.9 Filtres, suite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.2.10 Filtres, suite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.2.11 Comptage de n-uplets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.3 API Java de HBASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.3.2 Imports communs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7.3.3 Cration dune table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7.3.4 Suppression dune table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7.3.5 Manipulation dune table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
7.3.6 Insertion dune valeur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
7.3.7 Transformation en tableaux doctets . . . . . . . . . . . . . . . . . . . . . . . 92
7.3.8 Transformation inverse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
7.3.9 Insertion dune valeur, fonction . . . . . . . . . . . . . . . . . . . . . . . . . 93
7.3.10 Insertion dune valeur, critique . . . . . . . . . . . . . . . . . . . . . . . . . . 94
7.3.11 Extraire une valeur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
7.3.12 Rsultat dun Get . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
7.3.13 Affichage dune cellule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
7.3.14 Parcours des n-uplets dune table . . . . . . . . . . . . . . . . . . . . . . . . 95
7.3.15 Paramtrage dun Scan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
7.3.16 Filtrage dun Scan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

8 Hive et Cassandra 97
8.1 Hive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8.1.1 Prsentation rapide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8.1.2 Dfinition dun schma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

9
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

8.1.3 Types HiveQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98


8.1.4 Sparations des champs pour la lecture . . . . . . . . . . . . . . . . . . . . . 98
8.1.5 Chargement des donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
8.1.6 Liens entre HBase et Hive . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.1.7 Requtes HiveQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.1.8 Autres directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.2 Cassandra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
8.2.1 Prsentation rapide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
8.2.2 Modle de fonctionnement . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
8.2.3 Structure du cluster et donnes . . . . . . . . . . . . . . . . . . . . . . . . . 100
8.2.4 Cohrence des donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
8.2.5 Thorme CAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8.2.6 Modle de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8.2.7 Stockage des donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8.2.8 Rplication et redistribution des donnes . . . . . . . . . . . . . . . . . . . . 101
8.2.9 Informations sur le cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8.2.10 Connexion au shell Cassandra CQL . . . . . . . . . . . . . . . . . . . . . . . 102
8.2.11 Premires commandes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8.2.12 Affichage dinformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8.2.13 Premires commandes, suite . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8.2.14 Identification des n-uplets . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8.2.15 Insertion de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8.2.16 Insertion par fichier CSV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.2.17 Slection de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.2.18 Cration dun index secondaire . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.2.19 Mise jour de n-uplets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
8.2.20 Autres requtes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

10
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Semaine 1

Principes du Map-Reduce

Le cours de cette semaine prsente les concepts suivants :


But du cours
Mgadonnes
Systme de fichiers distribus
Programmation map-reduce

Figure 1: Logo Hadoop

1.1. Introduction
1.1.1. Pourquoi ce cours ?
Selon LinkedIn, les comptences les plus recherches en 2016 dans le monde sont :
1) Cloud and Distributed Computing (Hadoop, Big Data)
2) Statistical Analysis and Data Mining (R, Data Analysis)
10) Storage Systems and Management (SQL)
Voir ces transparents pour la liste en France, qui est trs similaire et inclut la connaissance de Python
en 13e position.

1.1.2. Prfixes multiplicatifs


Connaissez-vous les prfixes ?

signe prfixe facteur exemple reprsentatif


k kilo 103
M mga 106 vitesse de transfert par seconde
G giga 109 DVD, cl USB
T tra 1012 disque dur
P pta 1015
E exa 1018 FaceBook, Amazon
Z zetta 1021 internet tout entier depuis 2010

11
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

1.1.3. Mgadonnes ?
Les mgadonnes ou Big Data sont des collections dinformations qui auraient t considres comme
gigantesques, impossible stocker et traiter, il y a une dizaine dannes.
Internet : Google en 2015 : 10 Eo (10 milliards de Go), Facebook en 2014 : 300 Po de donnes
(300 millions de Go), 4 Po de nouvelles donnes par jour, Amazon : 1 Eo.
BigScience : tlescopes (1 Po/jour), CERN (500 To/jour, 140 Po de stockage), gnome,
environnement. . .
Les informations sont trs difficiles trouver.

La raison est que tout est enregistr sans discernement, dans lide que a pourra tre exploit. Certains
prchent pour que les donnes collectes soient pertinentes (smart data) plutt que volumineuses.

1.1.4. Prsentation
Le traitement daussi grandes quantits de donnes impose des mthodes particulires. Un SGBD
classique, mme haut de gamme, est dans lincapacit de traiter autant dinformations.
Rpartir les donnes sur plusieurs machines (jusqu plusieurs millions dordinateurs)
systme de fichiers spcial permettant de ne voir quun seul espace pouvant contenir des
fichiers gigantesques et/ou trs nombreux (HDFS),
bases de donnes spcifiques (HBase).
Traitements du type map-reduce :
algorithmes faciles crire,
excutions faciles parallliser.

1.1.5. Hadoop ?

Figure 2: Logo Hadoop

Hadoop est un systme de gestion de donnes et de traitements distribus. Il contient de beaucoup


de composants, dont :
HDFS un systme de fichier qui rpartit les donnes sur de nombreuses machines,
YARN un mcanisme dordonnancement de programmes de type MapReduce.
On va dabord prsenter HDFS puis YARN/MapReduce.

1.1.6. Un Data Center


Imaginez 5000 ordinateurs connects entre eux ; cest un cluster :
Voir la figure 3, page 13.

12
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Figure 3: Datacenter Google

Figure 4: Blade server

13
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

1.1.7. Serveur lame


Chacun de ces PC lames (blade computer) ou rack server peut ressembler ceci (4 CPU multi-curs,
128 Go de RAM, 24 To de disques rapides, 5000e) :
Voir la figure 4, page 13.

Il semble que Google utilise des ordinateurs assez basiques, peu chers mais extrmement nombreux
(106 ), consulter wikipedia.

1.2. Hadoop File System (HDFS)


1.2.1. Prsentation
HDFS est un systme de fichiers distribu. Cest dire :
un dispositif de stockage et daccs des fichiers
ces fichiers sont stocks sur un grand nombre de machines de manire rendre invisible la position
exacte dun fichier. Laccs est transparent, quelle que soient les machines qui contiennent les
fichiers.
HDFS permet de voir tous les dossiers et fichiers de ces milliers de machines comme un seul arbre,
contenant des Po de donnes, comme sils taient sur le disque dur local.

1.2.2. Organisation des fichiers


Vu de lutilisateur, HDFS ressemble un systme de fichiers Unix : il y a une racine, des rpertoires
et des fichiers. Les fichiers ont un propritaire, un groupe et des droits daccs comme avec ext4.
Sous la racine /, il y a :
des rpertoires pour les services Hadoop : /hbase, /tmp, /var
un rpertoire pour les fichiers personnels des utilisateurs : /user (attention, ce nest ni /home,
ni /users comme sur dautres systmes Unix). Dans ce rpertoire, il y a aussi trois dossiers
systme : /user/hive, /user/history et /user/spark.
un rpertoire pour dposer des fichiers partager avec tous les utilisateurs : /share

1.2.3. Commande hdfs dfs


La commande hdfs dfs et ses options permet de grer les fichiers et dossiers :
hdfs dfs -help
hdfs dfs -ls [noms...] (pas doption -l)
hdfs dfs -cat nom
hdfs dfs -mv ancien nouveau
hdfs dfs -cp ancien nouveau
hdfs dfs -mkdir dossier
hdfs dfs -rm -f -r dossier (pas -fr)
Il faut toutefois noter que les commandes mettent un certain temps ragir, voir cette page : ce sont
des logiciels crits en Java avec chargement de trs nombreux jars.
Dautre part, nos machines ne sont pas trs rapides.

14
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

1.2.4. changes entre HDFS et le monde


Pour placer un fichier dans HDFS, deux commandes quivalentes :
hdfs dfs -copyFromLocal fichiersrc fichierdst
hdfs dfs -put fichiersrc [fichierdst]
Pour extraire un fichier de HDFS, deux commandes possibles :
hdfs dfs -copyToLocal fichiersrc dst
hdfs dfs -get fichiersrc [fichierdst]
Exemple :

hdfs dfs -mkdir -p livres


wget http://www.textfiles.com/etext/FICTION/dracula
hdfs dfs -put dracula livres
hdfs dfs -ls livres
hdfs dfs -get livres/center_earth

1.2.5. Comment fonctionne HDFS ?


Comme avec de nombreux systmes de fichiers, chaque fichier HDFS est dcoup en blocs de taille
fixe. Un bloc HDFS = 256Mo ( lIUT, jai rduit 64Mo). Selon la taille dun fichier, il lui faudra
un certain nombre de blocs. Sur HDFS, le dernier bloc dun fichier fait la taille restante.
Les blocs sont numrots et chaque fichier sait quels blocs il occupe.
Les blocs dun mme fichier ne sont pas forcment tous sur la mme machine. Les rpartir sur
plusieurs machines permet dy accder simultanment par plusieurs processus.
En plus, dans HDFS, il y a rplication des blocs sur plusieurs machines. Chaque fichier se trouve
donc en plusieurs exemplaires diffrents endroits.

1.2.6. Organisation des machines pour HDFS


Un cluster HDFS est constitu de machines jouant diffrents rles exclusifs entre eux :
Lune des machines est le matre HDFS, appel le namenode. Cette machine contient tous les
noms et blocs des fichiers, comme un gros annuaire tlphonique.
Une autre machine est le secondary namenode, une sorte de namenode de secours, qui enregistre
des sauvegardes de lannuaire intervalles rguliers.
Certaines machines sont des clients. Ce sont des points daccs au cluster pour sy connecter
et travailler.
Toutes les autres machines sont des datanodes. Elles stockent les blocs du contenu des fichiers.

1.2.7. Un schma des nodes HDFS


Voir la figure 5, page 16.

Les datanodes contiennent des blocs, le namenode sait o sont les fichiers : quels blocs et quels
datanodes.
Consulter cette page pour des explications compltes.

15
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Figure 5: Maitre et esclaves HDFS

1.2.8. Explications
Les datanodes contiennent des blocs (nots A,B,C. . . ). Les mmes blocs sont dupliqus (replication)
sur diffrents datanodes, en gnral 3 fois. Cela assure :
fiabilit des donnes en cas de panne dun datanode,
accs parallle par diffrents processus aux mmes donnes.
Le namenode sait la fois :
sur quels blocs sont contenus les fichiers,
sur quels datanodes se trouvent les blocs voulus.
On appelle cela les metadata.
Inconvnient majeur : panne du namenode = mort de HDFS, cest pour viter a quil y a le secondary
namenode. Il archive les metadata, par exemple toutes les heures.

1.2.9. Mode high availability


Comme le namenode est absolument vital pour HDFS mais unique, Hadoop version 2 propose une
configuration appele high availability dans laquelle il y a 2 autres namenodes en secours, capables de
prendre le relais instantanment en cas de panne du namenode initial.
Les namenodes de secours se comportent comme des clones. Ils sont en tat dattente et mis jour
en permanence laide de services appels JournalNodes.
Les namenodes de secours font galement le mme travail que le secondary namenode, darchiver
rgulirement ltat des fichiers, donc ils rendent ce dernier inutile.

1.2.10. API Java pour HDFS


Hadoop propose une API complte pour accder aux fichiers de HDFS. Elle repose sur deux classes
principales :
FileSystem reprsente larbre des fichiers (file system). Cette classe permet de copier des
fichiers locaux vers HDFS (et inversement), renommer, crer et supprimer des fichiers et des
dossiers
FileStatus gre les informations dun fichier ou dossier :
taille avec getLen(),
nature avec isDirectory() et isFile(),

16
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Ces deux classes ont besoin de connatre la configuration du cluster HDFS, laide de la classe
Configuration. Dautre part, les noms complets des fichiers sont reprsents par la classe Path

1.2.11. Exemple
Voici quelques manipulations sur un fichier :

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.Path;

Configuration conf = new Configuration();


FileSystem fs = FileSystem.get(conf);
Path nomcomplet = new Path("/user/etudiant1", "bonjour.txt");
FileStatus infos = fs.getFileStatus(nomcomplet);
System.out.println(Long.toString(infos.getLen())+" octets");
fs.rename(nomcomplet, new Path("/user/etudiant1", "salut.txt"));

Dans la suite, import ...; correspondra ces importations.

1.2.12. Informations sur les fichiers


Exemple complet, afficher la liste des blocs dun fichier :

import ...;

public class HDFSinfo {


public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
Path nomcomplet = new Path("apitest.txt");
FileStatus infos = fs.getFileStatus(nomcomplet);
BlockLocation[] blocks = fs.getFileBlockLocations(
infos, 0, infos.getLen());
for (BlockLocation blocloc: blocks) {
System.out.println(blocloc.toString());
}
}
}

1.2.13. Lecture dun fichier HDFS


Voici un exemple simplifi de lecture dun fichier texte :

import java.io.*;
import ...;
public class HDFSread {

17
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

public static void main(String[] args) throws IOException {


Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
Path nomcomplet = new Path("apitest.txt");
FSDataInputStream inStream = fs.open(nomcomplet);
InputStreamReader isr = new InputStreamReader(inStream);
BufferedReader br = new BufferedReader(isr);
String line = br.readLine();
System.out.println(line);
inStream.close();
fs.close();
}
}

1.2.14. Cration dun fichier HDFS


Inversement, voici comment crer un fichier :
import ...;
public class HDFSwrite {
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
Path nomcomplet = new Path("apitest.txt");
if (! fs.exists(nomcomplet)) {
FSDataOutputStream outStream = fs.create(nomcomplet);
outStream.writeUTF("Bonjour tout le monde !");
outStream.close();
}
fs.close();
}
}

1.2.15. Compilation et lancement


Compiler et lancer ces programmes avec ce Makefile :
HDFSwrite: HDFSwrite.jar
hadoop jar HDFSwrite.jar

HDFSread: HDFSread.jar
hadoop jar HDFSread.jar

HDFSinfo: HDFSinfo.jar
hadoop jar HDFSinfo.jar

hadoop com.sun.tools.javac.Main $<


jar cfe $@ $(basename $<) .

18
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Taper make HDFSwrite par exemple.

1.3. Algorithmes Map-Reduce


1.3.1. Principes
Le but est de recueillir une information synthtique partir dun jeu de donnes.
Exemples sur une liste darticles dfinis par leur prix :
calculer le montant total des ventes dun article,
calculer larticle le plus cher,
calculer le prix moyen des articles.
Pour chacun de ces exemples, le problme peut scrire sous la forme de la composition de deux
fonctions :
map : extraction/calcul dune information sur chaque n-uplet,
reduce : regroupement de ces informations.

1.3.2. Exemple
Soient les 4 n-uplets fictifs suivants :

Id Marque Modle Prix


1 Renault Clio 4200
2 Fiat 500 8840
3 Peugeot 206 4300
4 Peugeot 306 6140

Calculer le prix maximal, moyen ou total peut scrire laide dalgorithmes, tudis en premire
anne, du type :

pour chaque n-uplet, faire :


valeur = FonctionM(n-uplet courant)
retourner FonctionR(valeurs rencontres)

1.3.3. Exemple (suite)


FonctionM est une fonction de correspondance : elle calcule une valeur qui nous intresse
partir dun n-uplet,
FonctionR est une fonction de regroupement (agrgation) : maximum, somme, nombre, moyenne,
distincts. . .
Par exemple, FonctionM extrait le prix dune voiture, FonctionR calcule le max dun ensemble de
valeurs :

pour chaque voiture, faire :


prix = getPrix(voiture courante)
retourner max(prix rencontrs)

19
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Pour lefficacit, les valeurs intermdiaires ne sont pas stockes mais transmises entre les deux fonctions
par une sorte de tube (comme dans Unix). Le programme ne scrit donc pas tout fait comme a.

1.3.4. Exemple en python

data = [
{'id':1, 'marque':'Renault', 'modele':'Clio', 'prix':4200},
{'id':2, 'marque':'Fiat', 'modele':'500', 'prix':8840},
{'id':3, 'marque':'Peugeot', 'modele':'206', 'prix':4300},
{'id':4, 'marque':'Peugeot', 'modele':'306', 'prix':6140} ]

## retourne le prix de la voiture passe en paramtre


def getPrix(voiture): return voiture['prix']

## affiche la liste des prix des voitures


print map(getPrix, data)

## affiche le plus grand prix


print reduce(max, map(getPrix, data) )

1.3.5. Explications
Lcriture map(fonction, liste) applique la fonction chaque lment de la liste. Elle effectue
la boucle pour de lalgorithme prcdent et retourne la liste des prix des voitures. Ce
rsultat contient autant de valeurs que dans la liste dentre.
La fonction reduce(fonction, liste) agglomre les valeurs de la liste par la fonction et
retourne le rsultat final1 .
Ces deux fonctions constituent un couple map-reduce et le but de ce cours est dapprendre les
comprendre et les programmer.
Le point cl est la possibilit de parallliser ces fonctions afin de calculer beaucoup plus vite sur une
machine ayant plusieurs curs ou sur un ensemble de machines relies entre elles.

1.3.6. Paralllisation de Map


La fonction map est par nature paralllisable, car les calculs sont indpendants.
Exemple, pour 4 lments traiter :
valeur1 = FonctionM(element1 )
valeur2 = FonctionM(element2 )
valeur3 = FonctionM(element3 )
valeur4 = FonctionM(element4 )
Les quatre calculs peuvent se faire simultanment, par exemple sur 4 machines diffrentes, condition
que les donnes y soient copies.
1
En python, au lieu de reduce(max, liste), on peut crire max(liste) directement.

20
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Remarque : il faut que la fonction mappe soit une pure fonction de son paramtre, quelle nait pas
deffet de bord tels que modifier une variable globale ou mmoriser ses valeurs prcdentes.

1.3.7. Paralllisation de Reduce


La fonction reduce se paralllise partiellement, sous une forme hirarchique, par exemple :
inter1 et 2 = FonctionR(valeur1 , valeur2 )
inter3 et 4 = FonctionR(valeur3 , valeur4 )
resultat = FonctionR(inter1 et 2 , inter3 et 4 )
Seuls les deux premiers calculs peuvent tre faits simultanment. Le 3e doit attendre. Sil y avait
davantage de valeurs, on procderait ainsi :
1. calcul parallle de la FonctionR sur toutes les paires de valeurs issues du map
2. calcul parallle de la FonctionR sur toutes les paires de valeurs intermdiaires issues de la phase
prcdente.
3. et ainsi de suite, jusqu ce quil ne reste quune seule valeur.

1.3.8. Un schma

Figure 6: Arbre Map-Reduce

1.4. YARN et MapReduce


1.4.1. Quest-ce que YARN ?
YARN (Yet Another Resource Negociator) est un mcanisme permettant de grer des travaux (jobs)
sur un cluster de machines.
YARN permet aux utilisateurs de lancer des jobs Map-Reduce sur des donnes prsentes dans HDFS,
et de suivre (monitor) leur avancement, rcuprer les messages (logs) affichs par les programmes.
ventuellement YARN peut dplacer un processus dune machine lautre en cas de dfaillance ou
davancement jug trop lent.
En fait, YARN est transparent pour lutilisateur. On lance lexcution dun programme MapReduce
et YARN fait en sorte quil soit excut le plus rapidement possible.

21
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

1.4.2. Quest-ce que MapReduce ?


MapReduce est un environnement Java pour crire des programmes destins YARN. Java nest pas
le langage le plus simple pour cela, il y a des packages importer, des chemins de classes fournir. . .
Il y a plusieurs points connatre, cest la suite de ce cours :
Principes dun job MapReduce dans Hadoop,
Programmation de la fonction Map,
Programmation de la fonction Reduce,
Programmation dun job MapReduce qui appelle les deux fonctions,
Lancement du job et rcupration des rsultats.
Commenons dabord avec le type des donnes changes entre Map et Reduce.

1.4.3. Paires cl-valeurs


Cest en fait un peu plus compliqu que ce qui a t expliqu initialement. Les donnes changes
entre Map et Reduce, et plus encore, dans la totalit du job sont des paires (cl, valeur) :
une cl : cest nimporte quel type de donnes : entier, texte. . .
une valeur : cest nimporte quel type de donnes
Tout est reprsent ainsi. Par exemple :
un fichier texte est un ensemble de (n de ligne, ligne).
un fichier mto est un ensemble de (date et heure, temprature)
Cest cette notion qui rend les programmes assez tranges au dbut : les deux fonctions Map et
Reduce reoivent et mettent de telles paires.

1.4.4. Map
La fonction Map reoit une paire en entre et peut produire un nombre quelconque de paires en
sortie : aucune, une ou plusieurs, volont. Les types des entres et des sorties sont comme on veut.
Cette spcification trs peu contrainte permet de nombreuses choses. En gnral, les paires que reoit
Map sont constitues ainsi :
la valeur de type text est lune des lignes ou lun des n-uplets du fichier traiter
la cl de type integer est la position de cette ligne dans le fichier (on lappelle offset en bon
franais)
Il faut comprendre que YARN lance une instance de Map pour chaque ligne de chaque fichier des
donnes traiter. Chaque instance traite la ligne quon lui a attribue et produit des paires en sortie.

1.4.5. Schma de Map


Voir la figure 7, page 23.

Les tches MAP traitent chacune une paire et produisent 0..n paires. Il se peut que les mmes cls
et/ou valeurs soient produites.

22
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Figure 7: Tches MAP et paires (cl, valeur)

1.4.6. Reduce
La fonction Reduce reoit une liste de paires en entre. Ce sont les paires produites par les instances
de Map. Reduce peut produire un nombre quelconque de paires en sortie, mais la plupart du temps,
cest une seule. Par contre, le point crucial, cest que les paires dentre traites par une instance de
Reduce ont toutes la mme cl.
YARN lance une instance de Reduce pour chaque cl diffrente que les instances de Map ont produit,
et leur fournit uniquement les paires ayant la mme cl. Cest ce qui permet dagrger les valeurs.
En gnral, Reduce doit faire un traitement sur les valeurs, comme additionner toutes les valeurs
entre elles, ou dterminer la plus grande des valeurs. . .
Quand on conoit un traitement MapReduce, on doit rflchir aux cls et valeurs ncessaires pour
que a marche.

1.4.7. Schma de Reduce

Figure 8: Tches Reduce et paires (cl, valeur)

Les tches Reduce reoivent une liste de paires ayant toutes la mme cl et produisent une paire qui
contient le rsultat attendu. Cette paire en sortie peut avoir la mme cl que celle de lentre.

1.4.8. Exemple
Une entreprise de tlphonie veut calculer la dure totale des appels tlphoniques dun abonn
partir dun fichier CSV contenant tous les appels de tous les abonns (n dabonn, n appel, date,
dure dappel). Ce problme se traite ainsi :
1. En entre, on a le fichier des appels (1 appel par ligne)
2. YARN lance une instance de la fonction Map par appel

23
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

3. Chaque instance de Map reoit une paire (offset, ligne) et produit une paire (n abonn, dure)
ou rien si cest pas labonn quon veut. NB: loffset ne sert rien ici.
4. YARN envoie toutes les paires vers une seule instance de Reduce (car il ny a quune seule cl
diffrente)
5. Linstance de Reduce additionne toutes les valeurs des paires quelle reoit et produit une seule
paire en sortie (n abonn, dure totale)

1.4.9. Remarques
En ralit, il ny a pas quune seule instance de Reduce, il y en a plusieurs pour faire la rduction
de manire hirarchique plus rapidement. Car en gnral lalgorithme quon crit dans la fonction
Reduce est une boucle sur chaque valeur reue.
galement, en ralit, il ny a pas une instance de Map par ligne de donnes. Cest la vision quon
peut avoir en tant que programmeur, mais a conduirait un nombre gigantesque dinstances pour
traiter un norme fichier. En fait, YARN instancie un seul Mappeur par machine esclave et appelle
sa mthode map plusieurs reprises pour traiter les donnes squentiellement.
Ce cours fait plusieurs simplifications comme cela afin de rester comprhensible pour une premire
dcouverte de Hadoop.

1.4.10. tapes dun job MapReduce


Un job MapReduce comprend plusieurs phases :
1. Prtraitement des donnes dentre, ex: dcompression des fichiers
2. Split: sparation des donnes en blocs traitables sparment et mise sous forme de (cl, valeur),
ex: en lignes ou en n-uplets
3. Map: application de la fonction map sur toutes les paires (cl, valeur) formes partir des
donnes dentre, cela produit dautres paires (cl, valeur) en sortie
4. Shuffle & Sort: redistribution des donnes afin que les paires produites par Map ayant les
mmes cls soient sur les mmes machines
5. Reduce: agrgation des paires ayant la mme cl pour obtenir le rsultat final.

1.4.11. Un schma

1.4.12. Explication du schma


1. Au dbut, YARN se renseigne sur lemplacement des donnes auprs du namenode et les fait
dcompresser si besoin par les datanodes concerns.
2. La phase Split consiste construire des paires (n de n-uplet, n-uplet) fournir aux tches Map.
3. YARN cre des processus Map sur chaque machine contenant une partie des donnes et leur
fournit les paires de leur machine successivement.
4. Chaque tche Map analyse ses donnes et met ou non une paire. a peut consister convertir
des chanes en nombres, faire des calculs, etc.

1.4.13. Explication du schma (suite)


5. YARN trie les paires sortant de Map selon leur cl et les envoie sur la machine qui fait tourner
la tche Reduce concerne par cette cl.

24
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Figure 9: tapes MapReduce

6. Les tches Reduce reoivent une liste de paires et effectuent la rduction des valeurs (max, sum,
avg. . . ). Elles mettent seulement la valeur finale. Elles peuvent tre mises en cascade quand il
y a beaucoup de paires.

1.5. Mise en uvre dans Hadoop


1.5.1. Prsentation
On arrive la partie la plus technique : la programmation dun job MapReduce en Java.
Il faut dfinir trois classes :
Une sous-classe de Mapper. Elle contient une seule mthode, appele map qui reoit une paire
cl-valeur en paramtre. Elle gnre un nombre quelconque de paires.
Une sous-classe de Reducer. Elle contient galement une seule mthode, appele reduce qui
reoit une liste de paires en paramtre. Elle gnre une seule paire.
Une classe gnrale qui cre un Job faisant rfrence aux deux prcdentes classes.
Les deux premires sont des patrons (templates) paramtres par les types des cls et des valeurs.

1.5.2. Squelette de Mapper

public class TraitementMapper


extends Mapper<TypCleE,TypValE, TypCleI,TypValI>
{
@Override
public void map(TypCleE cleE, TypValE valE,
Context context) throws Exception
{
/** traitement: cleI = ..., valI = ... **/
TypCleI cleI = new TypCleI(...);
TypValI valI = new TypValI(...);

25
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

context.write(cleI, valI);
}
}

1.5.3. Explications
La classe Mapper est paramtre par 4 types. Hlas, ce ne sont pas les types standard de Java, mais
des types spciaux permettant de transmettre efficacement des donnes entre les diffrents ordinateurs
du cluster. a complique lgrement les programmes.

type description
Text chane UTF8 quelconque
BooleanWritable reprsente un boolen
IntWritable entier 32 bits
LongWritable entier 64 bits
FloatWritable rel IEEE 32 bits
DoubleWritable rel IEEE 64 bits

1.5.4. Types de donnes MapReduce


Les types Text, IntWritable. . . sont des implmentations dune interface appele Writable. Cette
interface comprend :
un constructeur. On peut mettre la valeur initiale en paramtre.

IntWritable val = new IntWritable(34);

un modificateur : void set(nouvelle valeur);

val.set(35);

un accesseur : type get()

int v = val.get();

1.5.5. Interface Writable


Elle permet la srialisation, cest dire lcriture dune structure de donnes sous forme doctets et
lopration inverse, la dsrialisation qui permet de reconstruire une structure de donnes partir
doctets.
La srialisation est ncessaire pour changer des donnes entre machines. Cela fait partie de la
technique appele Remote Procedure Call (RPC). On ne peut pas simplement changer les octets
internes car les machines du cluster ne sont pas obligatoirement toutes pareilles : nombre doctets,
ordre des octets. . .
Cette interface nest pas limite des types simples mais peut grer des collections (tableaux, listes,
dictionnaires. . . ) et classes.

26
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

1.5.6. Classe Text


La classe Text permet de reprsenter nimporte quelle chane. Elle possde quelques mthodes
connatre :
String toString() extrait la chane Java
int getLength() retourne la longueur de la chane
int charAt(int position) retourne le code UTF8 (appel point) du caractre prsent cette
position
Ces mthodes ne sont pas suffisantes. Il faudra souvent convertir les Text en chanes.

1.5.7. Squelette de Reducer

public class TraitementReducer


extends Reducer<TypCleI,TypValI, TypCleS,TypValS>
{
@Override
public void reduce(TypCleI cleI, Iterable<TypValI> listeI,
Context context) throws Exception
{
TypCleS cleS = new TypCleS();
TypValS valS = new TypValS();
for (TypValI val: listeI) {
/** traitement: cleS.set(...), valS.set(...) **/
}
context.write(cleS, valS);
}
}

1.5.8. Explications
La mthode reduce reoit une collection de valeurs venant du Mapper. CleI et ValeursI sont les cls
et valeurs intermdiaires. Il faut itrer sur chacune pour produire la valeur de sortie du rducteur.
Comme pour map, la classe est paramtre par les types des cls et des valeurs manipuler. Ce sont
des Writable : Text, IntWritable. . .
Une chose cruciale nest pas du tout vrifie par Java : il est obligatoire que les types des cls TypCleI
et valeurs dentre TypValI du rducteur soient exactement les mmes que les types des cls et valeurs
de sortie du mapper. Si vous mettez des types diffrents, a passera la compilation mais plantera
lexcution.

1.5.9. Squelette de Traitement


Voici la classe principale qui cre et lance le job MapReduce :

27
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

public class Traitement extends Configured implements Tool


{
public int run(String[] args) throws Exception
{
/* voir transparent suivant */
}

public static void main(String[] args) throws Exception


{
if (args.length != 2) System.exit(-1);
Traitement traitement = new Traitement();
System.exit( ToolRunner.run(traitement, args) );
}
}

1.5.10. Squelette de Traitement (cur)


La mthode run contient ceci :

public int run(String[] args) throws Exception


{
Configuration conf = this.getConf();
Job job = Job.getInstance(conf, "traitement");
job.setJarByClass(Traitement.class);

job.setMapperClass(TraitementMapper.class);
job.setReducerClass(TraitementReducer.class);

FileInputFormat.addInputPath(job, new Path(args[0]));


FileOutputFormat.setOutputPath(job, new Path(args[1]));

boolean success = job.waitForCompletion(true);


return success ? 0 : 1;
}

1.5.11. Explications
La mthode run est charge de crer et lancer un Job. Il faut noter que la spcification Hadoop a
beaucoup chang depuis les premires versions. Il faut actuellement faire ainsi :
1. Obtenir une instance de Configuration. Elle contient les options telles que les formats des
fichiers, leur nom HDFS complet, leur codec de compression. . . voir le prochain cours.
2. Crer un Job, lui indiquer les classes concernes : mapper et reducer.
3. Fournir les noms complets des fichiers traiter et produire.
4. Indiquer les types des cls et valeurs. Par dfaut, ce sont des Text.
5. Attendre la fin du job et retourner un code derreur.
Davantage de dtails au prochain cours.

28
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

1.5.12. Compilation et lancement dun traitement


1. Compilation

hadoop com.sun.tools.javac.Main Traitement*.java

2. Emballage dans un fichier jar. NB: cest plus compliqu quand il y a des packages.

jar cfe Traitement.jar Traitement Traitement*.class

3. Prparation : mettre en place les fichiers traiter, supprimer le dossier de sortie

hdfs dfs -rm -r -f sortie

4. Lancement

yarn jar Traitement.jar entree sortie

5. Rsultats dans le dossier sortie

hdfs dfs -cat sortie/part-r-00000

29
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Semaine 2

Approfondissement sur MapReduce

Le cours de cette semaine prsente davantage de dtails sur les jobs MapReduce dans YARN :
spcification des entres
spcification des paires (cl, valeurs)
spcification des sorties
traitement de certains fichiers
MapReduce dans dautres langages sur YARN

2.1. Jobs MapReduce


2.1.1. Cration et lancement dun Job
Revenons sur le lancement dun job MapReduce :

public int run(String[] args) throws Exception


{
Configuration conf = this.getConf();
Job job = Job.getInstance(conf, "traitement");
job.setJarByClass(Traitement.class);
job.setMapperClass(TraitementMapper.class);
job.setReducerClass(TraitementReducer.class);

FileInputFormat.addInputPath(job, new Path(args[0]));


FileOutputFormat.setOutputPath(job, new Path(args[1]));

boolean success = job.waitForCompletion(true);


return success ? 0 : 1;
}

2.1.2. Configuration dun Job


Pour commencer avec des choses simples, il est possible de dfinir quelques options concernant un
Job :
void setNumReduceTasks(int tasks) dfinit le nombre de tches de type Reduce. Par contre,
il nest pas possible de modifier le nombre de tches Map parce que a dpend uniquement des
donnes traiter.
void setPriority(JobPriority priorit) fournir JobPriority.HIGH, JobPriority.LOW. . .

30
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Exemple :

job.setNumReduceTasks(1);
job.setPriority(JobPriority.LOW);

2.1.3. Spcification des entres


Les lignes suivantes spcifient ce quon veut traiter :

FileInputFormat.addInputPath(job, new Path(args[0]));


job.setInputFormatClass(TextInputFormat.class);

La premire ligne indique quels sont les fichiers HDFS traiter,


La seconde ligne indique le type de contenu de ces fichiers.
Voici davantage dinformations sur ces instructions.

2.1.4. Fichiers dentre


Cette instruction indique o prendre les fichiers traiter :

FileInputFormat.addInputPath(job, new Path("NOMCOMPLET"));

Cest un appel une mthode statique dans la classe FileInputFormat.


Si le chemin fourni est un dossier, alors tous ses fichiers sont employs,
Si les fichiers trouvs sont compresss (extensions .gz, .bz2, .lzo. . . ), ils sont automatiquement
dcompresss.
Les sous-classes de FileInputFormat telles que TextInputFormat et KeyValueTextInputFormat
sont galement responsables de la sparation (split) des donnes en paires (cl,valeur).

2.1.5. Format des donnes dentre


Cette instruction spcifie le type des fichiers lire et implicitement, les cls et les valeurs rencontres :

job.setInputFormatClass(TextInputFormat.class);

Important: les types des cls et valeurs du Mapper doivent concider avec la classe indique pour le
fichier.
Ici, la classe TextInputFormat est une sous-classe de FileInputFormat<LongWritable,Text>. Donc
il faut crire :

public class TraitementMapper


extends Mapper<LongWritable,Text, TypCleI,TypValI>
{
@Override
public void map(LongWritable cleE, Text valE, ...

31
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

2.1.6. Autres formats dentre


Il existe dautres formats dentre, comme KeyValueTextInputFormat qui est capable de lire des
fichiers dj au format (cl, valeur) :
les lignes se finissent par un '\n' ou un '\r' (cause srement un pb avec des fichiers Windows qui
ont les deux la fois)
chaque ligne est un couple (cl, valeur)
cest une tabulation '\t' qui spare la cl de la valeur
ces deux informations sont des Text

job.setInputFormatClass(KeyValueTextInputFormat.class);

public class TraitementMapper


extends Mapper<Text,Text, TypCleI,TypValI>

2.1.7. Changement du sparateur de KeyValueTextInputFormat


On peut changer le sparateur, par exemple une virgule :
Configuration conf = new Configuration();
conf.set(
"mapreduce.input.keyvaluelinerecordreader.key.value.separator",
",");

Job job = new Job(conf);


job.setInputFormatClass(KeyValueTextInputFormat.class);

2.1.8. Format des donnes intermdiaires


Les types des cls et valeurs sortant du mapper et allant au reducer, nots TypCleI et TypValI dans
ce qui prcde, sont dfinis par les instructions suivantes :
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);

Elles forcent la dfinition du mapper et du reducer ainsi :

class TraitementMapper extends Mapper<..., Text, IntWritable>


class TraitementReducer extends Reducer<Text, IntWritable, ...>

Elles sont absolument obligatoires quand ce ne sont pas les types par dfaut, ClassCastException
lors du lancement du reducer sinon.

2.1.9. Format des donnes de sortie


Voici les instructions qui spcifient le format du fichier de sortie :

32
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

job.setOutputFormatClass(TextOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(DoubleWritable.class);

Ce doivent tre les types de sortie du Reducer :

class TraitementReducer
extends Reducer<..., Text, DoubleWritable>

La classe TextOutputFormat<K,V> est paramtre par les types des cls et des valeurs. Par dfaut,
ce sont tous deux des Text.
Il existe dautres classes pour produire les donnes de sortie (voir plus loin), dont des crivains sur
mesure (voir en TP).

2.1.10. Fichiers de sortie


Les rsultats du job sont enregistrs dans des fichiers situs dans le dossier indiqu par :

FileOutputFormat.setOutputPath(job, new Path("DOSSIER"));

YARN enregistre un fichier par Reducteur final. Leurs noms sont part-r-00000, part-r-00001,. . .

2.1.11. Post-traitement des rsultats


Au lieu de rcuprer un simple fichier, on peut afficher proprement le rsultat final :

job.setOutputFormatClass(SequenceFileOutputFormat.class);
if (job.waitForCompletion(true)) {
SequenceFile.Reader.Option fichier =
SequenceFile.Reader.file(new Path(args[1],"part-r-00000"));
SequenceFile.Reader reader =
new SequenceFile.Reader(conf, fichier);
IntWritable annee = new IntWritable();
FloatWritable temperature = new FloatWritable();
while (reader.next(annee, temperature)) {
System.out.println(annee + " : " + temperature);
}
reader.close();
}

2.2. Types des cls et valeurs


2.2.1. Type Writable
Nous avons vu la semaine dernire quil fallait employer des Writable : Text, IntWritable,
FloatWritable. Linterface Writable est une optimisation/simplification de linterface Serializable

33
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

de Java. Celle de Java construit des structures plus lourdes que celle de Hadoop, parce quelle conti-
ennent les noms des types des donnes, tandis que les Writable ne contiennent que les octets des
donnes, et dautre part les Writable sont modifiables (mutables).
Il existe diffrents types de Writable pour des collections. On va donner lexemple dun Writable
spcifique drivant dun type tableau.

2.2.2. Classe ArrayWritable


Le type ArrayWritable reprsente des tableaux de Writable quelconques. Il est prfrable de la
sous-classer pour quelle contienne les donnes voulues :

public class IntArrayWritable extends ArrayWritable {


public IntArrayWritable() { super(IntWritable.class); }
public IntArrayWritable(int size) {
super(IntWritable.class);
IntWritable[] values = new IntWritable[size];
for (int i=0; i<size; i++) values[i] = new IntWritable();
set(values);
}
public IntWritable itemAt(int index) {
Writable[] values = get();
return (IntWritable)values[index];
}
}

2.2.3. Emploi de cette classe


Voici un exemple presque fonctionnel qui montre comment crer et utiliser une telle structure :

public class TraitementMapper


extends Mapper<LongWritable, Text, Text, IntArrayWritable>
{
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException
{
Text cle = new Text("ok");
IntArrayWritable valeur = new IntArrayWritable(2);
valeur.itemAt(0).set(123);
valeur.itemAt(1).set(value.getLength());
context.write(cle, valeur);
}
}

2.2.4. Mthodes supplmentaires


Vous pouvez rajouter vos propres mthodes cette classe. Par exemple pour additionner un autre
IntArrayWritable this :

34
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

public void add(IntArrayWritable autre)


{
// rcuprer les valeurs
Writable[] values = this.get();
Writable[] autres = autre.get();

// this = this + autre


for (int i=0; i<values.length; i++) {
IntWritable val = (IntWritable)values[i];
IntWritable aut = (IntWritable)autres[i];
val.set(val.get() + aut.get());
}
}

2.2.5. Interface Writable


Linterface Writable gre des contenus transmis entre un mapper et un reducer. Pour limplmenter,
il suffit de deux mthodes :
public void write(DataOutput sortie) : elle crit des donnes sur sortie,
public void readFields(DataInput entree) : vous devez extraire les mmes donnes et
dans le mme ordre.
Les deux classes DataInput et DataOutput sont des sortes de flots binaires (binary stream), comme
des fichiers. Ils possdent toutes les mthodes pour lire/crire les types courants :
DataInput : readBoolean(), readInt(), readFloat(), readLine(), etc.
DataOutput : writeBoolean(b), writeInt(i), writeFloat(f), writeLine(s). . .

2.2.6. Exemple dun Writable


Voici un exemple pour calculer une moyenne dans le reducer :

public class Moyenne implements Writable


{
private double total = 0.0;
private long nombre = 0L;

public void write(DataOutput sortie) throws IOException {


sortie.writeDouble(total);
sortie.writeLong(nombre);
}

public void readFields(DataInput entree) throws IOException {


total = entree.readDouble();
nombre = entree.readLong();
}
}

35
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

2.2.7. Mthodes supplmentaires


On peut lui ajouter des mthodes pour faciliter la programmation du mapper et du reducer :

public void set(double valeur) {


total = valeur;
nombre = 1L;
}

public void add(Moyenne autre) {


total += autre.total;
nombre += autre.nombre;
}

public double getMoyenne() {


return total/nombre;
}

2.2.8. Utilisation dans un Mapper


Voici comment on peut lemployer ct mapper :

public class MoyenneHauteurArbresMapper


extends Mapper<LongWritable, Text, Text, Moyenne>
{
@Override
public void map(LongWritable cleE, Text valeurE, Context context) throws Exception
{
Arbre.fromLine(valeurE.toString());
Text cleI = new Text(Arbre.getGenre());
Moyenne valeurI = new Moyenne();
valeurI.set(Arbre.getHauteur());
context.write(cleI, valeurI);
}
}

NB: il manque tout ce qui est exception et filtrage des lignes.

2.2.9. Utilisation dans un Reducer


Voici comment on peut lemployer ct reducer :

public class MoyenneHauteurArbresReducer


extends Reducer<Text, Moyenne, Text, DoubleWritable>
{
@Override
public void reduce(Text cleI, Iterable<Moyenne> valeursI, Context context) throws Exce
{

36
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

// cumuler les totaux et nombres de valeursI


Moyenne moyenne = new Moyenne();
for (Moyenne moy : valeursI) {
moyenne.add(moy);
}
valeurS = new DoubleWritable(moyenne.getMoyenne());
context.write(cleI, valeurS);
}
}

2.2.10. Configuration du Driver


Pour finir, voici le cur du driver :
Configuration conf = this.getConf();
Job job = Job.getInstance(conf, "MoyenneHauteurArbres Job");
job.setJarByClass(MoyenneHauteurArbresDriver.class);
job.setMapperClass(MoyenneHauteurArbresMapper.class);
job.setReducerClass(MoyenneHauteurArbresReducer.class);
FileInputFormat.addInputPath(job, new Path("arbres.csv"));
job.setInputFormatClass(TextInputFormat.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Moyenne.class);
FileOutputFormat.setOutputPath(job, new Path("resultats"));
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(DoubleWritable.class);
boolean success = job.waitForCompletion(true);

2.3. Efficacit
2.3.1. Remarque importante sur lefficacit
Il faut viter toute allocation mmoire rpte comme :

for (int i=0; i<10000; i++) {


IntWritable valeur = new IntWritable(i);
...
}

Il vaut mieux crer les objets hors de la boucle et utiliser leur modificateur ainsi :

IntWritable valeur = new IntWritable();


for (int i=0; i<10000; i++) {
valeur.set(i);
...
}

Cest possible parce que les Writable sont raffectables (mutables).

37
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

2.3.2. Allocation en dehors des mthodes


En poursuivant de la mme manire, on enlve les allocations des mthodes :

public class TraitementMapper extends Mapper<...>


{
private TypCleI cleI = new TypCleI(...);
private TypValI valI = new TypValI(...);
@Override
public void map(TypCleE cleE, TypValE valE, Context context)...
{
cleI.set(...);
valI.set(...);
context.write(cleI, valI);
}
}

2.3.3. Pige viter


Noubliez pas que le reducer peut tre relanc plusieurs fois :

public class TraitementReducer extends Reducer<...>


{
private TypValI valS = new TypValS(...);
private Moyenne moyenne = new Moyenne();
@Override
public void reduce(Text cleI, Iterable<Moyenne> valeursI, ...
{
// BUG : moyenne n'a pas t remise zro !!!
for (Moyenne valeurI : valeursI) {
moyenne.add(valeurI);
}
valeurS = new DoubleWritable(moyenne.getMoyenne());
context.write(cleI, valeurS);
}
}

2.4. Entre Map et Reduce


2.4.1. Combiner
Pour linstant, nous avons vu deux sortes de tches : map et reduce. Nous avons vu que les paires
(cl,valeur) produites par les tches map sont envoyes par une tape appele shuffle and sort travers
le rseau vers les tches rduce de manire regrouper toutes les cls identiques sur la mme machine.
Quand on traite des donnes volumineuses, a peut devenir trop lent. Hadoop propose un troisime
intervenant, entre map et reduce qui effectue un traitement local des paires produites par map. Cest
le Combiner . Son travail est de faire une premire tape de rduction de tout ce qui est produit
sur une machine.

38
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

2.4.2. Schma du Combiner

Figure 10: Cominer


Il traite des paires ayant la mme cl sur la mme machine que les tches Map. Les paires quil met
sont envoyes aux reducers.

2.4.3. Cas demploi dun Combiner


Le combiner permet de gagner du temps, non seulement en regroupant les valeurs prsentes sur la
mme machine, mais en faisant un petit calcul au passage.
Par exemple, pour calculer la plus grande valeur dun ensemble de donnes, il peut calculer le
maximum de ce quil reoit localement, et au lieu de produire une liste de valeurs destination des
rducteurs, il nen produit quune seule.
De fait, dans certains cas, le combiner est identique au reducer. On peut utiliser la mme classe pour
les deux.
job.setMapperClass(TraitementMapper.class);
job.setCombinerClass(TraitementReducer.class);
job.setReducerClass(TraitementReducer.class);

2.4.4. Cas de non-emploi dun Combiner


Que pensez-vous de ceci ? On veut calculer la temprature moyenne par station mto depuis 1901.
Les tches map parcourent les relevs, extraient lidentifiant de la station mto et la temprature
releve, ceci pour chaque mesure. Les paires sont (idstation, temperature). Les tches reduce calculent
la moyenne par station mto.
Peut-on utiliser un combiner charg de calculer la moyenne des temprature par station sur chaque
machine contenant un map ?
On ne peut pas employer de combiner quand loprateur dagrgation nest pas commutatif ou pas
associatif. Les oprateurs somme, min et max sont commutatifs et associatifs, mais pas le calcul
dune moyenne.

2.4.5. Diffrences entre un Combiner et un Reducer


1. Les paramtres dentre et de sortie du Combiner doivent tre identiques ceux de sortie du
Mapper, tandis que les types des paramtres de sortie du Reducer peuvent tre diffrents de
ceux de son entre.

39
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

2. On ne peut pas employer un Combiner quand la fonction nest pas commutative et associative.
3. Les Combiners reoivent leurs paires dun seul Mapper, tandis que les Reducers reoivent les
paires de tous les Combiners et/ou tous les Mappers. Les Combiners ont une vue restreinte des
donnes.
4. Hadoop nest pas du tout oblig de lancer un Combiner, cest seulement une optimisation locale.
Il ne faut donc pas concevoir un algorithme map-combine-reduce dans lequel le Combiner
jouerait un rle spcifique.

2.4.6. Squelette de Combiner


Les combiners reprennent la mme interface que les reducers sauf que les paires de sortie doivent tre
du mme type que les paires dentre :

public class TraitementCombiner


extends Reducer<TypCleI,TypValI, TypCleI,TypValI>
{
@Override
public void reduce(TypCleI cleI, Iterable<TypValI> listeI,
Context context) throws Exception
{
for (TypValI val: listeI) {
/** traitement: cleS = ..., valS = ... **/
}
context.write(new TypCleI(cleS), new TypValI(valS));
}
}

2.5. MapReduce dans dautres langages


2.5.1. Prsentation
Hadoop permet de programmer un Job MapReduce dans dautres langages que Java : Ruby, Python,
C++. . . En fait, il suffit que le langage permette de lire stdin et crive ses rsultats sur stdout.
Le Mapper est un programme qui lit des lignes sur stdin, calcule ce quil veut, puis crit des
lignes au format "%s\t%s\n" (cl, valeur) sur la sortie.
Entretemps, les lignes sont tries selon la cl, exactement comme le ferait la commande Unix
sort
Le Reducer doit lire des lignes au format "%s\t%s\n" (cl, valeur). Il doit dabord sparer ces
deux informations, puis traiter les lignes successives ayant la mme cl. a vous rappellera la
commande Unix uniq -c.

2.5.2. Exemple de Mapper en Python


Voici le compteur de mots programm en python :

##!/usr/bin/python
## -*- coding: utf-8 -*-

40
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

import sys
## traiter chaque ligne de l'entre standard
for ligne in sys.stdin:
# couper en mots et traiter chacun d'eux
for mot in ligne.split():
# trivialement: ce mot est en 1 exemplaire
paire = (mot, 1)
# crire la paire
print '%s\t%s' % paire

Chaque ligne est dcoupe en mots ; chacun est crit en tant que cl, avec la valeur 1 sur stdout.

2.5.3. Algorithme du rducteur


Cest un peu plus compliqu. Cest de lalgorithmique. Vous allez recevoir N lignes composes de
paires (cl,valeur). Vous devez accumuler (somme, moyenne, min, max. . . ) les valeurs correspondant
des cls identiques. Vous savez que les cls sont tries dans lordre, donc des lignes successives
auront la mme cl, sauf quand on change de cl.
Le parcours se fait ligne par ligne. Il faut donc mmoriser la cl de la ligne prcdente ainsi que
laccumulation des valeurs de cette cl. Quand la ligne courante a la mme cl que la prcdente, on
met jour le cumul. Sinon, on affiche le cumul (et sa cl) sur la sortie et on le remet zro.
la fin, ne pas oublier dafficher la dernire cl et le cumul.

2.5.4. Exemple de Reducer en Python


Voici le cur du compteur de mots sans les premires lignes :

cle_prec,nombre_total = None,0
for ligne in sys.stdin:
cle, valeur = ligne.split('\t', 1)
if cle == cle_prec:
nombre_total += int(valeur)
else:
if cle_prec != None:
paire = (cle_prec, nombre_total)
print '%s\t%s' % paire
cle_prec = cle
nombre_total = int(valeur)
if cle_prec != None:
paire = (cle_prec, nombre_total)
print '%s\t%s' % paire

2.5.5. Lancement de ce Job


Pour lancer un tel job, il faut
placer les deux scripts mapper.py et reducer.py sur HDFS

41
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

taper la commande complexe suivante :

yarn jar /usr/lib/hadoop-mapreduce/hadoop-streaming.jar \


-files mapper.py,reducer.py \
-mapper mapper.py -reducer reducer.py \
-input livres -output sortie

Il est souhaitable den faire un script ou un Makefile.


Il est intressant de voir quon peut le lancer dans un tube Unix, mais en mode squentiel :

cat data | mapper.py | sort | reducer.py

42
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Semaine 3

tude de cas MapReduce

Le cours de cette semaine explique comment crer une application MapReduce pour YARN complte.
Deux projets vont tre expliqus. Ils concernent des statistiques sur des documents.
calcul de la variance
calcul de la valeur mdiane
On va appliquer a la longueur des lignes de textes, mais a pourrait tre la dure de sjour sur une
place de parking payante, la temprature mesure midi, le nombre de sangliers dans les forts. . .

3.0.1. Application
Soient des donnes : des romans sous forme de fichiers texte. On sintresse la longueur des lignes
(pourquoi ? mystre. . . ).

1897
DRACULA
by Bram Stoker
CHAPTER I.
JONATHAN HARKERS JOURNAL.
(Kept in shorthand.)

3 May. Bistriz.- Left Munich at 8:35 P.M., on 1st May, arriving at


Vienna early next morning; should have arrived at 6:46, but train
was an hour late. Buda-Pesth seems a wonderful place, from the glimpse
which I got of it from the train and the little I could walk through
the streets. I feared to go very far from the station, as we had
arrived late and would start as near the correct time as possible. The
impression I had was that we were leaving the West and entering the
East; the most western of splendid bridges over the Danube, which is
here of noble width and depth, took us among the traditions of Turkish
rule.

3.1. Calcul de la variance


3.1.1. Dfinition
La variance dun ensemble de donnes permet de caractriser la dispersion des valeurs autour de la
moyenne. La variance est le carr de lcart type.

43
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

La variance Vx est la moyenne des carrs des carts des xi la moyenne m :

1X
Vx = (xi m)2
n i

Vous pourrez trouver la notation 2 pour la variance et ou x pour la moyenne.


Le problme de cette quation, cest quil faut dabord parcourir les donnes pour extraire la moyenne.

3.1.2. Autre criture


Il existe un autre algorithme :
P
1. Nombre de valeurs : n = 1
iP
2. Somme des valeurs : Sx = xi
i
x2
P
3. Somme des carrs : Sx2 = i
i
4. Moyenne des valeurs : Mx = Sx /n
5. Moyenne des carrs : Mx2 = Sx2 /n
6. Variance : Vx = Mx2 Mx Mx
Cet algorithme ne demande quun seul passage dans les donnes et il est paralllisable avec MapReduce.

3.1.3. criture MapReduce


Le principe est de ne faire quun seul passage travers les donnes, lors de la phase Map. Cette tape
doit collecter les trois informations n, Sx et Sx2 . Cest ltape Reduce qui calcule les moyennes et la
variance.
Map
extrait la valeur xi partir de la donne courante
met un triplet (1, xi , x2i ) en tant que valeur, associ une cl identique pour tous les
triplets
Combine
reoit une liste de triplets associs la mme cl
additionne tous ces triplets pour obtenir (n, Sx , Sx2 )
Reduce
mme calculs que Combine, on obtient les sommes finales
calcule Mx , Mx2 et Vx

3.1.4. Classe Variance


Comment transmettre les triplets (n, Sx, Sx2) entre les trois processus ?
driver la classe ArrayWritable : pas simple, et le pb, cest que n est un entier, les autres sont
des rels.
dfinir notre classe, appele Variance qui implmente Writable :
variables membres n, Sx et Sx2,
mthodes des Writable pour lire et crire les variables,
constructeur : initialise les trois variables zro,
affectation de x pour faciliter map,

44
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

addition de deux Variance pour faciliter combine et reduce,


calcul des moyennes et de la variance pour faciliter reduce.

3.1.5. Classe Variance (entte)


Voici le dbut de la classe :

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.Writable;

public class Variance implements Writable


{
private long n;
private double Sx;
private double Sx2;

Notez les types : cest du Big Data , donc potentiellement, les donnes peuvent tre normes. Un
int est limit 2 milliards.

3.1.6. Classe Variance (constructeur)


Voici le constructeur de la classe :

public Variance()
{
clear();
}

public void clear()


{
n = 0L;
Sx = 0.0;
Sx2 = 0.0;
}

Le suffixe L indique que cest une constante long.

3.1.7. Classe Variance (mthodes Writable)


Un Writable doit implmenter ces deux mthodes :

public void write(DataOutput sortie) throws IOException


{
sortie.writeLong(n);
sortie.writeDouble(Sx);

45
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

sortie.writeDouble(Sx2);
}

public void readFields(DataInput entree) throws IOException


{
n = entree.readLong();
Sx = entree.readDouble();
Sx2 = entree.readDouble();
}

Il faut lire et crire exactement la mme chose dans le mme ordre.

3.1.8. Classe Variance (mthode pour map)


Chaque mapper va avoir besoin de produire un triplet initialis partir de la valeur courante. La
mthode suivante va lui faciliter la vie :
public void set(double valeur)
{
n = 1L;
Sx = valeur;
Sx2 = valeur*valeur;
}

Il suffira de ceci dans le mapper pour chaque valeur x traiter :

Variance valeurI = new Variance();


valeurI.set(x);
context.write(cleI, valeurI);

3.1.9. Classe Variance (mthode pour combine)


Les combiners et le reducer vont devoir additionner de nombreux triplets afin dobtenir les totaux sur
les trois champs. Voici une mthode pratique :
public void add(Variance autre)
{
n += autre.n;
Sx += autre.Sx;
Sx2 += autre.Sx2;
}

Il leur suffira de faire ceci pour chaque liste de valeurs reues :

Variance valeurS = new Variance();


for (Variance valeur: valeursI) {
valeurS.add(valeur);
}

46
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

3.1.10. Classe Variance (mthode pour reduce)


Il est pratique de rajouter la mthode de calcul de la variance, plutt que la coder dans le reducer,
car toutes les variables sont sur place :
public double getVariance()
{
double Mx = Sx / n;
double Mx2 = Sx2 / n;
return Mx2 - Mx*Mx;
}

Voila. Cest tout ce quil y a dans la classe Variance. Cette classe peut facilement tre intgre dans
un autre projet ou modifie pour un autre calcul mathmatique du mme genre (cumul de valeurs).

3.1.11. Mapper pour la variance


La classe Mapper reoit un texte traiter. Chaque thread va soccuper dune seule ligne. Le but est
de calculer la variance des longueurs de ligne.
En entre du Mapper, il y a un texte, donc des paires (LongWritable, Text), parce que le driver
configure le job par :
job.setInputFormatClass(TextInputFormat.class);
En sortie du Mapper, on aura des paires (Text, Variance), la cl tant identique pour toutes les
paires.
On a donc lentte suivant :
public class VarianceLongueurLignesMapper
extends Mapper<LongWritable, Text, Text, Variance>
{

3.1.12. Classe VarianceLongueurLignesMapper


Voici le corps du mapper. Les allocations sont faites en dehors. La cl tant constante, elle est alloue
et affecte une seule fois.
private Text cleI = new Text("Vx");
private Variance valeurI = new Variance();

@Override
public void map(LongWritable cleE, Text valeurE, Context context)
throws IOException, InterruptedException
{
valeurI.set( valeurE.getLength() );
context.write(cleI, valeurI);
}

valeurE contient lune des lignes du texte traiter. cleE contient son offset, cest dire le numro
du premier octet de la ligne.

47
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

3.1.13. Combiner
Ce processus est optionnel de deux manires : dune part on peut sen passer, et dautre part, mme
programm, il nest pas forcment lanc par YARN. Sil est lanc, il est associ un Mapper et il
tourne pour rduire les donnes venant dune seule machine.
Son rle est davancer le travail du Reducer. On va lui demander de calculer les sommes partielles.
Comme il se trouve entre le Mapper et le Reducer, son entte est :

public class VarianceLongueurLignesCombiner


extends Reducer<Text, Variance, Text, Variance>
{

On doit remettre les mmes types en entre et en sortie pour les cls et valeurs. ~

3.1.14. Classe VarianceLongueurLignesCombiner


Voici le corps du combiner. Les cls et valeurs de sortie ne sont pas alloues en dehors.

private Variance valeurS = new Variance();


public void reduce(Text cleI, Iterable<Variance> valeursI, Context context)
throws IOException, InterruptedException
{
Text cleS = cleI;
valeurS.clear();
for (Variance valeur : valeursI) {
valeurS.add(valeur);
}
context.write(cleS, valeurS);
}

La cl dentre est recopie en sortie et les valeurs dentre sont additionnes. On va retrouver ce
mme schma dans le reducer.

3.1.15. Classe VarianceLongueurLignesReducer


Le reducer reoit toutes les sommes partielles, des mappers et ventuellement des combiners. Il calcule
les sommes finales et la valeur de la variance.
En entre, il va recevoir des paires (Text, Variance) et en sortie, il ne produit quun nombre, la
variance des longueurs de ligne, donc il produit une paire (Text, DoubleWritable).
Voici la dfinition de la classe :

public class VarianceLongueurLignesReducer


extends Reducer<Text, Variance, Text, DoubleWritable>
{

La cl de sortie sera encore la mme cl. Cest comme a quand on calcule une information synthtique
sur la totalit des donnes. On aurait des cls diffrentes sil fallait distinguer diffrentes variances.

48
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

3.1.16. VarianceLongueurLignesReducer (mthode reduce)


Voici le source du reducer :

private Variance total = new Variance();


private DoubleWritable valeurS = new DoubleWritable();

@Override
public void reduce(Text cleI, Iterable<Variance> valeursI, Context context)
throws IOException, InterruptedException
{
Text cleS = cleI;
total.clear();
for (Variance valeur : valeursI) {
total.add(valeur);
}
valeurS.set( total.getVariance() );
context.write(cleS, valeurS);
}

3.1.17. Programme principal


Le programme principal, appel Driver cre un job YARN. Il dfinit les classes, les types des donnes
et les fichiers concerns. Voici son point dentre avec la mthode main :

public class VarianceLongueurLignesDriver


extends Configured implements Tool
{
public static void main(String[] args) throws Exception
{
// prparer et lancer un job
VarianceLongueurLignesDriver driver =
new VarianceLongueurLignesDriver();
int exitCode = ToolRunner.run(driver, args);
System.exit(exitCode);
}

Tout est dans la mthode run surcharge de la classe Configured.

3.1.18. Driver
Il a plusieurs choses faire :
Vrifier les paramtres. Ils sont dans le tableau String[] args pass en paramtre de la
mthode.
Crer le job YARN
Dfinir les classes des Mapper, Combiner et Reducer afin que YARN sache quoi lancer
Dfinir les types des cls et valeurs sortant du Mapper
Dfinir les types des cls et valeurs sortant du Reducer

49
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Dfinir les fichiers ou dossiers traiter : ce sont les paramtres du programme.


Lancer le job.
Cest la fonction la plus longue de tout le logiciel.

3.1.19. Classe VarianceLongueurLignesDriver (mthode run)


Voici le dbut avec la vrification des paramtres et la cration du job YARN :
@Override
public int run(String[] args) throws Exception
{
// vrifier les paramtres
if (args.length != 2) {
System.err.println("fournir les dossiers d'entre et de sortie");
System.exit(-1);
}

// crer le job map-reduce


Configuration conf = this.getConf();
Job job = Job.getInstance(conf, "VarianceLongueurLignes");
job.setJarByClass(VarianceLongueurLignesDriver.class);

3.1.20. Classe VarianceLongueurLignesDriver (classes)


Voici comment on dfinit les classes des traitements. On nomme les classes correspondant aux
traitements :

// dfinir les classes Mapper, Combiner et Reducer


job.setMapperClass(VarianceLongueurLignesMapper.class);
job.setCombinerClass(VarianceLongueurLignesCombiner.class);
job.setReducerClass(VarianceLongueurLignesReducer.class);

Cest ncessaire car une fois compil, rien ne dit YARN quelle classe fait quoi. Le projet suivant
montrera une situation o il y a deux MapReduce successifs, donc plusieurs classes pour le mme
type de travail.

3.1.21. Classe VarianceLongueurLignesDriver (entre)


Voici comment on spcifie les donnes traiter. La premire instruction dit quon va traiter des textes
(un fichier CSV, mme compress, est un fichier texte, un .mp3 est un fichier binaire).
La deuxime instruction indique o est le fichier traiter. Si on fournit un nom de dossier, alors tous
les fichiers de ce dossier seront traits. Et avec la troisime ligne, on indique daller aussi traiter tous
les fichiers des sous-. . . dossiers.

// dfinir les donnes d'entre


job.setInputFormatClass(TextInputFormat.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileInputFormat.setInputDirRecursive(job, true);

50
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

La classe TextInputFormat fait que les paires fournies au mapper seront des (LongWritable, Text).

3.1.22. Classe VarianceLongueurLignesDriver (sorties)


Ensuite, on configure les types des cls intermdiaires et finales ainsi que le dossier de sortie :

// sorties du mapper = entres du reducer et du combiner


job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Variance.class);

// dfinir les donnes de sortie : dossier et types des paires


FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(DoubleWritable.class);

Le reducer crira le rsultat, une paire (Text, DoubleWritable) dans un fichier appel part-r-00000
dans le dossier de sortie.

3.1.23. Classe VarianceLongueurLignesDriver (lancement)


Pour finir, on lance le job :

// lancer le job et attendre sa fin


boolean success = job.waitForCompletion(true);
return success ? 0 : 1;
}

La mthode run doit retourner un code derreur : 0=ok, 1=erreur. Or la mthode waitForCompletion
retourne un boolen valant true si cest ok, false si a a plant.
Tlcharger le projet complet VarianceLongueurLignes.tar.gz.

3.1.24. Commandes de compilation de cet ensemble


Il reste voir comment on lance tout a :
1. Compilation des sources. La variable CLASSPATH contient les archives jar ncessaires la com-
pilation, par exemple ~/lib/hadoop/hadoop-common-2.7.1.jar:~/lib/hadoop/hadoop-mapreduce-c
Les chemins sont spars par un :

javac -cp $CLASSPATH *.java

2. Cration dune archive jar. On doit dire quelle est la classe principale, celle qui contient
main().

jar cfe projet.jar VarianceLongueurLignesDriver *.class

Cest plus compliqu si les fichiers source sont placs dans un dossier src et quil faut un dossier bin
pour mettre les binaires, et aussi sil y a des paquetages. Voir le Makefile des TP.

51
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

3.1.25. Commandes de lancement de cet ensemble


Voici maintenant lexcution, une fois quon a larchive projet.jar, faire chaque lancement :
1. Suppression du dossier des rsultats

hdfs dfs -rm -r -f resultats

2. Lancement du job. On donne les noms des dossiers.

yarn jar projet.jar /share/livres resultats

3. Affichage des messages. Il faut connatre lidentifiant de lapplication. Il est affich dans les
premires lignes suivant le lancement. Il est utile de rajouter | more la commande.

yarn logs -applicationId application_14579178155_003

4. Affichage des rsultats

hdfs dfs -cat resultats/part-r-00000

3.1.26. Bilan
crire le calcul la manire MapReduce
Lcriture initiale ne le permet pas. Il faut trouver un moyen de r-crire la formule afin de
parallliser les calculs. Ici, ce sont les sommes partielles sur plusieurs donnes (1, x et x2 ) qui
peuvent tre faites simultanment par les combiners. Par contre, cela demande des connaissances
en mathmatiques (Thorme de Knig-Huygens, wikipedia) qui sont hors comptence.
Si on ne trouve pas les bonnes formules, on ne peut pas faire le travail en MapReduce.
Dfinir la structure de donnes change entre les mappers et le reducer
Si on ne peut pas faire avec les types prdfinis simples, on doit implmenter la classe Writable
et rajouter les mthodes utiles.

3.2. Calcul dune mdiane


3.2.1. Principe
Le programme prcdent peut facilement tre adapt au calcul de diffrentes moyennes : arithmtique,
gomtrique (exponentielle de la moyenne des logarithmes), harmonique (inverse de la moyenne des
inverses), quadratique (racine de la moyenne des carrs).
La mdiane est une autre sorte dinformation statistique. Cest une valeur qui caractrise un ensemble
de donnes. Elle est telle quil y a autant de donnes meilleures quelle, que de pires.
Par exemple, dans le sac (bag ou multiensemble) {58, 81, 36, 93, 3, 8, 64, 43, 3}, la mdiane est 43. Il
y a autant de valeurs plus petites quelle {36, 3, 8, 3} que de plus grandes {58, 81, 93, 64}.
La mdiane nest pas forcment au milieu des donnes. Par contre, elle lest quand les donnes sont
tries et en nombre impair.

52
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

3.2.2. Principe du calcul en MapReduce


On se propose de calculer la mdiane des longueurs des lignes dun ensemble de textes.
Dans un trs grand corpus, de trs nombreuses lignes ont la mme longueur. Ainsi, a conduit
un multi-ensemble o le mme lment est prsent de nombreuses fois. Par exemple, une ligne de
longueur 67 est trs commune.
Le calcul de la mdiane reste le mme : il faut trouver la longueur telle quil y a autant de lignes plus
courtes que de lignes plus longues.
Pour viter un tri de toutes les longueurs de lignes qui serait trs coteux, le principe est de travailler
avec un histogramme des longueurs des lignes. Cet histogramme peut tre calcul avec un MapReduce.

3.2.3. Histogramme des longueurs des lignes


Cette image montre le nombre de lignes de chaque longueur. Elle permet de visualiser la position de
la mdiane, qui est 64 (ici).

Figure 11: Histogramme des longueurs des ligne

La somme des nombres dun ct, par exemple gauche entre 0 et 63 est juste infrieure la moiti
du nombre total de lignes.

3.2.4. Donnes calculer


En partant des textes organiss en lignes, on va calculer le nombre de lignes de chaque longueur, ainsi
que le nombre de lignes total.
Le nombre de lignes de chaque longueur par un premier MapReduce. Son travail consiste
produire lhistogramme. On va rcuprer un tableau (longueur de ligne, nombre de lignes de
cette longueur).
Le nombre de lignes total par un second MapReduce appliqu lhistogramme (cest un choix
purement pdagogique).
Ensuite, on va calculer la position de la mdiane par un parcours de lhistogramme de gauche droite
en accumulant les nombres de lignes. Ds quon dpasse la moiti du nombre total, cest quon est
sur la mdiane.

53
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

3.2.5. Premier MapReduce (le mapper)


Map1 reoit des textes ligne par ligne. Chaque thread gnre une paire (length(ligne), 1) :

public class MedianeLongueurLignesEtape1Mapper


extends Mapper<LongWritable, Text, IntWritable, LongWritable>
{
private final LongWritable valeurI = new LongWritable(1L);
private IntWritable cleI = new IntWritable();
@Override
public void map(LongWritable cleE, Text valeurE, Context context) throws IOException,
{
cleI.set(valeurE.getLength());
context.write(cleI, valeurI);
}
}

3.2.6. Premier MapReduce (le reducer)


Reduce1 additionne les paires reues de Map1 :

public class MedianeLongueurLignesEtape1Reducer


extends Reducer<IntWritable, LongWritable, IntWritable, LongWritable>
{
@Override
public void reduce(IntWritable cleI, Iterable<LongWritable> valeursI, Context context)
{
IntWritable cleS = cleI;
long nombre = 0L;
for (LongWritable valeurI : valeursI) {
nombre += valeurI.get();
}
LongWritable valeurS = new LongWritable(nombre);
context.write(cleS, valeurS);
}
}

3.2.7. Premier MapReduce (le driver)


Le driver construit un job MapReduce afin de traiter les textes. Il indique un dossier temporaire pour
enregistrer les rsultats.
Plusieurs MapReduce peuvent tre construits et lancs successivement :

Configuration conf = this.getConf();

Job etape1 = Job.getInstance(conf, "MedianeLongueurLignes1");


etape1.setJarByClass(MedianeLongueurLignesDriver.class);

54
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

...
Job etape2 = Job.getInstance(conf, "MedianeLongueurLignes2");
etape2.setJarByClass(MedianeLongueurLignesDriver.class);
...
if (!etape1.waitForCompletion(true)) return 1;
if (!etape2.waitForCompletion(true)) return 1;

3.2.8. Format des fichiers


La particularit, cest que la sortie du premier MapReduce est mise dans un SequenceFile afin dtre
facilement relue. Cest un format binaire contenant des paires (cl, valeur).
Voici la configuration de la sortie de ltape 1 :

etape1.setOutputFormatClass(SequenceFileOutputFormat.class);
FileOutputFormat.setOutputPath(etape1, PathTMP1);
etape1.setOutputKeyClass(IntWritable.class);
etape1.setOutputValueClass(LongWritable.class);

Voici la configuration de lentre de ltape 2 :

etape2.setInputFormatClass(SequenceFileInputFormat.class);
FileInputFormat.addInputPath(etape2, PathTMP1);

3.2.9. Second MapReduce (le mapper)


Map2 reoit une paire (longueur, nombre) venant du SequenceFile. Il produit une paire (0,
nombre) :
public class MedianeLongueurLignesEtape2Mapper
extends Mapper<IntWritable, LongWritable, IntWritable, LongWritable>
{
// mme cl pour tout le monde
private IntWritable cleI = new IntWritable(0);

@Override
public void map(IntWritable cleE, LongWritable valeurE, Context context)
throws IOException, InterruptedException
{
context.write(cleI, valeurE);
}
}

3.2.10. Second MapReduce (le reducer)


En fait, le second reducer est exactement le mme que le premier : il calcule le total des valeurs par
cl. Dans le second map, il ny a quune seule cl.
On peut galement lutiliser directement comme combiner dans les deux jobs MapReduce.

55
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

3.2.11. Le post-traitement
Le premier MapReduce produit un fichier (temporaire) contenant des paires (longueur de ligne,
nombre de lignes de cette longueur). On a vu que ctait un SequenceFile.
Le second MapReduce produit un fichier (temporaire) contenant une seule paire (0, nombre de
lignes total). Cest un simple fichier texte sur HDFS.
Il y a maintenant deux choses faire :
1. Rcuprer le nombre de lignes total issu du second MapReduce
2. Rcuprer et traiter lhistogramme issu du premier MapReduce
Ce qui est important, cest que YARN fait trier les lignes sortant du reducer dans lordre croissant
des cls. Cest dire lhistogramme sera automatiquement dans lordre.

3.2.12. Rcuprer le nombre de lignes total


Il faut relire le fichier part-r-00000 issu du second MapReduce. On veut le 2e mot de la premire
ligne :

private long ReadTotal() throws IOException


{
FSDataInputStream inStream =
fs.open(new Path(TMP2, "part-r-00000"));
try {
InputStreamReader isr = new InputStreamReader(inStream);
BufferedReader br = new BufferedReader(isr);
String line = br.readLine();
String[] mots = line.split("\t");
return Integer.parseInt(mots[1]);
} finally {
inStream.close();
}
}

3.2.13. Parcourir lhistogramme


Il faut relire le SequenceFile issu du premier MapReduce. Cest un peu plus complexe :

SequenceFile.Reader.Option fichier =
SequenceFile.Reader.file(new Path(TMP1,"part-r-00000"));
SequenceFile.Reader reader = new SequenceFile.Reader(conf, fichier);
try {
IntWritable longueur = new IntWritable();
LongWritable nombre = new LongWritable();
while (reader.next(longueur, nombre)) {
// traiter le couple (longueur, nombre)
...
}
System.out.println("resultat : "+resultat);

56
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

} finally {
reader.close();
}

3.2.14. Calculer la mdiane


Cest de lalgorithmique standard. Dans la boucle prcdente, on parcourt les couples (longueur,
nombre) dans lordre croissant des longueurs. Il faut juste arrter la boucle quand la somme des
nombres vus jusque l dpasse la moiti du nombre total.

long limite = ReadTotal() / 2;


long cumul = 0L;
while (reader.next(longueur, nombre)) {
cumul += nombre.get();
if (cumul >= limite) {
break; // arrter la boucle tout de suite
}
}
return longueur.get();

On peut amliorer pour retourner une interpolation entre la longueur actuelle et sa prcdente, selon
le dpassement de la limite.

3.2.15. Bilan
Cet exemple a montr comment exploiter les rsultats dun ou plusieurs MapReduce dans un mme
programme. Plusieurs formats de fichiers peuvent tre employs.
Tlcharger le projet complet MedianeLongueurLignes.tar.gz.

57
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Semaine 4

Pig

Le cours de cette semaine prsente le systme Pig et son langage Pig Latin. Ce dernier est un langage
de programmation de requtes sur des fichiers HDFS qui se veut plus simple que Java pour crire des
jobs MapReduce. Pig sert lancer les programmes Pig Latin dans lenvironnement Hadoop.

4.1. Introduction
4.1.1. Prsentation de Pig
Apache Pig est un logiciel initialement cr par Yahoo!. Il permet dcrire des traitement utiles
sur des donnes, sans subir la complexit de Java. Le but est de rendre Hadoop accessible des
non-informaticiens scientifiques : physiciens, statisticiens, mathmaticiens. . .
Pig propose un langage de scripts appel Pig Latin . Ce langage est qualifi de Data Flow
Language . Ses instructions dcrivent des traitements sur un flot de donnes. Conceptuellement, a
ressemble un tube Unix ; chaque commande modifie le flot de donnes qui la traverse. Pig Latin
permet galement de construire des traitements beaucoup plus varis et non-linaires.
Pig traduit les programmes Pig Latin en jobs MapReduce et intgre les rsultats dans le flot.

4.1.2. Exemple de programme Pig


Ce programme affiche les 10 adultes les plus jeunes extraits dun fichier csv contenant 3 colonnes :
identifiant, nom et age.
personnes = LOAD 'personnes.csv' USING PigStorage(';')
AS (userid:int, nom:chararray, age:int);
jeunesadultes = FILTER personnes BY age >= 18 AND age < 24;
classement = ORDER jeunesadultes BY age;
resultat = LIMIT classement 10;
DUMP resultat;

Pour lexcuter : pig programme.pig. a lance un job MapReduce dans Hadoop. On peut aussi
taper les instructions une par une dans le shell de Pig.
Le but de ce cours : comprendre ce script et en crire dautres.

4.1.3. Comparaison entre SQL et Pig Latin


Il y a quelques ressemblances apparentes entre SQL et Pig Latin. Il y a plusieurs mots cls en commun
(JOIN, ORDER, LIMIT. . . ) mais leur principe est diffrent :

58
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

En SQL, on construit des requtes qui dcrivent les donnes obtenir. On ne sait pas comment
le moteur SQL va faire pour calculer le rsultat. On sait seulement quen interne, la requte
va tre dcompose en boucles et en comparaisons sur les donnes et en utilisant au mieux les
index.
En Pig Latin, on construit des programmes qui contiennent des instructions. On dcrit
exactement comment le rsultat doit tre obtenu, quels calculs doivent tre faits et dans quel
ordre.
galement, Pig a t conu pour les donnes incertaines de Hadoop, tandis que SQL tourne sur des
SGBD parfaitement sains.

4.2. Langage Pig Latin


4.2.1. Structure dun programme
Les commentaires sont placs entre /*...*/ ou partir de -- et la fin de ligne.
Un programme Pig Latin est une succession dinstructions. Toutes doivent tre termines par un ;
Comme dans SQL, il ny a pas de notion de variables, ni de fonctions/procdures.
Le rsultat de chaque instruction Pig est une collection de n-uplets. On lappelle relation. On peut la
voir comme une table de base de donnes.
Chaque instruction Pig prend une relation en entre et produit une nouvelle relation en sortie.

sortie = INSTRUCTION entree PARAMETRES ...;

4.2.2. Excution dun programme


Lorsque vous lancez lexcution dun programme, Pig commence par lanalyser. Chaque instruction,
si elle est syntaxiquement correcte, est rajoute une sorte de plan daction, une succession de
MapReduce, et cest seulement la fin du programme que ce plan daction est excut en fonction de
ce que vous demandez la fin.
Linstruction EXPLAIN relation affiche le plan daction prvu pour calculer la relation. Cest assez
indigeste quand on nest pas spcialiste.

4.2.3. Relations et alias


La syntaxe nom = INSTRUCTION ... ; dfinit un alias, cest dire un nom pour la relation cre
par linstruction. Ce nom tant gnralement employ dans les instructions suivantes, cest a qui
construit un flot de traitement.

nom1 = LOAD ... ;


nom2 = FILTER nom1 ... ;
nom3 = ORDER nom2 ... ;
nom4 = LIMIT nom3 ... ;

Le mme alias peut tre rutilis dans des instructions diffrentes, ce qui cre des bifurcations dans le
flot de traitement : sparations ou regroupements.
Il nest pas recommand de raffecter le mme alias.

59
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

4.2.4. Enchanement des instructions


Pig permet soit denchaner les instructions par le mcanisme des alias, soit par un appel imbriqu.

nom4 = LIMIT (ORDER (FILTER (LOAD ...) ...) ...) ... ;

Vous choisirez celui que vous trouvez le plus lisible.


Toutefois, les appels imbriqus ne permettent pas de faire facilement des sparations de traitement,
au contraire des alias :

nom1 = LOAD ... ;


nom2 = FILTER nom1 ... ;
nom3 = FILTER nom1 ... ;
nom4 = JOIN nom2 ..., nom3 ;

4.2.5. Relations et types


Une relation est une collection ordonne de n-uplets qui possdent tous les mmes champs. Voici les
types possibles.
Les types scalaires sont :
int et long pour les entiers, float et double pour les rels
chararray pour des chanes quelconques.
bytearray pour des objets binaires quelconques
Il y a aussi trois types complexes :
dictionnaires (maps) : [nom#mickey, age#87]
n-uplets (tuples) de taille fixe : (mickey, 87, herg)
sacs (bags) = ensembles sans ordre de tuples : {(mickey, 87), (asterix, 56), (tintin,
86)}

4.2.6. Schma dune relation


La liste des champs dune relation est appel schma. Cest un n-uplet. On lcrit (nom1:type1,
nom2:type2, ...)
Par exemple, une relation contenant des employs aura le schma suivant :

(id:long, nom:chararray, prenom:chararray, photo:bytearray,


anciennet:int, salaire:float)

Linstruction LOAD 'fichier.csv' AS schma; permet de lire un fichier CSV et den faire une
relation daprs le schma indiqu.

4.2.7. Schmas complexes (tuples)


Pig permet la cration dune relation base sur un schma incluant des donnes complexes. Soit un
fichier contenant des segments 3D :

60
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

S1 (3,8,9) (4,5,6)
S2 (1,4,7) (3,7,5)
S3 (2,5,8) (9,5,8)

Jutilise le caractre pour reprsenter une tabulation.

Voici comment lire ce fichier :

segments = LOAD 'segments.csv' AS (


nom:chararray,
P1:tuple(x1:int, y1:int, z1:int),
P2:tuple(x2:int, y2:int, z2:int));
DUMP segments;

4.2.8. Schmas complexes (bags)


On peut galement lire des sacs, cest dire des ensembles de donnes de mmes types mais en
nombre quelconque :

L1 {(3,8,9),(4,5,6)}
L2 {(4,8,1),(6,3,7),(7,4,5),(5,2,9),(2,7,1)}
L3 {(4,3,5),(6,7,1),(3,1,7)}

Le schma de ce fichier est :

(nom:chararray, Points:{tuple(x:int, y:int, z:int)})

Explications :
Le deuxime champ du schma est spcifi ainsi :
nom du champ :{ type du contenu du sac }
Les donnes de ce champ doivent tre au format
{ liste de valeurs correspondant au type }

4.2.9. Schmas complexes (maps)


Pour finir, avec les dictionnaires, voici le contenu du fichier heros.csv :

1 [nom#asterix,metier#guerrier]
2 [nom#tintin,metier#journaliste]
3 [nom#spirou,metier#groom]

On en fait une relation par :

heros = LOAD 'heros.csv' AS (id:int, infos:map[chararray])

Remarque : toutes ces constructions, tuple, map et bags peuvent tre imbriques, mais certaines
combinaisons sont difficiles spcifier.

61
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

4.2.10. Nommage des champs


Il y a deux syntaxes pour nommer les champs dune relation. Soit on emploie leur nom en clair, soit
on les dsigne par leur position $0 dsignant le premier champ, $1 le deuxime et ainsi de suite.
On emploie la seconde syntaxe quand les noms des champs ne sont pas connus ou quils ont t
gnrs dynamiquement.
Quand il y a ambigut sur la relation concerne, on prfixe le nom du champ par le nom de la
relation : relation.champ
Lorsquun champ est un tuple, ses lments sont nomms relation.champ.element. Par
exemple segments.P1.z1
Pour un champ de type map, ses lments sont nomms relation.champ#element. Par exemple
heros.infos#metier
Il ny a pas de syntaxe pour laccs aux champs de type bag.

4.3. Instructions Pig


4.3.1. Introduction
Il y a plusieurs catgories dinstructions : interaction avec les fichiers, filtrage, jointures. . .
Pour commencer, il y a galement des instructions daccs aux fichiers HDFS lintrieur de Pig.
Ces commandes fonctionnent comme dans Unix ou comme le suggre leur nom et elles sont plutt
destines tre tapes dans le shell de Pig.
dossiers : cd, ls, mkdir, rmf (rmf = rm -f -r)
fichiers : cat, cp, copyFromLocal, copyToLocal, mv, rm
divers : help, quit, clear

4.3.2. Chargement et enregistrement de fichiers


LOAD 'fichier' USING PigStorage('sep') AS schema;
Charge le fichier qui doit tre au format CSV avec des champs spars par sep et en leur
attribuant les noms et types du schma. Des donnes qui ne correspondent pas restent vides.
Il nest pas ncessaire de mettre la clause USING quand le sparateur est la tabulation.
NB: le fichier doit tre prsent dans HDFS ; rien ne signale lerreur autrement que lchec
du programme entier.
STORE relation INTO 'fichier' USING PigStorage('sep');
Enregistre la relation dans le fichier, sous forme dun fichier CSV spar par sep, ex: ';',
':'. . .
Dans les deux cas, si le fichier porte une extension .gz, .bz2, il est (d)compress automatiquement.

4.3.3. Affichage de relations


DUMP relation;
Lance le calcul MapReduce de la relation et affiche les rsultats lcran. Cest seulement ce
stade que la relation est calcule.

62
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

DESCRIBE relation;
Affiche le schma, cest dire les champs, noms et types, de la relation. Cest utiliser ds
quon a un doute sur le programme.
SAMPLE relation;
Affiche quelques n-uplets choisis au hasard, une sorte dchantillon de la relation.

4.3.4. Instruction ORDER


Elle classe les n-uplets dans lordre croissant (ou dcroissant si DESC) des champs indiqus

ORDER relation BY champ [ASC|DESC], ...

a ressemble totalement ce quon fait avec SQL. Voir lexemple du transparent suivant.

RANK relation BY champ [ASC|DESC], ...

Retourne une relation ayant un premier champ supplmentaire, le rang des n-uplets par rapport au
critre indiqu.

4.3.5. Instruction LIMIT


Elle ne conserve de la relation que les N premiers n-uplets.

LIMIT relation N

On lutilise en gnral avec ORDER. Par exemple, cette instruction affiche les 10 plus gros achats :

triparmontant = ORDER achats BY montant DESC;


meilleurs = LIMIT triparmontant 10;
DUMP meilleurs;

On peut aussi lcrire de manire imbrique :

DUMP LIMIT (ORDER achats BY montant DESC) 10;

4.3.6. Instruction FILTER


Elle sert crer une relation ne contenant que les n-uplets qui vrifient une condition.

FILTER relation BY condition;

La condition :
comparaisons : mmes oprateurs quen C et en Java
nullit (vide) dun champ : IS NULL, IS NOT NULL
connecteurs logiques : (mmes oprateurs quen SQL) AND, OR et NOT

63
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

clients = LOAD 'clients.csv'


AS (idclient:int, age:int, adresse:chararray);
tresvieuxclients = FILTER clients
BY age > 1720 AND adresse IS NOT NULL;

4.3.7. Instruction DISTINCT


Elle sert supprimer les n-uplets en double. Cela ressemble la commande Unix uniq (sauf quils
nont pas besoin dtre dans lordre).

DISTINCT relation;

Note: la totalit des champs des tuples sont pris en compte pour liminer les doublons.
Si on veut liminer les doublons en se basant sur une partie des champs, alors il faut employer un
FOREACH, voir plus loin.

4.3.8. Instruction FOREACH GENERATE


Cest une instruction qui peut tre trs complexe. Dans sa forme la plus simple, elle sert gnrer
une relation partir dune autre, par exemple faire une projection.

FOREACH relation GENERATE expr1 AS champ1, ...;

Cre une nouvelle relation contenant les champs indiqus. a peut tre des champs de la relation
fournie ou des valeurs calcules ; la clause AS permet de leur donner un nom.
Exemple, on gnre des bons dachats gaux 5% du total des achats des clients :

bonsachat = FOREACH totalachatsparclient


GENERATE idclient, montant*0.05 AS bon;

4.3.9. numration de champs


Lorsquil y a de nombreux champs dans la relation dentre et aussi dans celle quil faut gnrer, il
serait pnible de tous les crire. Pig propose une notation champA .. champB pour numrer tous les
champs compris entre les deux. Si champA est omis, alors a part du premier ; si champB est omis,
alors lnumration va jusquau dernier champ.
Par exemple, une relation comprend 20 champs, on veut seulement retirer le 8e :

relation_sans_champ8 = FOREACH relation_complexe


GENERATE .. champ7 champ9 ..;

Attention, il faut crire deux points bien espacs.

64
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

4.3.10. Instruction GROUP BY


Linstruction GROUP relation BY champ rassemble tous les tuples de la relation qui ont la mme
valeur pour le champ. Elle construit une nouvelle relation contenant des couples (champ, {tuples
pour lesquels champ est le mme}).
Soit une relation appele achats (idachat, idclient, montant) :

1, 1, 12.50
2, 2, 21.75
3, 3, 56.25
4, 1, 34.00
5, 3, 3.30

GROUP achats BY idclient produit ceci :

(1, {(4,1,34.0), (1,1,12.5)})


(2, {(2,2,21.75)})
(3, {(3,3,56.25), (5,3,3.30)})

4.3.11. Remarque sur GROUP BY


Linstruction GROUP BY cre une nouvelle relation compose de couples dont les champs sont nomms :
group : cest le nom donn au champ qui a servi construire les groupements, on ne peut pas
changer le nom
relation : le nom de la relation groupe est donne au bag. Il contient tous les n-uplets dont le
champ BY a la mme valeur.
Il aurait t souhaitable que GROUP achats BY idclient produise des couples (idclient, achats).
Mais non, ils sont nomms (group, achats). Donc si on fait

achatsparclient = GROUP achats BY idclient;

on devra mentionner achatsparclient.group et achatsparclient.achats.

4.3.12. Instruction GROUP ALL


Linstruction GROUP relation ALL regroupe tous les n-uplets de la relation dans un seul n-uplet
compos dun champ appel group et valant all, et dun second champ appel comme la relation
grouper.

montants = FOREACH achats GENERATE montant;


montants_tous = GROUP montants ALL;

Cre ce seul n-uplet : (all, {(12.50),(21.75),(56.25),(34.00),(3.30)})

65
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

4.3.13. Utilisation de GROUP BY et FOREACH


On utilise en gnral FOREACH pour traiter le rsultat dun GROUP. Ce sont des couples (rappel) :
Le premier champ venant du GROUP BY sappelle group,
Le second champ est un sac (bag) contenant tous les n-uplets lis group. Ce sac porte le nom
de la relation qui a servi le crer.
On utilise FOREACH pour agrger le sac en une seule valeur, par exemple la somme de lun des champs.

achats = LOAD 'achats.csv' AS (idachat, idclient, montant);


achatsparclient = GROUP achats BY idclient;
totalachatsparclient = FOREACH achatsparclient
GENERATE group AS idclient, SUM(achats.montant) AS total;

4.3.14. Oprateurs
Pig propose plusieurs oprateurs permettant dagrger les valeurs dun sac. Le sac est construit par
un GROUP BY ou GROUP ALL.
SUM,AVG calcule la somme/moyenne des valeurs numriques.
MAX,MIN retournent la plus grande/petite valeur
COUNT calcule le nombre dlments du sac sans les null
COUNT_STAR calcule le nombre dlments avec les null
Il y a dautres oprateurs :
CONCAT(v1, v2, ...) concatne les valeurs fournies.
DIFF(sac1, sac2) compare les deux sacs et retourne un sac contenant les lments qui ne sont
pas en commun.
SIZE retourne le nombre dlments du champ fourni.

4.3.15. Utilisation de GROUP et FOREACH


Dans certains cas, on souhaite aplatir le rsultat dun GROUP, cest dire au lieu davoir des sacs
contenant tous les n-uplets regroups, on les veut tous part. a va donc crer autant de n-uplets
spars quil y avait dlments dans les sacs.

achatsclients = FOREACH achats GENERATE idclient,montant;


montantsparclient = GROUP achatsclients BY idclient;
plusieurs = FILTER montantsparclient BY COUNT(achatsclients)>1;
clientsmultiples = FOREACH plusieurs
GENERATE group AS idclient, FLATTEN(achatsclients.montant);

produit ceci, les clients qui ont fait plusieurs achats :

(1, 34.0)
(1, 12.5)
(3, 56.25),
(3, 3.30)

66
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

4.3.16. Instruction FOREACH GENERATE complexe


FOREACH relation { traitements... ; GENERATE ... } permet dinsrer des traitements avant
le GENERATE.
sousrelation = FILTER relation BY condition;
Exemple, on veut offrir un bon dachat seulement aux clients qui ont fait de gros achats, le bon
dachat tant gal 15% du montant total de ces gros achats :

achatsparclient = GROUP achats BY idclient;


grosbonsachat = FOREACH achatsparclient {
grosachats = FILTER achats BY montant>=30.0;
GENERATE group, SUM(grosachats.montant)*0.15 AS grosbon;
};

La relation achat du FILTER dsigne le second champ du GROUP achatsparclient trait par le
FOREACH.

4.3.17. Instruction FOREACH GENERATE complexe (suite)


Il est possible dimbriquer dautres instructions dans un FOREACH :
sousrelation = FOREACH relation GENERATE...;
sousrelation = LIMIT relation N;
sousrelation = DISTINCT relation;
Exemple, on cherche les clients ayant achet des produits diffrents :

achats = LOAD 'achats.csv'


AS (idachat:int, idclient:int, idproduit:int, montant:float);
achatsparclient = GROUP achats BY idclient;
nombreparclient = FOREACH achatsparclient {
produits = FOREACH achats GENERATE idproduit;
differents = DISTINCT produits;
GENERATE group AS idclient, COUNT(differents) AS nombre;
}
resultat = FILTER nombreparclient BY nombre>1;

4.3.18. DISTINCT sur certaines proprits


On a vu que linstruction DISTINCT filtre seulement les n-uplets exactement identiques. Voici comment
supprimer les n-uplets en double sur certains champs seulement. Ca veut dire quon garde seulement
lun des n-uplets au hasard quand il y en a plusieurs qui ont les mmes valeurs sur les champs
considrs.
Soit une relation A de schma (a1,a2,a3,a4,a5). On veut que les triplets (a1,a2,a3) soient uniques.

A = LOAD 'data.csv' AS (a1,a2,a3,a4,a5);


A_unique = FOREACH (GROUP A BY (a1,a2,a3)) {
seul = LIMIT A 1;

67
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

GENERATE group.a1,group.a2,group.a3,
FLATTEN(seul.a4),FLATTEN(seul.a5);
}

4.3.19. Instruction JOIN


Les jointures permettent, comme en SQL de crer une troisime table partir de plusieurs tables qui
ont un champ en commun.

JOIN relation1 BY champ1a, relation2 BY champ2b, ...

Cela cre une relation ayant autant de champs que toutes les relations mentionnes. Les n-uplets
quon y trouve sont ceux du produit cartsien entre toutes ces relations, pour lesquels le champ1a de
la relation1 est gal au champ2b de la relation2.
Dans la nouvelle relation, les champs sont nomms relation1::champ1a, relation1::champ1b, . . .

4.3.20. Exemple de jointure


Soit une relation clients (idclient, nom) :

1 lucien
2 andr
3 marcel

Et une relation achats (idachat, idclient, montant) :

1, 1, 12.50
2, 2, 21.75
3, 3, 56.25
4, 1, 34.00
5, 3, 3.30

4.3.21. Exemple de jointure (suite)


Linstruction JOIN clients BY idclient, achats BY idclient cre (idclient, nom, idachat, id-
client, montant) :

(1,lucien,4,1,34.25)
(1,lucien,1,1,12.5)
(2,andr,2,2,21.75)
(3,marcel,3,3,56.25)
(3,marcel,5,3,3.30)

Il y a dautres types de jointure :


JOIN relationG BY champG LEFT, relationD BY champD pour une jointure gauche
JOIN relationG BY champG RIGHT, relationD BY champD pour une jointure droite
CROSS relation1, relation2, ... produit cartsien

68
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

4.3.22. Instruction UNION


Cette instruction regroupe les n-uplets des relations indiques.

UNION ONSCHEMA relation1, relation2, ...

Il est trs prfrable que les relations aient les mmes schmas. Chaque champ cre sa propre colonne.

4.4. Conclusion
4.4.1. Comparaison entre SQL et Pig (le retour)
Revenons sur une comparaison entre SQL et Pig. Soit une petite base de donnes de clients et
dachats. La voici en SQL ; en Pig, a sera deux fichiers CSV.

CREATE TABLE clients (


idclient INTEGER PRIMARY KEY,
nom VARCHAR(255));
CREATE TABLE achats (
idachat INTEGER PRIMARY KEY,
idclient INTEGER,
FOREIGN KEY (idclient) REFERENCES clients(idclient),
montant NUMERIC(7,2));

On veut calculer le montant total des achats par client.

4.4.2. Affichage nom et total des achats


Voici la requte SQL :

SELECT nom, SUM(montant) FROM clients,achats


WHERE clients.idclient = achats.idclient
GROUP BY clients.idclient;

Cest trs diffrent en Pig Latin, mditer :

achats = LOAD 'achats.csv' AS (idachat, idclient, montant);


achatsparclients = GROUP achats BY idclient;
totaux = FOREACH achatsparclients
GENERATE group, SUM(achats.montant) AS total;
clients = LOAD 'clients.csv' AS (idclient, nom);
jointure = JOIN clients BY idclient, totaux BY group;
resultat = FOREACH jointure GENERATE nom,total;
DUMP resultat;

69
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Semaine 5

Spark

Le cours de cette semaine prsente le systme de programmation Spark, un autre mcanisme de Hadoop
pour crire des programmes de type MapReduce, nettement plus performants et plus polyvalents
que ceux bass sur YARN. Nous programmerons sur Spark en Python, mais dautres langages sont
possibles.

5.1. Introduction
5.1.1. Prsentation de Spark
Spark est une API de programmation parallle sur des donnes.
Lobjet principal de Spark est le RDD : Resilient Distributed Dataset. Cest un dispositif pour traiter
une collection de donnes par des algorithmes parallles robustes. Un RDD ne contient pas vraiment
de donnes, mais seulement un traitement.
Ce traitement nest effectu que lorsque cela apparat ncessaire. On appelle cela lvaluation
paresseuse. Dautre part, Spark fait en sorte que le traitement soit distribu sur le cluster, donc
calcul rapidement, et nchoue pas mme si des machines tombent en panne.

5.1.2. Intrts de Spark


Spark permet dcrire des traitements complexes composs de plusieurs phases map-reduce. On peut
le faire galement avec YARN, mais les donnes issues de chaque phase doivent tre stockes sur
HDFS, pour tre rutilises immdiatement aprs dans la phase suivante. Cela prend beaucoup de
temps et despace.
Les jobs YARN sont assez longs lancer et excuter. Il y a des temps de latence considrables.
Au contraire, Spark utilise beaucoup mieux la mmoire centrale des machines du cluster et gre
lui-mme lenchanement des tches.
Les traitements peuvent tre crits dans plusieurs langages : Scala, Java et Python. On utilisera ce
dernier pour sa simplicit pdagogique et le fait que vous lapprenez dans dautres cours.

5.1.3. Premier exemple Spark


Soit un fichier de donnes de type CSV provenant de http://opendata.paris.fr dcrivant des arbres
remarquables Paris. Chaque ligne dcrit un arbre : position GPS, arrondissement, genre, espce,
famille, anne de plantation, hauteur, circonfrence, etc. Le sparateur est ';'. La premire ligne
contient les titres.

70
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

On souhaite afficher lanne de plantation (champ n6) de larbre le plus grand (champ n7).
Avec des commandes Unix, ce traitement scrirait :

cat arbres.csv | cut -d';' -f6,7 | egrep -v 'HAUTEUR|;$' |\


sort -t';' -k2 -n -r | head -n 1

Par contre, jaurais apprci que cut permette de changer lordre des champs, a aurait facilit le classement.

5.1.4. Principe du traitement


Voyons comment faire la mme chose avec Spark. Une fois que le fichier arbres.csv est plac sur
HDFS, il faut :
1. sparer les champs de ce fichier.
2. extraire le 7e et 6e champs dans cet ordre ce sont la hauteur de larbre et son anne de
plantation. On en fait une paire (cl, valeur). La cl est la hauteur de larbre, la valeur est son
anne de plantation.
3. liminer la cl correspondant la ligne de titre du fichier et les cls vides (hauteur inconnue).
4. convertir les cls en float
5. classer les paires selon la cl dans lordre dcroissant.
6. afficher la premire des paires. Cest le rsultat voulu.

5.1.5. Programme pySpark


Voici le programme pySpark arbres.py :

##!/usr/bin/python
from pyspark import SparkConf, SparkContext
sc = SparkContext(conf=SparkConf().setAppName("arbres"))

arbres = sc.textFile("hdfs:/share/paris/arbres.csv")
tableau = arbres.map(lambda ligne: ligne.split(';'))
paires = tableau.map(lambda champs: (champs[6],champs[5]))
pairesok1 = paires.filter(
lambda (hauteur,annee): hauteur!='' and hauteur!='HAUTEUR')
pairesok2 = pairesok1.map(
lambda (hauteur,annee): (float(hauteur), annee))
classement = pairesok2.sortByKey(ascending=False)
print classement.first()

5.1.6. Remarques
Les deux premires instructions consistent extraire les donnes du fichier. Cest dassez bas niveau
puisquon travaille au niveau des lignes et des caractres.
Dans MapReduce sur YARN, ces aspects avaient t isols dans une classe Arbres qui masquait les
dtails et fournissait des mthodes pratiques, comme getHauteur et getAnnee.
Compar aux programmes MapReduce en Java, Spark parat plus rustique. Mais cest sa rapidit,
entre 10 et 100 fois suprieure YARN qui le rend extrmement intressant.

71
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

On programme en Spark un peu comme dans le TP2 : la problmatique est 1) darriver construire
des RDD contenant ce dont on a besoin et 2) dcrire des fonctions de traitement.

5.1.7. Lancement
Spark offre plusieurs manires de lancer le programme, dont :
Lancement sur un cluster de Spark Workers
spark-submit --master spark://$(hostname -f):7077 \
arbres.py
Loption --master de cette commande indique Spark quon doit faire appel au cluster de
machines sur lesquelles tournent des Spark Workers. Ce sont des processus clients chargs de
faire les calculs distribus pour Spark.
Spark permet aussi de lancer lexcution sur YARN :
spark-submit --master yarn-cluster arbres.py
Ce sont les esclaves YARN qui excutent le programme Spark.

5.1.8. Commentaires
Le programme prcdent fait appel des lambda. Ce sont des fonctions sans nom (anonymes).
Voici une fonction avec un nom employe dans un map Python :
def double(nombre):
return nombre * 2

map(double, [1,2,3,4])

Cela peut scrire galement avec une lambda :


map(lambda nombre: nombre * 2, [1,2,3,4])

La syntaxe est lambda paramtres: expression. a cre une fonction qui na pas de nom mais
quon peut placer dans un map.

5.1.9. Fonction lambda ou fonction nomme ?


Faut-il employer une lambda ou bien une fonction nomme ?
Complexit
Une lambda ne peut pas contenir un algorithme complexe. Elles sont limites une
expression seulement.
Au contraire, une fonction peut contenir des boucles, des tests, des affectations volont
Lisibilit
Les lambda sont beaucoup moins lisibles que les fonctions, impossibles commenter, parfois
cryptiques. . .
Praticit
Les lambda sont trs courtes et plus pratiques crire sur place, tandis que les fonctions
doivent tre dfinies ailleurs que l o on les emploie.

72
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

5.1.10. Fonction lambda ou fonction nomme ?


En conclusion :
Les lambda sont intressantes connatre, plutt pratiques
On ne les emploiera que pour des expressions trs simples, immdiates comprendre.
Exemples pySpark (extrait de lexemple initial) :

## chaque ligne est dcoupe en liste de mots


...map(lambda ligne: ligne.split(';'))
## on retourne un tuple compos des champs 6 et 5
...map(lambda champs: (champs[6],champs[5]))
## on ne garde que si cl n'est ni vide ni HAUTEUR
...filter(lambda (cle,val): cle!='' and cle!='HAUTEUR')
## on convertit la cl en float
...map(lambda (cle,val): (float(cle), val))

5.1.11. Fonction lambda ou fonction nomme ?


Le mme exemple complet avec des fonctions nommes :

def separ(ligne):
return ligne.split(';')
def hauteurannee(champs):
return (champs[6],champs[5])
def garderok( (cle,val) ):
return cle!='' and cle!='HAUTEUR'
def convfloat( (cle, val) ):
return (float(cle), val)

tableau = arbres.map(separ)
paires = tableau.map(hauteurannee)
pairesok1 = paires.filter(garderok)
pairesok2 = pairesok1.map(convfloat)

Les traitements sont loigns de leur dfinition.

5.1.12. Dernire remarque sur les fonctions


Spark fait tourner les fonctions sur des machines diffrentes afin dacclrer le traitement global. Il ne
faut donc surtout pas affecter des variables globales dans les fonctions elles ne pourront pas tre
transmises dune machine lautre.
Chaque fonction doit tre autonome, isole. Donc ne pas faire :

total = 0
def cumuler(champs):
global total

73
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

total += float(champ[6])
return champ[5]

annees = tableau.map(cumuler)

Il y a quand mme des variables globales dans Spark, mais on nen parlera pas dans ce cours.

5.2. lments de lAPI Spark


5.2.1. Principes
Spark est puissant car il repose sur des principes peu nombreux et simples. Consulter la documentation.
Donnes :
RDD : ils reprsentent des donnes distribues modifies par une transformation, par
exemple un map ou un filter.
Variables partages entre des traitements et distribues sur le cluster de machines.
Calculs :
Transformations : ce sont des fonctions (au sens mathmatique) du type : RDD
transformation(RDD). Elles crent un nouveau RDD partir dun existant.
Actions : ce sont des fonctions qui permettent dextraire des informations des RDD, par
exemple les afficher sur lcran ou les enregistrer dans un fichier.

5.2.2. Dbut dun programme


Un programme pySpark doit commencer par ceci :

##!/usr/bin/python
from pyspark import SparkConf, SparkContext

nomappli = "essai1"
config = SparkConf().setAppName(nomappli)
sc = SparkContext(conf=config)

sc reprsente le contexte Spark. Cest un objet qui possde plusieurs mthodes dont celles qui crent
des RDD.
Pour lancer le programme, faire : spark-submit essai1.py

5.2.3. RDD
Un RDD est une collection de donnes abstraite, rsultant de la transformation dun autre RDD ou
dune cration partir de donnes existantes. Un RDD est distribu, cest dire rparti sur plusieurs
machines afin de parallliser les traitements.
On peut crer un RDD de deux manires :
Parallliser une collection

74
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Si votre programme contient des donnes itrables (tableau, liste. . . ), elles peuvent devenir un RDD.

donnees = ['veau', 'vache', 'cochon', 'couve']


RDD = sc.parallelize(donnees)

On le nomme collection paralllise .

5.2.4. RDD (suite)


Jeux de donnes externes
Spark peut utiliser de nombreuses sources de donnes Hadoop : HDFS, HBase. . . et il connait de
nombreux types de fichiers : texte et les formats Hadoop tels que SequenceFile vu en semaine 2. Il y
a dautres formats de lecture. Consulter la documentation.
Voici comment lire un simple fichier texte ou CSV :

RDD = sc.textFile("hdfs:/share/data.txt")

Comme avec MapReduce, chaque ligne du fichier constitue un enregistrement. Les transformations
appliques sur le RDD traiteront chaque ligne sparment. Les lignes du fichier sont distribues sur
diffrentes machines pour un traitement parallle.

5.2.5. Lire et crire des SequenceFile


Certains traitements Spark font appel la notion de paires (cl,valeur). Cest le cas de lexemple
initial. Les cls permettent par exemple de classer des valeurs dans un certain ordre.
Pour stocker efficacement ce genre de RDD, on emploie un SequenceFile. Voir la documentation
Hadoop.
Lecture dun SequenceFile dans un RDD
Cette fonction lit les paires du fichier et cre un RDD :

RDD = sc.sequenceFile("hdfs:/share/data1.seq")

criture dun RDD dans un SequenceFile


Cette mthode enregistre les paires (cl, valeur) du RDD :

RDD.saveAsSequenceFile("hdfs:/share/data2.seq")

5.2.6. Actions
Avant de voir les transformations, voyons les actions. Ce sont des mthodes qui sappliquent un
RDD pour retourner une valeur ou une collection.
liste = RDD.collect() retourne le RDD sous forme dune liste Python. Attention la taille
si cest du BigData.
nombre = RDD.count() retourne le nombre dlments

75
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

premier = RDD.first() retourne le premier lment


premiers = RDD.take(n) retourne les n premiers lments.
Note: il ny a pas de mthode last pour retourner le ou les derniers lments.
resultat = RDD.reduce(fonction) applique une fonction dagrgation (associative) du type
fn(a,b)c

grand = RDD.reduce(lambda a,b: max(a,b))

5.2.7. Transformations
Les RDD possdent plusieurs mthodes qui ressemblent aux fonctions map, filter, etc. de Python.
En Python ordinaire, map est une fonction dont le premier paramtre est une lambda ou le nom dune
fonction, le second paramtre est la collection traiter :

liste = [1,2,3,4]
doubles = map(lambda n: n*2, liste)

En pySpark, map est une mthode de la classe RDD, son seul paramtre est une lambda ou le nom
dune fonction :

liste = sc.parallelize([1,2,3,4])
doubles = liste.map(lambda n: n*2)

Les deux retournent les rsultats, liste ou RDD.

5.2.8. Transformations de type map


Chacune de ces mthodes retourne un nouveau RDD partir de celui qui est concern (appel self
en Python).
RDD.map(fonction) : chaque appel la fonction doit retourner une valeur qui est mise dans le
RDD sortant.

RDD = sc.parallelize([1,2,3,4])
print RDD.map(lambda n: n+1).collect()

RDD.filter(fonction) : la fonction retourne un boolen. Il ne reste du RDD que les lments


pour lesquels la fonction retourne True.

RDD = sc.parallelize([1,2,3,4])
print RDD.filter(lambda n: (n%2)==0).collect()

5.2.9. Transformations de type map (suite)


RDD.flatMap(fonction) : chaque appel la fonction doit retourner une liste (vide ou pas) et
toutes ces listes sont concatnes dans le RDD sortant.

76
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

RDD = sc.parallelize([0,1,2,3])
print RDD.flatMap(lambda n: [n]*n).collect()

En Python, la notation [chose]*n produit la liste [ chose chose chose. . . ] contenant n lments. Si
n=0, a cre une liste vide. Exemple ['ok']*3 vaut ['ok', 'ok', 'ok'].
Donc, ici, les rsultats de la lambda sont [], [1], [2, 2], [3, 3, 3] et au retour du flatMap on
aura [1, 2, 2, 3, 3, 3]

5.2.10. Transformations ensemblistes


Ces transformations regroupent deux RDD, self et celui pass en paramtre.
RDD.distinct() : retourne un seul exemplaire de chaque lment.
RDD = sc.parallelize([1, 2, 3, 4, 6, 5, 4, 3])
print RDD.distinct().collect()

RDD1.union(RDD2) : contrairement son nom, a retourne la concatnation et non pas lunion


des deux RDD. Rajouter distinct() pour faire une vraie union.
RDD1 = sc.parallelize([1,2,3,4])
RDD2 = sc.parallelize([6,5,4,3])
print RDD1.union(RDD2).collect()
print RDD1.union(RDD2).distinct().collect()

5.2.11. Transformations ensemblistes (suite)


RDD1.intersection(RDD2) : retourne lintersection des deux RDD.
RDD1 = sc.parallelize([1,2,3,4])
RDD2 = sc.parallelize([6,5,4,3])
print RDD1.intersection(RDD2).collect()

5.2.12. Transformations sur des paires (cl, valeur)


Les transformations suivantes manipulent des RDD dont les lments sont des paires (cl, valeur)
((K,V) en anglais)
RDD.groupByKey() : retourne un RDD dont les lments sont des paires (cl, liste des valeurs
ayant cette cl dans le RDD concern).
RDD.sortByKey(ascending) : retourne un RDD dont les cls sont tries. Mettre True ou
False.
RDD.reduceByKey(fonction) : regroupe les valeurs ayant la mme cl et leur applique la
fonction (a,b)c.
RDD = sc.parallelize([ (1,"paul"),(2,"anne"),
(1,"emile"),(2,"marie"),(1,"victor") ])
print RDD.reduceByKey(lambda a,b: a+"-"+b).collect()

retourne [(1, "paul-emile-victor"), (2, "anne-marie")]

77
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

5.2.13. Transformations de type jointure


Spark permet de calculer des jointures entre RDD1={(K1,V1). . . } et RDD2={(K2,V2). . . } et
partageant des cls K identiques.
RDD1.join(RDD2) : retourne toutes les paires (K, (V1, V2)) lorsque V1 et V2 ont la mme cl.
RDD1.leftOuterJoin(RDD2) : retourne les paires (K, (V1, V2)) ou (K, (V1, None)) si (K,V2)
manque dans RDD2
RDD1.rightOuterJoin(RDD2) : retourne les paires (K, (V1, V2)) ou (K, (None, V2)) si (K,V1)
manque dans RDD1
RDD1.fullOuterJoin(RDD2) : retourne toutes les paires (K, (V1, V2)), (K, (V1, None)) ou (K,
(None, V2))

RDD1 = sc.parallelize([ (1,"tintin"),(2,"asterix"),(3,"spirou") ])


RDD2 = sc.parallelize([ (1,1930),(2,1961),(1,1931),(4,1974) ])
print RDD1.join(RDD2).collect()

78
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Semaine 6

SparkSQL

Le cours de cette semaine prsente le systme SparkSQL. Cest une sur-couche de Spark permettant
dinterroger des donnes laide de SQL directement, et aussi dune API ayant des fonctions identiques.

6.1. SparkSQL
6.1.1. Prsentation
SparkSQL rajoute une couche simili-SQL au dessus des RDD. a sappuie sur deux concepts :
DataFrames Ce sont des tables SparkSQL : des donnes sous forme de colonnes nommes. On peut
les construire partir de fichiers JSON, de RDD ou de tables Hive (voir le dernier cours).
RDDSchema Cest la dfinition de la structure dun DataFrame. Cest la liste des colonnes et de
leurs types. Un RDDSchema peut tre dfini laide dun fichier JSON.
Il y a des liens entre DataFrame et RDD. Les RDD ne sont que des donnes, des n-uplets bruts. Les
DataFrames sont accompagnes dun schma.

6.1.2. Dbut dun programme


Un programme pySpark doit commencer par ceci :

##!/usr/bin/python
from pyspark import SparkConf, SparkContext, SQLContext
from pyspark.sql.functions import *

nomappli = "essai1"
config = SparkConf().setAppName(nomappli)
sc = SparkContext(conf=config)
sqlContext = SQLContext(sc)

sqlContext reprsente le contexte SparkSQL. Cest un objet qui possde plusieurs mthodes dont
celles qui crent des DataFrames et celles qui permettent de lancer des requtes SQL.

6.1.3. Crer un DataFrame


Il y a plusieurs manires de crer un DataFrame. Il faut la fois fournir le schma (noms et types des
colonnes) et les donnes. Lune des mthodes simples consiste utiliser un fichier JSON.

79
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Un fichier JSON est pratique car il contient la fois les donnes et le schma, mais a ne convient
que pour de petites donnes.
Un fichier JSON contient la srialisation dune structure de donnes JavaScript. Pour les donnes
qui nous intressent, cest simple. Chaque n-uplet est englob par {...} ; les champs sont crits
"nom":"valeur". Voici un exemple de trois n-uplets :

{"nom":"Paul"}
{"nom":"mile", "age":30}
{"nom":"Victor", "age":19}

6.1.4. Crer un DataFrame partir dun fichier JSON


SparkSQL a volu, alors la fonction de lecture des JSON nest pas la mme selon la version :
version 1.3 df = sqlContext.jsonFile("NOM.json")
version 1.4 df = sqlContext.read.json("NOM.json")
Elles retournent un DataFrame df contenant les donnes. Voir plus loin ce quon peut en faire.
A savoir quun DataFrame ainsi cr ne connat pas les types des colonnes, seulement leurs noms.

6.1.5. Crer un DataFrame partir dun RDD


Cest plus compliqu car il faut indiquer le schma. Un schma est une liste de StructField. Chacun
est un couple (nom, type).

## cration d'un RDD sur le fichier personnes.csv


fichier = sc.textFile("hdfs:/tmp/personnes.csv")
tableau = fichier.map(lambda ligne: ligne.split(";"))
## dfinition du schma
champ1 = StructField("nom", StringType)
champ2 = StructField("age", IntType)
schema = [champ1, champ2]
## cration d'un DataFrame sur le RDD
personnes = sqlContext.createDataFrame(tableau, schema)

df est un DataFrame contenant les donnes et le schma.

6.1.6. Extraction dinformations dun DataFrame


Il est facile dextraire une colonne dun DataFrame :

colonneAge = df.age

Note: si une proprit est vide ou vaut null, python voit None.
La proprit columns retourne la liste des noms des colonnes :

80
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

print df.columns

La classe DataFrame possde de nombreuses mthodes qui seront prsentes plus loin, page 82.

6.1.7. Donner un nom de table SQL un DataFrame


Cela consiste donner un nom dsignant la future table SQL contenue dans le DataFrame. Cest une
opration ncessaire pour excuter des requtes SQL. En effet, la variable personnes contenant le
DataFrame ne connat pas son propre nom.

personnes.registerTempTable("personnes")

Le DataFrame df pourra tre utilis dans une requte SQL sous le nom personnes. Il est donc
commode de remettre le mme nom que le DataFrame.
NB: ce nest quune table temporaire, elle disparat la fin du programme.

6.1.8. Exemple de requte SQL


Une fois que le DataFrame est rempli et nomm, on peut linterroger. Il y a plusieurs moyens. Le
premier est dcrire directement une requte SQL.

resultat = sqlContext.sql("SELECT nom FROM personnes")

for nuplet in resultat.collect():


print nuplet.nom

Le rsultat de la mthode sql est un nouveau DataFrame contenant les n-uplets demands (doc-
umentation). On les affiche laide dune simple boucle et dun appel collect() comme en
pySpark.
Un autre moyen pour crire des requtes est dappeler les mthodes de lAPI.

6.2. API SparkSQL


6.2.1. Aperu
LAPI SparkSQL pour Python est trs complte. Elle comprend plusieurs classes ayant chacune de
nombreuses mthodes :
DataFrame reprsente une table de donnes relationnelles
Column reprsente une colonne dun DataFrame
Row reprsente lun des n-uplets dun DataFrame
Ces classes permettent dcrire une requte SQL autrement quen SQL, laide dappels de mthodes
enchans.

81
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

6.2.2. Exemple de requte par lAPI


Soit une table de clients (idclient, nom) et une table dachats (idachat, idclient, montant). On veut
afficher les noms des clients ayant fait au moins un achat dun montant suprieur 30.
En SQL, on lcrirait :

SELECT DISTINCT nom FROM achats, clients


WHERE achats.idclient = clients.idclient
AND achats.montant > 30.0;

En pySparkSQL :

resultat = achats.filter(achats.montant > 30.0) \


.join(clients, clients.idclient == achats.idclient) \
.select("nom") \
.distinct()

6.2.3. Classe DataFrame


Cest la classe principale. Elle dfinit des mthodes appliquer aux tables. Il y en a quelques unes
connatre :
filter(condition) retourne un nouveau DataFrame qui ne contient que les n-uplets qui
satisfont la condition. Cette condition peut tre crite dans une chane SQL ou sous forme
dune condition Python.

resultat = achats.filter("montant > 30.0")


resultat = achats.filter(achats.montant > 30.0)

Remarquer la diffrence de nommage des champs.

6.2.4. Mthodes de DataFrame


count() retourne le nombre de n-uplets du DataFrame concern.
distinct() retourne un nouveau DataFrame ne contenant que les n-uplets distincts
limit(n) retourne un nouveau DataFrame ne contenant que les n premiers n-uplets
join(autre, condition, type) fait une jointure entre self et autre sur la condition. Le type
de jointure est une chane parmi "inner" (dfaut), "outer", "left_outer", "right_outer"
et "semijoin"
collect() retourne le contenu de self sous forme dune liste de Row. On peut lutiliser pour
un affichage final :

print achats.filter(achats.idclient == 1).collect()

82
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

6.2.5. Agrgation
groupBy(colonnes) regroupe les n-uplets qui ont la mme valeur pour les colonnes qui sont
dsignes par une chane SQL. Cette mthode retourne un objet appel GroupedData sur lequel
on peut appliquer les mthodes suivantes :
count() : nombre dlments par groupe
avg(colonnes) : moyenne des colonnes par groupe
max(colonnes), min(colonnes) : max et min des colonnes par groupe
sum(colonnes) : addition des colonnes par groupe

tapc = achats.groupBy("idclient").sum("montant")
napc = achats.groupBy("idclient").count()

Lagrgation cre des colonnes appeles daprs la fonction : "AVG(montant)", "MAX(montant)", etc.

6.2.6. Classement
sort(colonnes) classe les n-uplets de self selon les colonnes, dans lordre croissant. Si on
spcifie la colonne par un nom pyspark (table.champ, on peut lui appliquer la mthode desc()
pour classer dans lordre dcroissant ; sinon, il faut employer la fonction desc(colonnes) pour
classer dans lordre dcroissant.

topa = achats.groupBy("idclient").sum("montant") \
.sort(desc("SUM(montant)")).first()

La mthode first retourne le premier n-uplet de self.

83
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Semaine 7

HBase

Le cours de cette semaine se tourne vers la reprsentation des donnes complexes dans Hadoop. HBase
est une base de donnes adapte aux mgadonnes.

7.1. Introduction
7.1.1. Prsentation de HBase
HBase est un systme de stockage efficace pour des donnes trs volumineuses. Il permet daccder aux
donnes trs rapidement mme quand elles sont gigantesques. Une variante de HBase est notamment
utilise par FaceBook pour stocker tous les messages SMS, email et chat, voir cette page.
HBase mmorise des n-uplets constitus de colonnes (champs). Les n-uplets sont identifis par une
cl. laffichage, les colonnes dun mme n-uplet sont affiches successivement :

Cls Colonnes et Valeurs


isbn7615 colonne=auteur valeur="Jules Verne"
isbn7615 colonne=titre valeur="De la Terre la Lune"
isbn7892 colonne=auteur valeur="Jules Verne"
isbn7892 colonne=titre valeur="Autour de la Lune"

7.1.2. Structure interne


Pour obtenir une grande efficacit, les donnes des tables HBase sont spares en rgions. Une rgion
contient un certain nombre de n-uplets contigus (un intervalle de cls successives).
Une nouvelle table est mise initialement dans une seule rgion. Lorsquelle dpasse une certaine limite,
elle se fait couper en deux rgions au milieu de ses cls. Et ainsi de suite si les rgions deviennent
trop grosses.
Chaque rgion est gre par un Serveur de Rgion (Region Server). Ces serveurs sont distribus sur
le cluster, ex: un par machine. Un mme serveur de rgion peut soccuper de plusieurs rgions de la
mme table.
Au final, les donnes sont stockes sur HDFS.

7.1.3. Tables et rgions


Une table est dcoupe en rgions faisant peu prs la mme taille. Le dcoupage est bas sur les cls.
Chaque rgion est gre par un Serveur de rgion. Un mme serveur peut grer plusieurs rgions.
Voir la figure 12, page 85.

84
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Figure 12: Rgions HBase

7.1.4. Diffrences entre HBase et SQL


Voici quelques caractristiques de HBase :
Les n-uplets sont classs selon leur cl, dans lordre alphabtique. Cette particularit est
extrmement importante pour la recherche dinformations. On est amen dfinir les cls de
faon rapprocher les donnes connexes.
Les n-uplets de HBase peuvent tre incomplets. Les colonnes ne sont pas forcment remplies
pour chaque n-uplet, au point quon peut mme avoir des colonnes diffrentes pour les n-uplets.
Ce ne sont pas des valeurs null, mais des colonnes carrment absentes. On qualifie a de
matrice creuse (sparse data).
Les colonnes appeles qualifiers sont groupes en familles.
Les valeurs, appeles cellules sont enregistres en un certain nombre de versions, avec une date
appele timestamp.

7.1.5. Structure des donnes


Au plus haut niveau, une table HBase est un dictionnaire <cl, n-uplet> tri sur les cls,
Chaque n-uplet est une liste de familles,
Une famille est un dictionnaire <nomcolonne, cellule> tri sur les noms de colonnes (aussi
appeles qualifier),
Une cellule est une liste de (quelques) paires <valeur, date>. La date, un timestamp permet
didentifier la version de la valeur.
Donc finalement, pour obtenir une valeur isole, il faut fournir un quadruplet :

(cl, nomfamille, nomcolonne, date)

Si la date est omise, HBase retourne la valeur la plus rcente.

7.1.6. Exemple
On veut enregistrer les coordonnes et les achats de clients. On va construire une table contenant
trois familles :
La famille personne contiendra les informations de base :

85
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

colonnes personne:nom et personne:prenom


La famille coords contiendra ladresse :
colonnes coords:rue, coords:ville, coords:cp, coords:pays
La famille achats contiendra les achats effectus :
colonnes achats:date, achats:montant, achats:idfacture
HBase autorise d-normaliser un schma (redondance dans les informations) afin daccder aux
donnes plus rapidement.

7.1.7. Nature des cls


Les familles et colonnes constituent un n-uplet. Chacun est identifi par une cl.
Les cls HBase sont constitues de nimporte quel tableau doctets : chane, nombre. . . En fait, cest
un point assez gnant quand on programme en Java avec HBase, on doit tout transformer en tableaux
doctets : cls et valeurs. En Java, a se fait par :

final byte[] octets = Bytes.toBytes(donne);

Voir page 92 pour tous les dtails.


Si on utilise le shell de HBase, alors la conversion des chanes en octets et inversement est faite
implicitement, il ny a pas sen soucier.

7.1.8. Ordre des cls


Les n-uplets sont classs par ordre des cls et cet ordre est celui des octets. Cest donc lordre
lexicographique pour des chanes et lordre des octets internes pour les nombres. Ces derniers sont
donc mal classs cause de la reprsentation interne car le bit de poids fort vaut 1 pour les nombres
ngatifs ; -10 est rang aprs 3.
Par exemple, si les cls sont composes de "client" concatne un numro, le classement sera :

client1
client10
client11
client2
client3

Il faudrait crire tous les numros sur le mme nombre de chiffres.

7.1.9. Choix des cls


Pour retrouver rapidement une valeur, il faut bien choisir les cls. Il est important que des donnes
connexes aient une cl trs similaire.
Par exemple, on veut stocker des pages web. Si on indexe sur leur domaine, les pages vont tre
ranges nimporte comment. La technique consiste inverser le domaine, comme un package Java.

86
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

URL URL invers


info.iut-lannion.fr com.alien.monster
monster.alien.com com.alien.www
mp.iut-lannion.fr fr.iut-lannion.info
www.alien.com fr.iut-lannion.mp
www.iut-lannion.fr fr.iut-lannion.www

Mme chose pour les dates : AAAAMMJJ

7.1.10. viter le hotspotting


Il faut galement concevoir les cls de manire viter laccumulation de trafic sur une seule rgion.
On appelle a un point chaud (hotspotting). a arrive si les clients ont tendance manipuler souvent
les mmes n-uplets.
Paradoxalement, a peut tre provoqu par le classement des cls pour lefficacit comme dans le
transparent prcdent.
a vient aussi du fait quil ny a quun seul serveur par rgion2 . Il ny a donc pas de paralllisme
possible.
Pour rsoudre ce problme, on peut disperser les cls en rajoutant du sel , cest dire un bidule
plus ou moins alatoire plac au dbut de la cl, de manire carter celles qui sont trop frquemment
demandes : un timestamp, un hash du dbut de la cl. . .

7.2. Travail avec HBase


7.2.1. Shell de HBase
HBase offre plusieurs mcanismes pour travailler, dont :
Un shell o on tape des commandes,
Une API utiliser dans des programmes Java, voir plus loin,
Une API Python appele HappyBase.
Il y a aussi une page Web dynamique qui affiche ltat du service et permet de voir les tables.
On va dabord voir le shell HBase. On le lance en tapant :

hbase shell

Il faut savoir que cest le langage Ruby qui sert de shell. Les commandes sont crites dans la syntaxe
de ce langage.
2
Une volution de HBase est demande pour permettre plusieurs serveurs sur une mme rgion.

87
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

7.2.2. Commandes HBase de base


Voici les premires commandes :
status affiche ltat du service HBase
version affiche la version de HBase
list affiche les noms des tables existantes
describe 'table' dcrit la table dont on donne le nom.
NB: ne pas mettre de ; la fin des commandes.
Attention bien mettre les noms de tables, de familles et de colonnes entre '...'
Les commandes suivantes sont les oprations CRUD : crer, lire, modifier, supprimer.

7.2.3. Cration dune table


Il y a deux syntaxes :
create 'NOMTABLE', 'FAMILLE1', 'FAMILLE2'...
create 'NOMTABLE', {NAME=>'FAMILLE1'}, {NAME=>'FAMILLE2'}...
La seconde syntaxe est celle de Ruby. On spcifie les familles par un dictionnaire {proprit=>valeur}.
Dautres proprits sont possibles, par exemple VERSIONS pour indiquer le nombre de versions
garder.
Remarques :
Les familles doivent tre dfinies lors de la cration. Cest coteux de crer une famille
ultrieurement.
On ne dfinit que les noms des familles, pas les colonnes. Les colonnes sont cres dynamiquement.

7.2.4. Destruction dune table


Cest en deux temps, il faut dabord dsactiver la table, puis la supprimer :
1. disable 'NOMTABLE'
2. drop 'NOMTABLE'
Dsactiver la table permet de bloquer toutes les requtes.

7.2.5. Ajout et suppression de n-uplets


Ajout de cellules
Un n-uplet est compos de plusieurs colonnes. Linsertion dun n-uplet se fait colonne par colonne.
On indique la famille de la colonne. Les colonnes peuvent tre cres volont.

put 'NOMTABLE', 'CLE', 'FAM:COLONNE', 'VALEUR'


Suppression de cellules
Il y a plusieurs variantes selon ce quon veut supprimer, seulement une valeur, une cellule, ou tout un
n-uplet :

deleteall 'NOMTABLE', 'CLE', 'FAM:COLONNE', TIMESTAMP


deleteall 'NOMTABLE', 'CLE', 'FAM:COLONNE'
deleteall 'NOMTABLE', 'CLE'

88
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

7.2.6. Affichage de n-uplets


La commande get affiche les valeurs dsignes par une seule cl. On peut spcifier le nom de la
colonne avec sa famille et ventuellement le timestamp.

get 'NOMTABLE', 'CLE'


get 'NOMTABLE', 'CLE', 'FAM:COLONNE'
get 'NOMTABLE', 'CLE', 'FAM:COLONNE', TIMESTAMP

La premire variante affiche toutes les colonnes ayant cette cl. La deuxime affiche toutes les valeurs
avec leur timestamp.

7.2.7. Recherche de n-uplets


La commande scan affiche les n-uplets slectionns par les conditions. La difficult, cest dcrire les
conditions en Ruby.

scan 'NOMTABLE', {CONDITIONS}

Parmi les conditions possibles :


COLUMNS=>['FAM:COLONNE',...] pour slectionner certaines colonnes.
STARTROW=>'CLE1', STOPROW=>'CLE2' pour slectionner les n-uplets de [CLE1, CLE2[.
Ou alors (exclusif), une condition base sur un filtre :
FILTER=>"PrefixFilter('binary:client')"
Il existe de nombreux filtres, voir la doc.

7.2.8. Filtres
Lensemble des filtres dun scan doit tre plac entre "...".
Plusieurs filtres peuvent tre combins avec AND, OR et les parenthses.
Exemple :

{ FILTER =>
"PrefixFilter('client') AND ColumnPrefixFilter('achat')" }

PrefixFilter('chane') : accepte les valeurs dont la cl commence par la chane


ColumnPrefixFilter('chane') : accepte les valeurs dont la colonne commence par la chane.

7.2.9. Filtres, suite


Ensuite, on a plusieurs filtres qui comparent quelque chose une valeur constante. La syntaxe gnrale
est du type :
MachinFiter(OPCMP, VAL)
. . . avec OPCMP VAL dfinies ainsi :

89
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

OPCMP doit tre lun des oprateurs <, <=, =, !=, > ou >= (sans mettre de quotes autour)
VAL est une constante qui doit valoir :
'binary:chaine' pour une chane telle quelle
'substring:chaine' pour une sous-chane
'regexstring:motif' pour un motif egrep, voir la doc.
Exemple :

{ FILTER => "ValueFilter(=,'substring:iut-lannion')"}

7.2.10. Filtres, suite


Plusieurs filtres questionnent la cl, famille ou colonne dune valeur :
RowFilter(OPCMP, VAL)
FamilyFilter(OPCMP, VAL)
QualifierFilter(OPCMP, VAL)
accepte les n-uplet dont la cl, famille, colonne correspond la constante
SingleColumnValueFilter('fam','col',OPCMP,VAL)
garde les n-uplets dont la colonne 'fam:col' correspond la constante. Ce filtre est utile pour
garder des n-uplets dont lun des champs possde une valeur qui nous intresse.
ValueFilter(OPCMP, VAL)
accepte les valeurs qui correspondent la constante

7.2.11. Comptage de n-uplets


Voici comment compter les n-uplets dune table, en configurant le cache pour en prendre 1000 la fois
count 'NOMTABLE', CACHE => 1000
Cest tout ?
Oui, HBase nest quun stockage de mgadonnes. Il na pas de dispositif dinterrogations sophistiqu
(pas de requtes imbriques, dagrgation, etc.)
Pour des requtes SQL sophistiques, il faut faire appel Hive. Hive est un SGBD qui offre un
langage ressemblant SQL et qui sappuie sur HBase.

7.3. API Java de HBASE


7.3.1. Introduction
On peut crire des programmes Java qui accdent aux tables HBase. Il y a un petit nombre de classes
et de mthodes connatre pour dmarrer.
Nous allons voir comment :
crer une table
ajouter des cellules
rcuprer une cellule
parcourir les cellules

90
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Noter quon se bat contre le temps, HBase volue trs vite et de nombreux aspects deviennent
rapidement obsoltes (deprecated). LAPI tait en 0.98.12 cette anne (hadoop 2.7.1), maintenant
cest la 2.0 et la 3.0 est dj annonce.

7.3.2. Imports communs


Pour commencer, les classes importer :

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.*;

Ensuite, chaque programme contient ces lignes (API 0.98) qui tablissent une connexion avec le
serveur HBase :

Configuration config = HBaseConfiguration.create();


HBaseAdmin admin = new HBaseAdmin(config);
try {
...
} finally {
admin.close();
}

7.3.3. Cration dune table


Voici une fonction qui cre une table :

static void CreerTable(HBaseAdmin admin,


String nomtable, String... familles)
throws IOException
{
TableName tn = TableName.valueOf(nomtable);
HTableDescriptor htd = new HTableDescriptor(tn);
for (String famille: familles) {
htd.addFamily(new HColumnDescriptor(famille));
}
admin.createTable(htd);
}

Notez que jai fourni le HBaseAdmin en paramtre et que les familles sont sous forme de varargs.

7.3.4. Suppression dune table


Voici comment on supprime une table, en vrifiant au pralable si elle existe :

91
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

static void SupprimerTable(HBaseAdmin admin, String nomtable)


{
TableName tn = TableName.valueOf(nomtable);
if (admin.tableExists(tn)) {
admin.disableTable(tn);
admin.deleteTable(tn);
}
}

7.3.5. Manipulation dune table


Dans les fonctions suivantes, on va modifier les donnes dune table existante. Pour cela, il faut
rcuprer un objet HTable reprsentant la table. Il est important de librer cet objet ds quil ne sert
plus. Voici comment faire en API 0.98 :

static void OperationSurTable(Configuration config,


String nomtable, ...)
{
HTable table = new HTable(config, nomtable);
try {
... oprations sur le contenu de la table ...
} finally {
table.close();
}
}

Prvoir aussi larrive de IOException tout moment.

7.3.6. Insertion dune valeur


Linsertion dune valeur consiste crer une instance de la classe Put. Cet objet spcifie la valeur
insrer :
identifiant du n-uplet auquel elle appartient
nom de la famille
nom de la colonne
valeur
en option, le timestamp lui affecter.
Toutes les donnes concernes doivent tre converties en tableaux doctets.

7.3.7. Transformation en tableaux doctets


HBase stocke des donnes binaires quelconques : chanes, nombres, images jpg, etc. Il faut seulement
les convertir en byte[].
Convertir une donne en octets se fait quelque soit son type par :

92
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

final byte[] octets = Bytes.toBytes(donne);

Dans le cas de cls de n-uplets de type nombre (int, long, float et double), le classement des cls
sera fantaisiste cause de la reprsentation interne, voir cette page. Du fait que le signe du nombre
soit en tte et vaut 1 pour les nombres ngatifs, 0 pour les nombres positifs, un nombre ngatif sera
considr comme plus grand quun positif.
Il est possible dy remdier en trafiquant le tableau doctets afin dinverser le signe mais cest hors
sujet.

7.3.8. Transformation inverse


La rcupration des donnes partir des octets nest pas uniforme. Il faut imprativement connatre
le type de la donne pour la rcuprer correctement. Il existe plusieurs fonctions, voir la doc :

String chaine = Bytes.toString(octets);


Double nombre = Bytes.toDouble(octets);
Long entier = Bytes.toLong(octets);

Dans certains cas, HBase nous retourne un grand tableau doctets dans lequel nous devons piocher
ceux qui nous intressent. Nous avons donc trois informations : le tableau, loffset du premier octet
utile et le nombre doctets. Il faut alors faire ainsi :

Double nombre = Bytes.toDouble(octets, debut, taille);

7.3.9. Insertion dune valeur, fonction

static void AjouterValeur(Configuration config,


String nomtable, String id,
String fam, String col, String val)
{
HTable table = new HTable(config, nomtable);
try {
// construire un Put
final byte[] rawid = Bytes.toBytes(id);
Put action = new Put(rawid);
final byte[] rawfam = Bytes.toBytes(fam);
final byte[] rawcol = Bytes.toBytes(col);
final byte[] rawval = Bytes.toBytes(val);
action.add(rawfam, rawcol, rawval);
// effectuer l'ajout dans la table
table.put(action);
} finally { table.close(); }
}

93
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

7.3.10. Insertion dune valeur, critique


Le problme de la fonction prcdente, cest quon a ajout une valeur de type chane. Il faut
crire une autre fonction pour ajouter un entier, un rel, etc.
Il faudrait rflchir une fonction un peu plus gnrale, laquelle on peut fournir une donne
quelconque et qui lajoute correctement en binaire. Cest pas tout fait trivial, car la mthode
Bytes.toBytes naccepte pas le type Object en paramtre.
Il ne faut pas insrer de nombreuses valeurs une par une avec la mthode table.put. Utiliser
la surcharge table.put(ArrayList<Put> liste).

7.3.11. Extraire une valeur


La rcupration dune cellule fait appel un Get. Il se construit avec lidentifiant du n-uplet voulu.
Ensuite, on applique ce Get la table. Elle retourne un Result contenant les cellules du n-uplet.

static void AfficherNuplet(Configuration config,


String nomtable, String id)
{
final byte[] rawid = Bytes.toBytes(id);
Get action = new Get(rawid);
// appliquer le get la table
HTable table = new HTable(config, nomtable);
try {
Result result = table.get(action);
AfficherResult(result);
} finally { table.close(); }
}

7.3.12. Rsultat dun Get


Un Result est une sorte de dictionnaire (famille,colonne)valeur
Sa mthode getValue(famille, colonne) retourne les octets de la valeur dsigne, sil y en a
une :

byte[] octets = result.getValue(rawfam, rawcol);

On peut parcourir toutes les cellules par une boucle :

void AfficherResult(Result result)


{
for (Cell cell: result.listCells()) {
AfficherCell(cell);
}
}

94
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

7.3.13. Affichage dune cellule


Cest un peu lourdingue car il faut extraire les donnes de tableaux doctets avec offset et taille, et
attention si le type nest pas une chane.
static void AfficherCell(Cell cell)
{
// extraire la famille
String fam = Bytes.toString(cell.getFamilyArray(),
cell.getFamilyOffset(), cell.getFamilyLength());
// extraire la colonne (qualifier)
String col = Bytes.toString(cell.getQualifierArray(),
cell.getQualifierOffset(), cell.getQualifierLength());
// extraire la valeur (PB si c'est pas un String)
String val = Bytes.toString(cell.getValueArray(),
cell.getValueOffset(), cell.getValueLength());
System.out.println(fam+":"+col+" = "+val);
}

7.3.14. Parcours des n-uplets dune table


Raliser un Scan par programme nest pas trs compliqu. Il faut fournir la cl de dpart et celle
darrt (ou alors le scan se fait sur toute la table). On reoit une numration de Result.
static void ParcourirTable(Configuration config,
String nomtable, String start, String stop)
{
final byte[] rawstart = Bytes.toBytes(start);
final byte[] rawstop = Bytes.toBytes(stop);
Scan action = new Scan(rawstart, rawstop);

HTable table = new HTable(config, nomtable);


ResultScanner results = table.getScanner(action);
for (Result result: results) {
AfficherResult(result);
}
}

7.3.15. Paramtrage dun Scan


Il est possible de filtrer le scan pour se limiter :
certaines familles et colonnes (on peut en demander plusieurs la fois), sinon par dfaut, cest
toutes les colonnes.

action.add(rawfam, rawcol);

rajouter des filtres sur les valeurs, par exemple ci-dessous, on cherche les colonnes suprieures
ou gales une limite.
NB: Il faut utiliser la classe CompareOp et BinaryComparator

95
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

BinaryComparator binlimite = new BinaryComparator(rawlimite);


SingleColumnValueFilter filtre = new SingleColumnValueFilter(
rawfam, rawcol, CompareOp.GREATER_OR_EQUAL, binlimite);
action.setFilter(filtre);

7.3.16. Filtrage dun Scan


Pour dfinir une condition complexe, il faut construire un FilterList quon attribue au Scan.
Un FilterList reprsente soit un et (MUST_PASS_ALL), soit un ou (MUST_PASS_ONE). Les
FilterList peuvent tre imbriqus pour faire des combinaisons complexes.

SingleColumnValueFilter filtre1 = ...


QualifierFilter filtre2 = ...

FilterList conjonction = new FilterList(


FilterList.Operator.MUST_PASS_ALL, filtre1, filtre2);
action.setFilter(conjonction);

Attention aux comparaisons de nombres. Elles sont bases sur la comparaison des octets internes, or
gnralement, les nombres ngatifs ont un poids fort plus grand que celui des nombres positifs.

96
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Semaine 8

Hive et Cassandra

HBase est un mcanisme pour stocker des donnes trs volumineuses de type (cl, {valeurs. . . }) et y
accder trs rapidement, mais dune manire trs simpliste :

get 'meteo','id19971225203000','data:temperature'

Hive et Cassandra permettent dutiliser SQL pour interroger les donnes :

SELECT annee, MAX(temperature)


FROM releves
WHERE temperature != 9999 AND quality IN (0,1,4,5,9)
GROUP BY annee;

Hive peut utiliser les donnes de HBase en tant que tables, Cassandra gre ses propres tables.

8.1. Hive
8.1.1. Prsentation rapide
Hive simplifie le travail avec une base de donnes comme HBase ou des fichiers CSV. Hive permet
dcrire des requtes dans un langage inspir de SQL et appel HiveQL. Ces requtes sont transformes
en jobs MapReduce.
Pour travailler, il suffit dfinir un schma qui est associ aux donnes. Ce schma donne les noms et
types des colonnes, et structure les informations en tables exploitables par HiveQL.

8.1.2. Dfinition dun schma


Le schma dune table est galement appel mta-donnes (cest dire informations sur les donnes).
Les mtadonnes sont stockes dans une base de donnes MySQL, appele metastore.
Voici la dfinition dune table avec son schma :

CREATE TABLE releves (


idreleve STRING,
annee INT, ...
temperature FLOAT, quality BYTE,
...)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

97
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

Le dbut est classique, sauf les contraintes dintgrit : il ny en a pas. La fin de la requte indique
que les donnes sont dans un fichier CSV. Voyons dabord les types des colonnes.

8.1.3. Types HiveQL


Hive dfinit les types suivants :
BIGINT (8 octets), INT (4), SMALLINT (2), BYTE (1 octet)
FLOAT et DOUBLE
BOOLEAN valant TRUE ou FALSE
STRING, on peut spcifier le codage (UTF8 ou autre)
TIMESTAMP exprim en nombre de secondes.nanosecondes depuis le 01/01/1970 UTC
donnes structures comme avec Pig :
ARRAY<type> indique quil y a une liste de type
STRUCT<nom1:type1, nom2:type2...> pour une structure regroupant plusieurs valeurs
MAP<typecle, typeval> pour une suite de paires cl,valeur

8.1.4. Sparations des champs pour la lecture


La cration dune table se fait ainsi :

CREATE TABLE nom (schma) ROW FORMAT DELIMITED descr du format

Les directives situes aprs le schma indiquent la manire dont les donnes sont stockes dans le
fichier CSV. Ce sont :
FIELDS TERMINATED BY ';' : il y a un ; pour sparer les champs
COLLECTION ITEMS TERMINATED BY ',' : il y a un , entre les lments dun ARRAY
MAP KEYS TERMINATED BY ':' : il y a un : entre les cls et les valeurs dun MAP
LINES TERMINATED BY '\n' : il y a un \n en fin de ligne
STORED AS TEXTFILE : cest un CSV.

8.1.5. Chargement des donnes


Voici comment charger un fichier CSV qui se trouve sur HDFS, dans la table :

LOAD DATA INPATH '/share/noaa/data/186293'


OVERWRITE INTO TABLE releves;

NB: le problme est que Hive dplace le fichier CSV dans ses propres dossiers, afin de ne pas dupliquer
les donnes. Sinon, on peut crire CREATE EXTERNAL TABLE ... pour empcher Hive de capturer le
fichier.
On peut aussi charger un fichier local (pas HDFS) :

LOAD DATA LOCAL INPATH 'stations.csv'


OVERWRITE INTO TABLE stations;

Le fichier est alors copi sur HDFS dans les dossiers de Hive.

98
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

8.1.6. Liens entre HBase et Hive


Il est galement possible demployer une table HBase.
Cela fait appel la notion de gestionnaire de stockage (Storage Handler). Cest simplement une
classe gnrale qui gre la lecture des donnes. Elle a des sous-classes pour diffrents systmes, dont
HBaseStorageHandler pour HBase.

CREATE TABLE stations(idst INT, name STRING, ..., lat FLOAT,...)


STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH
SERDEPROPERTIES("hbase.columns.mapping" = ":idst,data:name,...")
TBLPROPERTIES("hbase.table.name" = "stations");

La clause SERDEPROPERTIES (serialisation/dsrialisation) associe les noms des colonnes HBase


ceux de la table Hive.

8.1.7. Requtes HiveQL


Comme avec les SGBD conventionnels, il y a un shell lanc par la commande hive. Cest l quon
tape les requtes SQL. Ce sont principalement des SELECT. Toutes les clauses que vous connaissez
sont disponibles : FROM, JOIN, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT.
Il y en a dautres pour optimiser le travail MapReduce sous-jacent, par exemple quand vous voulez
classer sur une colonne, il faut crire :

SELECT... DISTRIBUTE BY colonne SORT BY colonne;

La directive envoie les n-uplets concerns sur une seule machine afin de les comparer plus rapidement
pour tablir le classement.

8.1.8. Autres directives


Il est galement possible dexporter des rsultats dans un dossier :

INSERT OVERWRITE LOCAL DIRECTORY '/tmp/meteo/chaud'


SELECT annee,mois,jour,temperature
FROM releves
WHERE temperature > 40.0;

Parmi les quelques autres commandes, il y a :


SHOW TABLES; pour afficher la liste des tables (elles sont dans le metastore).
DESCRIBE EXTENDED table; affiche le schma de la table

99
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

8.2. Cassandra
8.2.1. Prsentation rapide
Cassandra est indpendant de HBase et mme de Hadoop. On peut configurer un cluster Cassandra
en dehors de Hadoop.
Il gre lui-mme la distribution et la rplication des donnes. Les traitements distribus sont
extrmement rapides, beaucoup plus quavec Hive.
Cassandra offre un langage dinterrogation appel CQL trs similaire SQL. Certains concepts sont
spcifiques.

8.2.2. Modle de fonctionnement


Cassandra est distribu, cest dire que :
1. Les donnes sont disposes sur plusieurs machines, avec ou sans rplication (certaines machines
ont des donnes en commun).
2. Les traitements sont effectus simultanment sur ces machines, selon les donnes quelles ont
par rapport ce quil faut faire.
Cassandra est galement dcentralis, cest dire quaucune machine na un rle particulier. Dans
Hadoop, les machines nont pas les mmes rles : namenode, datanode. . . Dans Cassandra, elles
ont toutes le mme rle : stocker les donnes et calculer les requtes. On peut contacter nimporte
laquelle.

8.2.3. Structure du cluster et donnes


Les machines sont organises en un anneau : chacune est relie une prcdente et une suivante, le
tout formant une boucle. Les communications sont gres laide dun mode appel Gossip (rumeur)
: les informations vont vers quelques machines, qui les relayent vers quelques autres, et ainsi de suite.
Les mises jour de donnes sont donc effectues de proche en proche.
Ce modle sans arbitre central pose un problme pour dfinir la cohrence des donnes (consistency).
un moment donn, il est possible que les machines naient pas toutes les mmes valeurs dans les
tables, le temps que les mises jour se propagent.

8.2.4. Cohrence des donnes


En fait, cest un problme de fond. Dans tout systme de donnes, il est impossible davoir simultan-
ment (thorme CAP) :
la Cohrence : les clients lisent tous la mme valeur au mme moment,
la disponibilit (Availability) : les donnes peuvent tre lues et crites tout moment,
la rsistance aux Partitions : les donnes peuvent tre distribues et rsister des pannes de
communication entre machines.
Chaque systme privilgie deux de ces critres. Par exemple les SGBD SQL ne garantissent que laxe
CA, Cassandra privilgie AP, et HBase que CP.

100
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

8.2.5. Thorme CAP


Concernant la consistance, Cassandra propose trois niveaux :
Consistance stricte Celle des SGBD relationnels. Toute lecture de donnes doit retourner la
dernire valeurs crite.
Consistance causale Si une donne est modifie plusieurs fois en squence par le mme agent, il faut
obliger les lectures retourner la dernire valeur, par contre si elle est modifie simultanment
par des agents diffrents, alors il se peut quon ne relise pas toujours la mme.
Consistance finale Les mises jour sont faites progressivement, en arrire-plan. Les donnes ne
sont cohrentes quau bout dun certain temps, mais il y a un dmon qui
Cela se dfinit lors de la cration des tables.

8.2.6. Modle de donnes


Espace de cls Cest lquivalent dune base de donnes dans le monde SQL. Un keyspace peut
contenir plusieurs tables.
Table Une table regroupe des colonnes. Avant, ctait appel famille de colonnes. Cest plus proche
de HBase que dun SGBD relationnel car il y a une certaine souplesse dans cette notion.
Colonne Elle contiennent les attributs des n-uplets. Comme avec HBase, cest trs libre, sans
normalisation obligatoire.
Partition Cest lquivalent dun n-uplet, une liste de (nom de colonne, valeur). Les n-uplets sont
identifis par une cl.

8.2.7. Stockage des donnes


Les machines Cassandra sont organises en anneau et chacune stocke une partie des n-uplets dune
table. Ce nest pas fait nimporte comment :
les n-uplets sont classs selon lordre de leur cl (identifiant), en fait selon lordre dun hachage
de cette cl, appel token.
plusieurs algorithmes de hachage sont disponibles : murmur, md5, lexicographique.
chaque machine stocke un intervalle de ces hachages (de tel token tel token) et les intervalles
pris en charge se suivent en croissant, selon lordre de lanneau. Cest un peu comme avec
HBase mais sans lindirection des RegionServers.
De cette manire, on sait trs rapidement quelle machine sadresser quand on demande un n-uplet.

8.2.8. Rplication et redistribution des donnes


Les donnes dune machine sont recopies sur les N-1 suivantes le long de lanneau, N tant le nombre
de rplications.
Si une machine devient inaccessible, il faut redistribuer ses tokens sur les autres.
Pour faire tout cela plus facilement et ne pas surcharger le rseau, Cassandra dfinit des nuds
virtuels : une machine physique contient plusieurs machines virtuelles, en fonction de leur puissance
de calcul, chacune stockant un intervalle de tokens.

101
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

8.2.9. Informations sur le cluster


La commande nodetool permet de grer le cluster. On lui fournit un paramtre qui indique quoi
faire :

nodetool info

affiche des informations gnrales sur le cluster

nodetool status

affiche ltat de chaque machine dans le cluster.

8.2.10. Connexion au shell Cassandra CQL


Il faut fournir le nom ou le nIP dune des machines du cluster. Par exemple, lIUT, il suffira de
taper :

cqlsh master

Cela ouvre un shell CQL dans lequel on tape les requtes (D ou exit pour quitter).
La premire connatre est HELP. On peut lui ajouter un paramtre, par exemple HELP DESCRIBE.

8.2.11. Premires commandes


Cration dun espace de cls (ensemble de tables)

CREATE KEYSPACE [IF NOT EXISTS] nomkeyspace


WITH REPLICATION = {
'class': 'SimpleStrategy',
'replication_factor': 2
};

La stratgie SimpleStrategy convient pour les clusters locaux. Ici, les donnes seront rpliques en
2 exemplaires.
Suppression dun keyspace et de tout son contenu

DROP KEYSPACE nomks;

8.2.12. Affichage dinformations


Liste des keyspaces existants

DESCRIBE KEYSPACES;

Structure dun keyspace : cela affiche toutes les commandes servant le reconstruire ainsi que
ses tables

102
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

DESCRIBE KEYSPACE nomkeyspace;

8.2.13. Premires commandes, suite


Slection dun keyspace pour travailler

USE nomkeyspace;

Cration dune table

CREATE TABLE [IF NOT EXISTS] nomtable ( def colonnes );

On peut prfixer le nom de la table par nomkeyspace. si on est hors keyspace ou quon veut en
dsigner un autre.
Les dfinitions de colonnes sont comme en SQL : nom type. Les types sont boolean, int, float,
varchar, text, blob, timestamp, etc.
Il y a des types spciaux, comme counter, list, set, map, etc.

8.2.14. Identification des n-uplets


Soit une table reprsentant des clients :

CREATE TABLE clients (


idclient INT, -- n du client
departement INT, -- n du dpartement, ex: 22, 29, 35...
nom TEXT, ... -- coordonnes du client...
PRIMARY KEY (...)

On a plusieurs possibilits pour la contrainte PRIMARY KEY :


PRIMARY KEY (idclient) : les n-uplets sont identifis par le n client, cest la row key
PRIMARY KEY (departement, idclient) : la cl est composite, departement sert de cl de
partition . Tous les clients du mme dpartement seront sur la mme machine et ils seront
classs par idclient.

8.2.15. Insertion de donnes


Cest un peu comme en SQL et avec dautres possibilits :

INSERT INTO nomtable (nomscolonnes...) VALUES (valeurs...);


INSERT INTO nomtable JSON 'donnes json';

Contrairement SQL, les noms des colonnes concernes sont obligatoires, mais toutes les colonnes
nont pas obligation dy tre, les absentes seront affectes avec null.
Exemple :

103
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

INSERT INTO clients


(idclient, departement, nom) VALUES (1, 22, 'pierre');
INSERT INTO clients
(idclient, nom) VALUES (2, 'paul');
INSERT INTO clients JSON '{"id":3, "nom":"jacques"}';

8.2.16. Insertion par fichier CSV


Il est possible de stocker les donnes dans un fichier CSV et de les injecter dans une table par :

COPY nomtable(nomscolonnes...) FROM 'fichier.csv';

On doit mettre les noms des colonnes dans le mme ordre que le fichier CSV. Ce dernier ne doit pas
contenir de ligne de titre.
Une table peut tre enregistre dans un fichier CSV par :

COPY nomtable(nomscolonnes...) TO 'fichier.csv';

Le fichier sera cr/cras avec les donnes indiques.

8.2.17. Slection de donnes


Cest comme en SQL :

SELECT nomscolonnes... FROM table


[WHERE condition]
[ORDER BY cols ordre]
[LIMIT nombre]
[ALLOW FILTERING];

Les colonnes peuvent utiliser la notation * et faire appel aux fonctions dagrgation COUNT, MIN, MAX,
AVG, SUM.
Il y a une trs forte limite sur la clause WHERE : elle doit slectionner des n-uplets contigus. Donc cest
limit aux conditions sur les cls primaires ou secondaires (crer un index). Les versions rcentes
de Cassandra permettent de questionner sur des intervalles de cls, en ajoutant les mots-cls ALLOW
FILTERING.

8.2.18. Cration dun index secondaire


La cl est un index primaire. On rajoute un index secondaire par :

CREATE INDEX ON table ( nomcolonne );

Lindex sappelle gnralement table_nomcolonne_idx.


Les colonnes indexes peuvent tre questionnes par une clause WHERE.
Pour supprimer un index :

104
IUT de Lannion P. Nerzic
Dept Informatique Outils Hadoop pour le Big Data 2016-17

DROP INDEX table_nomcolonne_idx

8.2.19. Mise jour de n-uplets


UPDATE
DELETE FROM

8.2.20. Autres requtes


Oubliez les jointures et les groupements, il ny en a pas. Cassandra comme les autres systmes sont
destins stocker dnormes volumes de donnes. Les possibilits de traitement sont trs limites.
Pour en faire davantage, il faut programmer avec les API de Cassandra.
CQL offre dautres possibilits : cration de triggers et de fonctions. On peut aussi grer les utilisateurs
et les permissions.

105

Vous aimerez peut-être aussi