2013-03-31 7 views
8

mio mapper deve inviare i seguenti tuple:Come Java Hadoop Mapper può inviare più valori

<custID,prodID,rate> 

E voglio inviare al riduttore la custID come una chiave, e come valore prodID e tasso di insieme, come sono necessari per la fase di riduzione. Qual è il modo migliore per farlo?

public void map(Object key, Text value, Context context) 
     throws IOException, InterruptedException { 

    String[] col = value.toString().split(","); 
    custID.set(col[0]); 
    data.set(col[1] + "," + col[2]); 
    context.write(custID, data); 
} 

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

    for (Text val : values) { 
     String[] temp = val.toString().split(","); 
     Text rate = new Text(temp[1]); 
     result.set(rate); 
     context.write(key, result); 
    } 
} 
+0

Perché non è possibile inviare più valori? Niente limita il numero di coppie chiave-valore che può produrre una singola attività mappa. – kichik

risposta

3

Il più semplice che posso pensare è solo per unirli in una singola stringa:

output.collect(custID, prodID + "," + rate); 

Poi, divisi se il backup sui riduttori.

Se pubblichi un po 'più codice dal tuo mapper forse potremmo dare un esempio migliore.

AGGIORNAMENTO: Detto questo, hai chiesto il migliore modo. Il modo più corretto è probabilmente creare insieme un raggruppamento di classi prodID e rate insieme e inviarlo.

+0

Ho provato questa soluzione (per unirle), ma quando in riduttore utilizzo String v = val.toString(). Split (","); comando per dividere la stringa, posso usare regolarmente la v [0], ma quando uso v [1] valore ottengo un'eccezione "array fuori limite". –

+0

Puoi pubblicare del codice (nella tua domanda originale o un gin pastebin/github) per quello che hai attualmente? –

+0

Ho aggiunto del codice, grazie. –

11

Il modo migliore è scrivere CustomWritables

Questo è per valore doppio. È possibile cambiare la situazione di testo o stringa

import java.io.DataInput; 
import java.io.DataOutput; 
import java.io.IOException; 
import org.apache.hadoop.io.Writable; 


/** 
* @author Unmesha SreeVeni U.B 
* 
*/ 
public class TwovalueWritable implements Writable { 
    private double first; 
    private double second; 

    public TwovalueWritable() { 
     set(first, second); 
    } 
    public TwovalueWritable(double first, double second) { 
     set(first, second); 
    } 
    public void set(double first, double second) { 
     this.first = first; 
     this.second = second; 
    } 
    public double getFirst() { 
     return first; 
    } 
    public double getSecond() { 
     return second; 
    } 
    @Override 
    public void write(DataOutput out) throws IOException { 
     out.writeDouble(first); 
     out.writeDouble(second); 
    } 
    @Override 
    public void readFields(DataInput in) throws IOException { 
     first = in.readDouble(); 
     second = in.readDouble(); 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#hashCode() 
    */ 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     long temp; 
     temp = Double.doubleToLongBits(first); 
     result = prime * result + (int) (temp^(temp >>> 32)); 
     temp = Double.doubleToLongBits(second); 
     result = prime * result + (int) (temp^(temp >>> 32)); 
     return result; 
    } 
    /* (non-Javadoc) 
    * @see java.lang.Object#equals(java.lang.Object) 
    */ 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (!(obj instanceof TwovalueWritable)) { 
      return false; 
     } 
     TwovalueWritable other = (TwovalueWritable) obj; 
     if (Double.doubleToLongBits(first) != Double 
       .doubleToLongBits(other.first)) { 
      return false; 
     } 
     if (Double.doubleToLongBits(second) != Double 
       .doubleToLongBits(other.second)) { 
      return false; 
     } 
     return true; 
    } 
    @Override 
    public String toString() { 
     return first + "," + second; 
    } 
} 

E da mapper si può solo emettere come

context.write(key,new TwovalueWritable(prodID,rate)); 

Spero che questo aiuti.

+0

le sue buone soluzioni, ma ho bloccato con la stringa come sovrascrivere il metodo equals ... –

+0

@RaviHTapela: Se si utilizza Eclipse IDE - uguale, hashCode può essere generato automaticamente –