Hadoop, première partie : Le système de fichier et le MapReduce au service des gros volumes de données

Nous allons parler dans ce billet d’Hadoop, le framework Java d’Apache en vogue pour le traitement de données très volumineuses (pouvant aller jusqu’à plusieurs pétaoctets). Ce framework implémente notamment sa propre version de l’algorithme MapReduce, qui a été instauré par Google.

 

hadoopNous allons donc d’abord présenter rapidement deux concepts fondamentaux d’Hadoop : son système de fichiers, ainsi que l’algorithme de MapReduce, et ensuite nous illustrerons cela par un exemple simple, avant d’aller plus loin dans de prochains articles.

  • Le système de données distribué d’Hadoop : le HDFS
Hadoop utilise un système de fichiers virtuel qui lui est propre : le HDFS (Hadoop Distributed File System), et qui se décompose en un namenode (le maître) et plusieurs datanodes (les noeuds de données).
Les datanodes regroupent les blocs de données en les répliquant (ci-dessous, les blocs sont tous répliqués trois fois). Le namenode, quant à lui, va orchestrer les données, et contient les informations concernant l’emplacement des différentes répliques. Le secondary namenode  sert à effectuer des checkpoints réguliers du namenode, afin de les réutiliser en cas de problème. Ci-dessous un schéma expliquant les différents noeuds du HDFS :
 

  • l’algorithme de MapReduce dans Hadoop :
Le MapReduce est une technique qui décompose le traitement d’une opération (appelée « job » chez Hadoop) en plusieurs étapes, dont deux élémentaires, afin d’optimiser un traitement parallèle des données.

i. Le « Mapping » :

Cette étape accomplit une opération spécifique sur chaque élément de la liste en input : à partir d’une liste sous la forme <clé,valeur>, il génère alors une liste en output sous la même forme :

ii. Le « Reducing » :

L’opération qui se situe après le Mapping et le Reducing est appelée le Shuffling, et réarrange les éléments de la liste afin de préparer le Reducing.
Le traitement voulu est alors effectué, donnant l’output final :
  • Un exemple de traitement de MapReduce avec Hadoop :
Nous avons donc pu nous familiariser avec les concepts clés d’Hadoop, il est temps d’illustrer cela par un exemple. Nous n’avons pas un pétaoctet de données sous la main, mais nous allons profiter de la prolifération de l’open data pour effectuer un petit traitement sur des données simples. Le site open data de nos amis belges data.gov.be donne librement accès à de nombreuses données, comme par exemple la liste des différents prénoms recensés en Belgique en 2007, qui se présente sous la forme d’un fichier Excel contenant plus de 38 000 entrées.
Ces données existent aussi pour les femmes, nous avons tout concaténé afin d’avoir un fichier .csv regroupant tous les prénoms belges en 2007, hommes et femmes, sous la forme (Nom,Nombre d’apparitions) :


 
Traitement des données :
Le traitement que nous voulons faire est simple : nous voulons avoir le nombre de personnes par lettre de l’alphabet en Belgique. Pour ce faire, il suffit de créer une fonction Map et une fonction Reduce adaptée à nos besoins, et sous la bonne forme (clé,valeur), afin qu’Hadoop puisse alors effectuer le traitement.

Voici comment vont être réalisées les différentes opérations :

 

Implémentation en Java des méthodes Map et Reduce :

public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
       public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
              String[] tokens = value.toString().split(",");
              String cle = tokens[0].substring(0,1);
              int valeur = Integer.parseInt(tokens[1]);
              context.write(new Text(cle), new IntWritable(valeur));
       }
}
public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> {
       public void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException,InterruptedException {
              int sum = 0;
              for (IntWritable val : values) {
                   sum += val.get();
              }
       context.write(key, new IntWritable(sum));
       }
}

 

Nous pouvons maintenant exporter en un jar executable, qu’on va ensuite pouvoir lancer avec Hadoop. Mais tout d’abord, il faut que le fichier en entrée (pour nous la liste des prénoms et le nombre d’apparitions correspondantes) soit dans le HDFS. Pour ce faire, il suffit d’utiliser la gestion du HDFS par ligne de commande :

hadoop fs -mkdir /input
hadoop fs -put /repertoire_local/noms_belges.csv /input

 

Nous pouvons alors éxécuter le jar via Hadoop, en demandant que le fichier de sortie soit crée dans le dossier output du HDFS, qui sera alors créé. Il suffit alors de récupérer ce fichier en local sachant que, par défaut, le fichier est nommé « part-r-00000 » :

hadoop jar /repertoire_local/exemple.jar /input/noms_belges.csv /output
hadoop fs -get /output/part-r-00000 /repertoire_local_sortie

 

Voici un aperçu du fichier obtenu :

Nous avons donc pu voir les possibilités offertes par Hadoop pour le traitement distribué des données, et sa simplicité de mise en oeuvre.
Pour plus d’informations, vous pouvez consulter la documentation d’Apache, ou le très complet « Hadoop : The Definitive Guide« , de Tom White.

5 pensées sur “Hadoop, première partie : Le système de fichier et le MapReduce au service des gros volumes de données

  • 17 juillet 2012 à 14 h 51 min
    Permalink

    Paragraphe ii : le shuffling a lieu après le mapping et le reducing pour préparer le reducing ? Ce n’est pas très clair : c’est récursif ?
    Des concepts intéressants, mais je n’ai vu ( ou pas compris ) dans l’exemple à quel moment la logique de distribution était mise en œuvre.
    Merci en tous les cas.

    Répondre
  • 18 juillet 2012 à 17 h 24 min
    Permalink

    1) shuffling non c’est une étape intermédiaire entre le map et le reduce pour trier les données selon le key
    2) les jobs seront distribué sur les machines banales donc le set initial des données sera splité sur n machine exécutant chacune un job map. Chaque output sera traité par un nœud selon l’implémentation reduce.

    Répondre
  • 19 juillet 2012 à 10 h 03 min
    Permalink

    Bonjour Yannick, 

    Comme l’a dit Tunisiano, le shuffling a lieu entre le mapping et le reducing, ce n’est pas récursif :
    1/mapping 2/shuffling 3/reducing
    Désolé si ce n’était pas clair!
    La logique de distribution est présente en fait à chaque étape. Il faut imaginer que les données sont réparties sur plusieurs noeuds, et que du coup le mapping se fait parallèlement sur les différents noeuds, puis le shuffling, puis le reducing.
    Si vous avez d’autres questions, n’hésitez-pas!

    Elias

    Répondre
  • 19 juillet 2012 à 13 h 29 min
    Permalink

    A propos de Hadoop, je signale l’article suivant fort intéressant:

    « Why the days are numbered for Hadoop as we know it — Cloud Computing News »
    http://gigaom.com/cloud/why-the-day

    Cet article indique la chose suivante :
    – Hadoop est tout à fait utile pour tout un nombre de traitements divers et variés
    – pour certains traitements particuliers, Google a créé, il y a maintenant quelques années (!), un certain nombre d’autres plates-formes pour obtenir de meilleures performances

    L’article+les commentaires donnent qques refs d’outils open source qui tendent vers qq chose qui ressemblent aux plates-formes propriétaires de Google, mais il y a encore pas mal de chemins à faire, contrairement à Hadoop bcp plus connu et popularisé.

    Répondre
  • 1 août 2016 à 21 h 08 min
    Permalink

    Bonjour je travailles chez Google et je peux vous dire que plus personne n’utilise mapreduce chez nous

    Répondre

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

%d blogueurs aiment cette page :