2015-01-08 8 views
1

Mapper에서 일부 데이터를 보내고 Reducer에서 읽으려고하면 약간 변경되었습니다. 이력서에서, 나는 set 함수를 사용하여 데이터를 채운 다음 get 함수를 사용하여 감속기에서 읽습니다. 나는 왜 println을하면 데이터가 다른지 이해할 수 없다.Mapper에서 보낸 텍스트/문자열 값이 Reducer에서 읽을 때 잘못되었습니다.

나는 "ValorFechaHora"라는 클래스, 3 개 변수 Medicion, Fecha 및 호라에 전송하고 데이터 :

public class ValorFechaHora implements Writable { 
 

 
\t private IntWritable Medicion; 
 
\t private Text Fecha; 
 
\t private Text Hora; 
 
\t 
 
\t public void ValorFechaHora(){ 
 
\t \t 
 
\t } 
 
\t 
 
\t public void ValorFechaHora(IntWritable Medicion, Text Fecha, Text Hora){ 
 
\t \t setMedicion(Medicion); 
 
\t \t setFecha(Fecha); 
 
\t \t setHora(Hora); 
 
\t } 
 
\t 
 
\t public IntWritable getMedicion() { 
 
\t \t return Medicion; 
 
\t } 
 

 
\t public void setMedicion(IntWritable medicion) { 
 
\t \t Medicion = medicion; 
 
\t } 
 

 
\t public Text getFecha() { 
 
\t \t return Fecha; 
 
\t } 
 

 
\t public void setFecha(Text fecha) { 
 
\t \t Fecha = fecha; 
 
\t } 
 

 
\t public Text getHora() { 
 
\t \t return Hora; 
 
\t } 
 

 
\t public void setHora(Text hora) { 
 
\t \t Hora = hora; 
 
\t } 
 

 
\t @Override 
 
\t public int hashCode() { 
 
\t \t final int prime = 31; 
 
\t \t int result = 1; 
 
\t \t result = prime * result + ((Fecha == null) ? 0 : Fecha.hashCode()); 
 
\t \t result = prime * result + ((Hora == null) ? 0 : Hora.hashCode()); 
 
\t \t result = prime * result 
 
\t \t \t \t + ((Medicion == null) ? 0 : Medicion.hashCode()); 
 
\t \t return result; 
 
\t } 
 

 
\t @Override 
 
\t public boolean equals(Object obj) { 
 
\t \t if (this == obj) 
 
\t \t \t return true; 
 
\t \t if (obj == null) 
 
\t \t \t return false; 
 
\t \t if (getClass() != obj.getClass()) 
 
\t \t \t return false; 
 
\t \t ValorFechaHora other = (ValorFechaHora) obj; 
 
\t \t if (Fecha == null) { 
 
\t \t \t if (other.Fecha != null) 
 
\t \t \t \t return false; 
 
\t \t } else if (!Fecha.equals(other.Fecha)) 
 
\t \t \t return false; 
 
\t \t if (Hora == null) { 
 
\t \t \t if (other.Hora != null) 
 
\t \t \t \t return false; 
 
\t \t } else if (!Hora.equals(other.Hora)) 
 
\t \t \t return false; 
 
\t \t if (Medicion == null) { 
 
\t \t \t if (other.Medicion != null) 
 
\t \t \t \t return false; 
 
\t \t } else if (!Medicion.equals(other.Medicion)) 
 
\t \t \t return false; 
 
\t \t return true; 
 
\t } 
 

 
\t public void readFields(DataInput in) throws IOException { 
 
\t \t 
 
\t \t Medicion = new IntWritable(in.readInt()); 
 
\t \t Fecha = new Text(in.readLine()); 
 
\t \t Hora = new Text(in.readLine()); 
 
\t } 
 
\t 
 
\t public void write(DataOutput out) throws IOException { 
 
\t \t Medicion.write(out); 
 
\t \t Fecha.write(out); 
 
\t \t Hora.write(out); 
 
\t } \t 
 

 
}
다음

내 매퍼 볼 수 있습니다

public static class LogsMapper extends 
 
