IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hadoop & co Discussion :

Probleme de Output.collect mapreduce: des attributes pas a jour?


Sujet :

Hadoop & co

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2014
    Messages : 54
    Points : 47
    Points
    47
    Par défaut Probleme de Output.collect mapreduce: des attributes pas a jour?
    Bonjour,

    J'ai un petit souci avec Hadoop que j'etais entrain d essayer de resudre depuis deux jours mais en vain !!

    J ai la methode map suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public
          void
          map(LongWritable key, Text value, OutputCollector<Text, MyObject> output, Reporter reporter)
                                                                                                                     throws IOException {
    
    try {
    
      ForXmlHandling message = (ForXmlHandling) unmarshaller.unmarshal(new StringReader(value.toString()));
    
      MyObject row = XmlParser.parse(message);
    
       row.setOrigin(true);
      output.collect(new Text(row.getRecordKey().toString()), row);
      }
    
    catch(JAXBException e) {
       LOG.debug(e);
    }
    ouMyObject est un object que j ai cree:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public class MyObject  {
    
      private boolean                   original;
      private boolean                   split;
      ....
    
      }
    E fait, en lancant le mapper dans le mode debug, meme en settant l attribut origin de l pbjet row à true, l'output du mapper (output.collect) est toujours un object row mais avec l attribut origin setté à false (valeur par defaut d un boolean). Je ne comprends pas qu est ce que le probleme avec output.collect et pourquoi il ne prend pas l objet row mis a jour.

    Auriez vous des idees ? Aurais je rate quelque chose ?

    Merci d avance de votre aide!!

  2. #2
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 190
    Points : 182
    Points
    182
    Par défaut
    Bonjour,

    c'est quoi comme version hadoop, sandbox, linux, window, cloudera, apache, hortonworks . ?

    Je ne sais pas si il y a tout le code et d'après ce que je peux comprendre, je ne vois vois pas le context.write des arguments en sortie du mapper
    il doit être aussi au niveau du reducer, je vois que le set dans les objets output avec l'utilisation de la methode collect de OutputCollector. regardez de ce côté.
    ca necessite de revoir les paramètres du mapper pour essayer avec un write

    exemple, voir les fonctions map/reduce
    http://codingjunkie.net/mapreduce-reduce-joins/

    il est possible que le reducer se plante (auquel cas il faut regarder les logs mapred/yarn) ou qu'il travaille sur des données nulles et que le résultat en soit altéré
    ou vide

    Il faut raisonner, KEYIN, VALUEIN, KEYOUT, VALUEOUT avec leur type

    je ne sais pas si le collect est correctement utilisé

    public void map(LongWritable key, Text value, OutputCollector<LongWritable, Text> output, Reporter reporter) throws IOException {

    newID = randomGenerator.nextInt(10000);
    newValue = value + ":" + newID;
    output.collect(new LongWritable(newID), new Text(newValue));
    }

    Autre solution, utilisez un objet Boolean avec set Boolean.False par default, et pas les primitifs, pour voir si ce n'est pas un soucis de serialization

    2 Jours, c'est rien , des que vous mettez le pied dedans, compter en semaines voir en mois selon les problèmes, hadoop est un enfer qui doit se mériter,

    cdt

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2014
    Messages : 54
    Points : 47
    Points
    47
    Par défaut
    J utilise hadoop apache.

    EN fait, tout s effectue normalement comme je voulais jusqu a ce que je fais output.collect!!!

    J ai fait un petit test en lancant uniquement le mapper sur un petit echantillon de donnees, et du coup ca ne marche pas ( j ai fait comme bordi m a suggere: utuiliser Boolean au lieu de boolean mais en vain)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    ublic
          void
          map(LongWritable key, Text value, OutputCollector<Text, MyObject> output, Reporter reporter)
                                                                                                                     throws IOException {
    
    try {
    
      ForXmlHandling message = (ForXmlHandling) unmarshaller.unmarshal(new StringReader(value.toString()));
    
      MyObject row = XmlParser.parse(message);
      LOG.debug("origin attribute in row: {}", row.isOrigin);
       row.setOrigin(false);
      output.collect(new Text(row.getRecordKey().toString()), row);
      }
    
    catch(JAXBException e) {
       LOG.debug(e);
    }
    Le log me retourne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    origin attribute in row: true
    (qui est la valeur attendue, vu ce que j ai implemetne dans mon code).
    Et en essayant de la modifier avant d ecrire le resultat dans le mapper: rien ne se passe. Au contraire, le mapper me retourne un objet row avec origin = null!!!.

    Ca veut dire que lorsque je change l etat de l attribut origin dans mon code, cela n a aucun effet sur le mapper!!!

    Je suis vraiment perdu !!!

  4. #4
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 190
    Points : 182
    Points
    182
    Par défaut
    Citation Envoyé par ahmadou_20 Voir le message
    J utilise hadoop apache.

    EN fait, tout s effectue normalement comme je voulais jusqu a ce que je fais output.collect!!!
    Le log me retourne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    origin attribute in row: true
    (qui est la valeur attendue, vu ce que j ai implemetne dans mon code).
    Et en essayant de la modifier avant d ecrire le resultat dans le mapper: rien ne se passe. Au contraire, le mapper me retourne un objet row avec origin = null!!!.
    question bête, la méthode setOrigin et bien implémentée ?

    il y a bien le this ?, ca arrive parfois, ce genre de truc, surtout quand on cherche ailleurs

    void setOrigin( Boolean origin ) {

    this.origin=origin;
    }

    affichez la valeur après l'appel du setOrigin(..), si il y a la valeur dans la methode collect qu'il y un problem.

    LOG.debug("origin attribute in row: Before setOrgin {}", row.isOrigin);
    row.setOrigin(false);
    LOG.debug("origin attribute in row: After setOrigin {}", row.isOrigin);
    output.collect(new Text(row.getRecordKey().toString()), row);

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2014
    Messages : 54
    Points : 47
    Points
    47
    Par défaut
    Le setter fonctionne parfaitement. Je viens de le tester maintenant et il produit les resultats auxquels je m attends:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    LOG.debug("origin attribute in row: Before setOrgin {}", row.isOrigin);
    row.setOrigin(false);
    LOG.debug("origin attribute in row: After setOrigin {}", row.isOrigin);
    output.collect(new Text(row.getRecordKey().toString()), row);
    produit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    origin attribute in row: Before setOrgin true
    origin attribute in row: AftersetOrgin false
    Par contre, le output de mapper contient un objet row avec l attribut origin egal a null (valeur par defaut de Boolean).
    Donc les valeurs des atributs de MyObject row s updatent parfaitement avec les differents setters que j appelle mais quand il s agit d ecrire le resultat final (apres ces updates) au mapper, il bugge.!!!!!!!!

  6. #6
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 190
    Points : 182
    Points
    182
    Par défaut
    Citation Envoyé par ahmadou_20 Voir le message
    Le setter fonctionne parfaitement. Je viens de le tester maintenant et il produit les resultats auxquels je m attends:
    Par contre, le output de mapper contient un objet row avec l attribut origin egal a null (valeur par defaut de Boolean).
    Donc les valeurs des atributs de MyObject row s updatent parfaitement avec les differents setters que j appelle mais quand il s agit d ecrire le resultat final (apres ces updates) au mapper, il bugge.!!!!!!!!
    On peut voir le typage de la classe qui utilise votre mapper

    public class Dummy extends ????? implement Mapper ??????? {

    ....
    map(....)
    ...

    }

  7. #7
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2014
    Messages : 54
    Points : 47
    Points
    47
    Par défaut
    Mapper:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    
    public class SbrXmlMapper implements Mapper<LongWritable, Text, Text, SbrXmlParserValueOutput> {
      
      private final static Logger LOG                   = LoggerFactory.getLogger(SbrXmlParser.class);
      
      private Unmarshaller        unmarshaller;
      
        
      @Override
      public void configure(JobConf iJobConf) {
      
        try {
          
          JAXBContext jc = JAXBContext.newInstance(ForPnrHandling.class);
          
          this.unmarshaller = jc.createUnmarshaller();
                
        }
        
        catch(JAXBException e) {
          
          LOG.error(e.getMessage());
        }
        
      }
      
      @Override
      public void close() throws IOException {
      
      }
      
      @Override
      public
              void
              map(LongWritable key, Text value, OutputCollector<Text, SbrXmlParserValueOutput> output, Reporter reporter)
                                                                                                                         throws IOException {
      
        try {
          
              ForXmlHandling message = (ForXmlHandling) unmarshaller.unmarshal(new StringReader(value.toString()));
          
            List<SbrXmlParserValueOutput> rows = SbrXmlParser.parse(message); //parse est une methode que j appelle pour processer un message.
          
              for(SbrXmlParserValueOutput row : rows) {
    
              LOG.debug("Row original before {}", row.isOriginal());
              row.setOriginal(false);
              LOG.debug("Row original after {}", row.isOriginal());
              
              output.collect(new Text(row.getRecordKey().toString()), row);
            }
          }
          
        }
        
        catch(JAXBException e) {
          
         LOG.debug(e);
          
        }
    Reducer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    public class SbrXmlReducer implements org.apache.hadoop.mapred.Reducer<Text, SbrXmlParserValueOutput, Text, Text> {
      
    
      
      @Override
      public void reduce(Text key, Iterator<SbrXmlParserValueOutput> values, OutputCollector<Text, Text> output,
                         Reporter reporter) throws IOException {
      
        Map<String, SbrXmlParserValueOutput> reduced = SbrXmlParser.reduce(key.toString(), values);
    
        OutputCollector collector = null;
    
        for(Entry<String, SbrXmlParserValueOutput> entry : reduced.entrySet()) {
          
          output.collect(new Text(entry.getValue().getItineraryKey().toString()), new Text(entry.getValue()
                                                                                                   .getJSON()
                                                                                                   .toString()));
          if(collector != null) {
            collector.collect(new Text(entry.getValue().getItineraryKey().toString()), new Text(entry.getValue()
                                                                                                        .getRecordKey()
                                                                                                        .toString()));
          }
        }
        
      }
    Je tiens a preciser que je pense que le probleme vient du mapper parce que output.collect (dans le mapper) n a pas l air de prendre les bonnes valeurs.

  8. #8
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 190
    Points : 182
    Points
    182
    Par défaut
    Une hypothese à vérifier, normalement on utilise des writable types hadoop (IntWritable,LongWritable,etc..) pour permettre la serialization/deserialisation interne entre mapper/reducer et qui nécessite l'implémentation de méthode writable dans le cas d'objet ou d'utiliser les writable type hadoop existant, je ne sais pas si il est possible de s'en passer en l'état de mes connaissance.

    comme vous semblez avoir un objet qui n'utilise peut être pas les writable type hadoop (?), il est possible que cela peut expliquer les pertes de données après exécution du colllect quand il part de l'autre côté, row devient null quand il utilse la serialization/deserialization hadoop lors des échanges.


    https://developer.yahoo.com/hadoop/t....html#writable

    exemple

    public class MyObject implements Writable {

    ....
    public void write(DataOutput out) throws IOException {
    // TODO Auto-generated method stub
    out.writeBoolean(origin);

    }
    @Override
    public void readFields(DataInput in) throws IOException {
    // TODO Auto-generated method stub

    origin=in.readBoolean();
    }

  9. #9
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 190
    Points : 182
    Points
    182
    Par défaut
    J'ai trouvé un exemple un peu approchant d'un objet utilisateur véhiculer par le mapper/reducer via OutputCollector

    le mapper

    http://www.javased.com/?source_dir=b...othMapper.java

    public class BehemothMapper implements Mapper<Text, BehemothDocument, Text, BehemothDocument> {

    public void map(Text key, BehemothDocument inputDoc, OutputCollector<Text, BehemothDocument> output, Reporter reporter)


    l'object BehemothDocument transportation avec l'implementation des types writable

    public class BehemothDocument implements Writable {

    http://www.javased.com/?source_dir=b...hDocument.java


    Le reducer

    public class BehemothReducer implements Reducer<Text, BehemothDocument, Text, BehemothDocument> {

    public void reduce(Text key, Iterator<BehemothDocument> doc, OutputCollector<Text, BehemothDocument> output, Reporter reporter)

    http://www.javased.com/?source_dir=b...thReducer.java

    On peut noter, dans la clase BehemothDocument, le respect de la seriailization/deserialization de l'objet, avec les méthodes write/readfFields de l'interface
    writeTable

    Si ca peut aider

  10. #10
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2014
    Messages : 54
    Points : 47
    Points
    47
    Par défaut
    Oui effectivement Bordi!! Merci beaucoup!!

    Le probleme venait du fait que les methodes
    readFields
    et
    write
    dans MyObject (implementant Writable) ne consideraient pas mes deux booleans origin et split.
    Du coup la serialization/deserialisation interne entre mapper/reducer ne se deroulait pas convenablement.

    Maintenant, j'ai ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
     public void write(DataOutput out) throws IOException {
    
        _original.write(out);
        _split.write(out);
      }
      
      public void readFields(DataInput in) throws IOException {
      
        _original = new BooleanWritable();
        _split = new BooleanWritable();
        
        _original.readFields(in);
        _split.readFields(in);
      }
    Par ailleurs, j ai du changer le type boolean en BooleanWritable. Et ca marchait parfaitement !!!

    Merci encore une fois.

  11. #11
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 190
    Points : 182
    Points
    182
    Par défaut
    Citation Envoyé par ahmadou_20 Voir le message
    Oui effectivement Bordi!! Merci beaucoup!!

    Le probleme venait du fait que les methodes et dans MyObject (implementant Writable) ne consideraient pas mes deux booleans origin et split.
    Du coup la serialization/deserialisation interne entre mapper/reducer ne se deroulait pas convenablement.

    Par ailleurs, j ai du changer le type boolean en BooleanWritable. Et ca marchait parfaitement !!!

    Merci encore une fois.

    Content que vous ayez résolu votre problème, il est souvent difficile de trouver des réponses dans le monde hadoop, et c'est très coûteux en temps.
    c'est pour ca que je parle souvent tout seul dans mes fils jusqu'à que j'ai trouvé la solution.

    Je repars me replonger dans le monde du machine learning, spark/mahout/R, c'est aussi un gros bazar.

    bonne continuation

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 09/07/2015, 17h48
  2. Réponses: 12
    Dernier message: 20/05/2009, 16h32
  3. Réponses: 1
    Dernier message: 04/08/2008, 18h57
  4. [POO] Héritage et visibilité des attributs : pas de "protected" en JS ?
    Par Hervé Saladin dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 27/11/2007, 16h44
  5. probleme avec des attributs
    Par elghadi_mohamed dans le forum C++
    Réponses: 3
    Dernier message: 22/10/2006, 19h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo