2016-07-11 4 views
0

Ich arbeite an einem mapreduce-Programm mit hadoop.
Ich habe diesen Teil des Codes in meinem Minderer:Zweite Iteration - Werte bleiben gleich

public void reduce(Text key, Iterable<TextLongWritable> values,Context context) throws IOException, InterruptedException { 

    long word1count = 0; 
    List<TextLongWritable> cache = new ArrayList<TextLongWritable>(); 

    String decade = key.toString().split("\t")[0]; 
    String word1 = key.toString().split("\t")[1]; 

    for (TextLongWritable val : values) { 
     if (val.getWord().equals("*")){ 
      word1count += val.getCount(); 
      continue; 
     } 
     cache.add(val); 
     log.info("***Reducer*** Word1: " + word1 + " Word2: " + val.getWord()); 
    } 

    context.write(key, new Text("" + word1count)); 

    for (TextLongWritable value : cache) { 
     if (value.getWord().equals("*")){ 
      continue; 
     } 
     log.info("***Reducer*** Word1: " + word1 + " Word2: " + value.getWord()); 
     context.write(new Text(decade + "\t" + value.getWord()), new Text(word1 + " " + value.getCount() + "\t" + word1count)); 
    } 

} 

Erstens, ich bin mit Caching, wie ich here um sah zweimal auf Werte zu durchlaufen.

Mein Problem ist, dass in der zweiten Schleife alle Werte gleich bleiben. Zum Beispiel, wenn ich eine Liste mit den Wörtern onetwothree habe. Sagen wir, der Schlüssel ist 1900 test, so dass word1 = "test".

Das wird erste Logger ausgegeben:

***Reducer*** Word1: test Word2: one 
***Reducer*** Word1: test Word2: two 
***Reducer*** Word1: test Word2: three 

Aber die zweite Logger ausgegeben wird: aus irgendeinem Grund

***Reducer*** Word1: test Word2: one 
***Reducer*** Word1: test Word2: one 
***Reducer*** Word1: test Word2: one 

Der Wert bleibt gleich.
Was mache ich hier falsch? Hat es etwas mit Hadoop zu tun?

Antwort

0

habe ich es geschafft, dies zu this Seite mit Bezug zu lösen. Ich ging eigentlich zuerst über alle diese Fälle, wo dieser Fall ist das zweite falsche Beispiel auf dieser Seite.

Eine Erklärung darüber, was in managing iterator in mapreduce Post hier geschieht.

Also, was ich tun musste, ist eine tiefe Kopie meines Wertes zu machen, bevor es zu cache hinzufügen.

Zur Vervollständigung hier ist mein Arbeitscode:

public void reduce(Text key, Iterable<TextLongWritable> values,Context context) throws IOException, InterruptedException { 

    long word1count = 0; 
    List<TextLongWritable> cache = new ArrayList<TextLongWritable>(); 

    String decade = key.toString().split("\t")[0]; 
    String word1 = key.toString().split("\t")[1]; 

    for (TextLongWritable val : values) { 
     if (val.getWord().equals("*")){ 
      word1count += val.getCount(); 
      continue; 
     } 
     TextLongWritable val_copy = new TextLongWritable(val.getWord(),val.getCount()); 
     cache.add(val_copy); 
    } 

    context.write(key, new Text("" + word1count)); 

    for (TextLongWritable value : cache) { 
     context.write(new Text(decade + "\t" + value.getWord()), new Text(word1 + " " + value.getCount() + "\t" + word1count)); 
    } 
} 
1

Hadoop speichert dasselbe Objekt bei der Deserialisierung durch GC-Overhead. Sie müssen Ihre TextLongWritable klonen oder tief kopieren, um sie in eine Sammlung zu legen.

Verwandte Themen