Notes de cours Practical BigData Nguyen-Nhut DOAN 15 janvier 2015 Introduction Ces notes personnelles traduisent la deuxième partie du cours INF553 de l Ecole Polytechnique sur les bases de données et les challenges de BigData. On commence par une petite introduction d Hadoop, puis MapReduce et enfin d autres compositions de ce système. Ses notes personnelles sont pour objectif de faire un soutien et un complément du cours. Le cours est basé sur la méthode Hadoop, The definitive guide de Tom White. 1 Installation d Hadoop sur Macbook Voici mon processus d installer Hadoop sur un Macbook pro (MacOSX 10.9.5). 1. Aller au site web d Apache Hadoop et télécharger la version recommandée. 2. Extraire le fichier tar et le localiser dans un certain dossier (Par exemple : /user/hadoop-2.6.0 ) 3. Ouvrir le fichier bash profile en tapant % open -a TextEdit.app.bash_profile 4. Ajouter ces lignes au fichier ouvert export HADOOP_INSTALL=/user/hadoop-2.6.0 PATH=$PATH:$HADOOP_INSTALL/bin 5. Tester en tapant % hadoop version L écran devrait afficher quelque chose de similaire à : Hadoop 2.6.0 Subversion https://git-wip-us.apache.org/repos/asf/hadoop.git -r e3496499ecb8d220fba99dc5ed4c99c8f9e33bb1 Compiled by jenkins on 2014-11-13T21:10Z Compiled with protoc 2.5.0 From source with checksum 18e43357c8f927c0695f1e9522859d6a This command was run using /user/hadoop-2.6.0/share/hadoop/common/hadoop-common-2.6.0.jar 1
2 Trois modes de fonction d Hadoop et configuration 2.1 Configuration Il est nécessaire de remarquer que les propriétés commune peuvent être écrites dans le fichier core-site.xml, que les propriétés de HDFS dans hdfs-site.xml, et que MapReduce dans mapred-site.xml. Les trois fichiers se trouvent dans le dossier /user/hadoop-2.6.0/etc/hadoop. Hadoop est capable de fonctionner en trois modes : Mode locale Mode pseudo-distribuée Mode distribuée 2.2 Mode locale Rien à modifier dans des trois fichiers mentionnés ci-dessus. 2.3 Mode pseudo-distribuée Il faut modifier respectivement les trois fichiers ci-dessus en : <?xml version="1.0"?> <!-- core-site.xml --> <configuration> <property> <name>fs.default.name</name> <value>hdfs://localhost/</value> </property> </configuration> <?xml version="1.0"?> <!-- hdfs-site.xml --> <configuration> <property> <name>dfs.replication</name> <value>1</value> </property> </configuration> <?xml version="1.0"?> <!-- mapred-site.xml --> <configuration> <property> <name>mapred.job.tracker</name> <value>localhost:8021</value> </property> </configuration> 2
Ensuite il faut lancer ssh pour faire fonctionner deamons. Si on n a pas encore ssh, il suffit simplement de l installer par la commande (ou similaire) : % sudo apt-get install ssh 2.4 Mode distribuée À mettre à jour très bientôt. 3 Pourquoi Hadoop? 3.1 Challanges des données 3.2 Stockage et analyse des données 3.3 Quelques mots sur Hadoop 4 Introduction de MapReduce 4.1 Premier exemple On commence par un exemple q ui vient des observations météorologiques. Les données se trouvent sur le site web http://www.ncdc.noaa.gov/, qui sont de la même forme que dans le fichier suivant http://hurricane.ncdc.noaa.gov/cdo/3505dat.txt. Il y a environ 10 000 fichiers correspondants aux différentes stations du monde. Si on va rassembler tous les fichiers du XXe siècle par exemple, il faut un nombre énorme des fichiers de taille petite. Il est souvent plus facile de travailler avec peu de fichiers de grosse taille plutôt qu avec trop de fichiers de taille petite. Il est donc possible de joindre ces derniers pour faciliter la vie. On aura des fichiers dont les lignes sont à la forme : 0067011990999991950051507004...9999999N9+00001+99999999999... On considère maintenant le problème de trouver la température maximale pour chaque an. Dans chaque ligne, l an et la température en degré se trouvent en positions suivantes : 0067011990999991950051507004...9999999N9+00001+99999999999... L objectif est de traverser toutes les lignes de ce gros fichier pour chercher les températures annuelles maximales. 4.2 Analyse de données avec Hadoop et Java La figure 1 nous montre le logique de MapReduce pour résoudre le problème de max température. 4.2.1 Mapper Voici les codes en Java. Il y aura 3 parties : une méthode Map, une méthode Reduce et une classe centrale qui appelle ces processus. 3
Figure 1 Logique MapReduce pour MaxTemperature import java.io.ioexception; import org.apache.hadoop.io.intwritable; import org.apache.hadoop.io.longwritable; import org.apache.hadoop.io.text; import org.apache.hadoop.mapred.mapreducebase; import org.apache.hadoop.mapred.mapper; import org.apache.hadoop.mapred.context; public class MaxTemperature { static class MaxTemperatureMapper extends Mapper<LongWritable, Text, Text, IntWritable> { private static final int MISSING = 9999; public void map(longwritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.tostring(); String year = line.substring(15, 19); int airtemperature; if (line.charat(87) == + ) { // parseint doesn t like leading plus signs airtemperature = Integer.parseInt(line.substring(88, 92)); else { airtemperature = Integer.parseInt(line.substring(87, 92)); String quality = line.substring(92, 93); if (airtemperature!= MISSING && quality.matches("[01459]")) { context.write(new Text(year), new IntWritable(airTemperature)); 4
Quelques remarques : L interface Mapper prendre 4 paramètres qui sont les types des clés et des valeurs de l input et output. Les types IntWritable et LongWritable correspondent aux int et long de Java alors que le type Text correspond au String de Java. Context est l environnement où l on écrit l output de Mapper. L input et l output sont toujours des paires clef-valeur. La méthode map agit en fonction de la clé. 4.2.2 Reducer import java.io.ioexception; import java.util.iterator; import org.apache.hadoop.io.intwritable; import org.apache.hadoop.io.text; import org.apache.hadoop.mapred.mapreducebase; import org.apache.hadoop.mapred.outputcollector; import org.apache.hadoop.mapred.reducer; import org.apache.hadoop.mapred.reporter; static class MaxTemperatureReducer extends Reducer<Text, IntWritable, Text, IntWritable> { public void reduce(text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int maxvalue = Integer.MIN_VALUE; for (IntWritable value : values) { maxvalue = Math.max(maxValue, value.get()); context.write(key, new IntWritable(maxValue)); Remarque : La deuxième paramètre de Reducer est maintenant un EtIterable de Java. Rappelons que pour traverser une Iterable, il suffit d utiliser for i : I. L input et l output sont toujours des paires clef-valeur. 4.2.3 La fonction main import java.io.ioexception; import org.apache.hadoop.fs.path; 5
import org.apache.hadoop.io.intwritable; import org.apache.hadoop.io.text; import org.apache.hadoop.mapred.fileinputformat; import org.apache.hadoop.mapred.fileoutputformat; import org.apache.hadoop.mapred.job; public static void main(string[] args) throws Exception{ if (args.length!= 2) { System.err.println("Usage: MaxTemperature <input path> <output path>"); System.exit(-1); Job job = new Job(); job.setjarbyclass(maxtemperature.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); job.setmapperclass(maxtemperaturemapper.class); job.setreducerclass(maxtemperaturereducer.class); job.setoutputkeyclass(text.class); job.setoutputvalueclass(intwritable.class); System.exit(job.waitForCompletion(true)? 0 : 1); Remarque : Job appelle la classe à faire fonctionner et crée des Jars. Job précise aussi le mapper et reducer à employer ainsi que les types du résultat. API : Un ensemble de fonctions et méthodes qui permettre de créer des applications accédant des données d un système d exploitation, une application ou d autres services. 4.3 Comment fonctionne MapReduce? Un job MapReduce est une unité de travail que les clients voudraient réaliser, comprenant des données input, un programme MapReduce, et des information de configuration. Le job est divisé en tâches de type Map et Reduce. Les noeuds qui contrôle l exécution du job : un jobtracker et des tasktracker. Jobtracker distribue le travail aux tasktrackers. Tasktrackers fonctionnent et envoient un rapport de progression au jobtracker. Hadoop divide l input en split. Splits sont traités en parallèle. Plus de splits, moins de temps traité en général. Si les splits sont très petits, le temps dominant est celui de gestion des splits et 6
création des Map-tâches. Pour la plupart des jobs, une taille possible des split est celui d un bloc HDFS, 64 MB par défaut. Data locality optimization : Map-tâches fonctionnent sur un noeud où les données input résident dans HDFS. Les map-tâches écrivent les résultat sur une disque locale et non pas sur HDFS car les outputs de Map sont intermédiaires. À la complétion des tâches, les outputs de Map pourront être jetés. Si le noeud qui traite une map-tâche rate, jobtracker désigne un autre noeud à réaliser sa tâche. Reduce ne possède pas l avantage de localité des données. On distingue les cas où il n y a qu un seul Reduce-tâche, où plusieurs reduce-tâches sont présentes, et où il n y a aucune reduce-tâche. (figure 2, 3). Figure 2 1 reduce-tâche vs plusieurs reduce-tâches vs 0 reduce-tâche Dans le cas de plusieures reduce-tâches, il existe un étape de combiner des fonctions. La fonction combinante fait le même truc que Reducer. Il suffit d ajouter une ligne dans la fonction main : public static void main(string[] args) throws Exception{ if (args.length!= 2) { System.err.println("Usage: MaxTemperature <input path> <output path>"); System.exit(-1); Job job = new Job(); job.setjarbyclass(maxtemperature.class); FileInputFormat.addInputPath(job, new Path(args[0])); 7
FileOutputFormat.setOutputPath(job, new Path(args[1])); job.setmapperclass(maxtemperaturemapper.class); job.setcombinerclass(maxtemperaturereducer.class); job.setreducerclass(maxtemperaturereducer.class); job.setoutputkeyclass(text.class); job.setoutputvalueclass(intwritable.class); System.exit(job.waitForCompletion(true)? 0 : 1); 4.4 Hadoop Streaming Hadoop fournit un API pour MapReduce qui nous permet d écrire les fonctions Map et Reduce en autres langages que Java. Hadoop Streaming utilise les streams (fluxe) standards d Unix comme interfaces entre Hadoop est le programme. Il est donc possible d utilser quelque soit le programme qui est capable de lire l input standard et écrire un output standard. Input de reduce et output de map sont de formes tsv avec des paires clés-valeurs. On verra des exemples avec le même problème (écrit en Java) maintenant écrit en Python et C++ (Hadoop Pipes) pour illustrer le point. 8