\t \t \t Mapper<LongWritable, Text, Text, ValorFechaHora> { 
 

 
\t \t //En el mapper emitimos lo que leemos. Key = Dirección MAC. Value = Medición + Fecha + Hora 
 
\t \t 
 
\t \t private Text outKey = new Text(); 
 
\t \t private ValorFechaHora outValue = new ValorFechaHora(); 
 
\t \t 
 
\t \t @Override 
 
\t \t protected void map(LongWritable offset, Text line, Context context) 
 
\t \t \t \t throws IOException, InterruptedException { 
 
\t \t \t 
 
\t \t \t 
 
\t \t \t // Utilizamos row_auxiliar y row para leer los datos correctos (El offset no nos interesa) 
 
\t \t \t // Ejemplo de dato de entrada tras salir del filtrado básico "2536816 \t -47dB;8C:3A:E3:92:CB:3E;2014-11-12;14:22:20.795806" 
 
\t \t \t 
 
\t \t \t String row_auxiliar[] = line.toString().split("\t"); 
 
\t \t \t String row[] = row_auxiliar[1].split(";"); 
 
\t \t \t 
 
\t \t \t // Los datos en row quedan... ---> row[0]= Medicion row[1]= MAC row[2]= Fecha row[3]= Hora 
 
\t 
 
\t \t \t //Elegimos la MAC como key 
 
\t \t \t outKey = new Text(row[1]); 
 
\t \t \t 
 
\t \t \t //Elegimos la Medicion, Fecha y Hora como value 
 
\t \t \t outValue.setMedicion(new IntWritable(Integer.valueOf(row[0].substring(0,3)))); 
 
\t \t \t outValue.setFecha(new Text(row[2])); 
 
\t \t \t outValue.setHora(new Text(row[3])); 
 
\t \t \t 
 
\t \t \t context.write(outKey, outValue); 
 
\t \t \t \t 
 
\t \t };

. 나는 bucle 를하고있는 중이 야 때 변수 val.getFecha의 toString()()를 감속기에하는 이유

public static class MaxReducer extends 
 
\t \t \t Reducer<Text, ValorFechaHora, Text, Text> { 
 
\t \t 
 
\t \t //En el reduce por ahora únicamente contamos el número de veces que ha sido la MAC registrada 
 
\t \t 
 
\t \t protected void reduce(Text MAC, 
 
\t \t \t \t Iterable<ValorFechaHora> values, Context context) 
 
\t \t \t \t throws IOException, InterruptedException { 
 

 
\t \t \t Text outKey = new Text(); 
 
\t \t \t Text outValue = new Text(); 
 
\t \t \t 
 
\t \t \t outKey = MAC; 
 
\t \t \t int sum = 0; 
 
\t \t \t 
 
\t \t \t for(ValorFechaHora val : values){ 
 
\t \t \t \t System.out.println("1" + " " + val.getMedicion().toString()); 
 
\t \t \t \t System.out.println("2" + " " + val.getFecha().toString()); 
 
\t \t \t \t System.out.println("3" + " " + val.getHora().toString()); 
 
\t \t \t \t 
 
\t \t \t \t sum = sum +1; 
 
\t \t \t } 
 
\t \t \t 
 
\t \t \t outValue = new Text(Integer.toString(sum)); 
 
\t \t \t 
 
\t \t \t context.write(outKey, outValue); 
 
\t \t };

글쎄, 난 이해가 안 : 여기

(210) 내 감속기입니다 변수 outKey.getFecha(). toString 매퍼에서

TYA이

답변

1

클래스 "ValorFechaHora"이러한 코드 라인을 변경하여 문제를 해결했다. Text 객체의 readFields 메서드를 사용해야합니다.

현재 String을 인수로 허용하는 생성자를 통해 Text 객체를 채우려고합니다. 텍스트 객체가 개행 줄 바꿈없이 데이터 스트림에 직렬화 될 때 in.readLine을 사용하여 DataInput 객체에서 String을 다시 읽을 수는 없습니다.

이 문제를 해결하려면 변수를 초기화 한 다음 readFields 메서드 만 사용해야합니다 (현재 개체 재사용 패턴을 사용하고 있지 않으므로 코드에 다른 노크 효과가있을 수 있음) 다음과 같이 바로 readFields의 방법을 업데이트 그대로 그렇지 않으면 코드를 유지하기 위해 (하지만 비효율적)

private IntWritable Medicion = new IntWritable(); 
private Text Fecha = new Text(); 
private Text Hora = new Text(); 

public void readFields(DataInput in) { 
    Medicion.readFields(in); 
    Fecha.readFields(in); 
    Hora.readFields(in); 
} 

: (어떤 새로운 각 K/V 개체에 대한 개체를 만드는 것보다 더 효율적입니다)

public void readFields(DataInput in) { 
    Medicion = new Text(); 
    Medicion.readFields(in); 

    Fecha = new Text(); 
    Fecha.readFields(in); 

    Hora = new Text(); 
    Hora.readFields(in); 
} 
+0

정말 고마워 크리스! 왜 내가 왜하고 있었는지 설명 해줘서 고마워. 스테이크;) =) – MagicTaly

1

내가 왜 내가 잘 이해하지 못하는 다른 (S)는 발생하지만 난 당신이 잘못된 방법은 텍스트 객체를 채우기 위해 호출을 사용하고

\t public void readFields(DataInput in) throws IOException { 
 
\t \t 
 
\t \t Medicion = new IntWritable(in.readInt()); 
 
\t \t //Fecha = new Text(in.readLine()); 
 
\t \t //Hora = new Text(in.readLine()); 
 

 
     //Those two lines for these ones: 
 

 
     Fecha = new Text(Text.readString(in)); 
 
\t \t Hora = new Text(Text.readString(in));

TYU