могу ли я использовать текст в качестве значения для записи в контекст в mapreduce

#hadoop #mapreduce #hadoop2

#hadoop #mapreduce #hadoop2

Вопрос:

У меня есть сценарий для вычисления среднего значения двух столбцов в map reduce. Итак, что я сделал, я получил значения из файла с помощью mapper и объединил их в текст, а затем попытался записать их в контекст, как показано ниже.

 class TestMapper extends Mapper<LongWritable, Text, Text, Text> {
  private Text outputKey;
  private Text outputVal;


  @Override
  public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  
  //more code here

context.write(outputkey,OutputVal);


    
  }
} 

Комментарии:

1. Да, вы можете использовать текст в качестве значения, фактически вы можете использовать любой другой тип данных, поддерживаемый платформой Hadoop. У вас есть какие-либо проблемы? если да, поделитесь своим кодом и трассировкой стека исключения.

2. Спасибо за беспокойство, Азим. Я добился этого, изменив типы данных в объекте задания.

3. Было бы лучше, если бы вы могли прочитать Hadoop от Oreilly’s: The Definitive Guide book. Это потрясающе. Отлично, ваша проблема решена 🙂

Ответ №1:

Здесь вы должны использовать пользовательский тип данных, например, класс TextPair, который имеет два текстовых элемента для хранения необходимых вам данных. Ниже приведен пример кода, который используется для вывода пары строк в значении контекста mapper.

 // Mapper's map code
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, TextPair>.Context context)
        throws IOException, InterruptedException {

    String line = value.toString();
    String year = line.substring(15, 19);
    int airTemperature;
    if (line.charAt(87) == ' ') { // parseInt doesn't like leading plus signs
      airTemperature = Integer.parseInt(line.substring(88, 92));
    } else {
      airTemperature = Integer.parseInt(line.substring(87, 92));
    }
    String quality = line.substring(92, 93);
    if (airTemperature != MISSING amp;amp; quality.matches("[01459]")) {
        System.out.println("Year " year " " airTemperature);
      context.write(new Text(year), new TextPair(String.valueOf(airTemperature),1));
    }
 

// Text Pair — пользовательский код типа данных ниже

 public class TextPair implements WritableComparable<TextPair> {

private Text first;
private Text second;

//Default constructor is a must
public TextPair() {
    this.first=new Text();
    this.second=new Text();
}

public TextPair(String first,int second) {
    try {
        this.first=new Text(first);
        this.second=new Text(String.valueOf(second));
    }catch(Exception ex) {
        System.out.println("Exception occurred " ex.getCause());
    }

}

// Other methods such as compare, equals, hashcode, write, readFields etc implementation also needs to done

public Text getFirst() {
    return first;
}

public Text getSecond() {
    return second;
}

@Override
public String toString() {
    return this.first "t" this.second "t";
}

}
 

Если вам нужна еще более подробная информация, обратитесь к Окончательному руководству Hadoop. Надеюсь, это поможет.

Комментарии:

1. Привет @Pushkin, я следовал указанной вами логике. Но я получаю ошибку того же типа. Я сослался на окончательный путеводитель. Но у меня это не работает.

2. Я получаю такую ошибку. Ошибка: java.io.IOException: несоответствие типа значению с карты: ожидаемый org.apache.hadoop.io.FloatWritable, получена текстовая пара

3. Я видел, как это происходило, когда в коде задания (где вы настраиваете mapper и reducer) тип вывода был указан иначе, чем тот, который фактически выводится из mapper. Также было бы полезно, если бы вы могли поделиться своим полным кодом для Job, Mapper и Reducer.

4. Это сработало отлично. И нам не нужно использовать TextPair в моем случае. Это можно сделать с самим текстом. Большое спасибо за вашу помощь.