Сериализация с использованием ArrayWritable, кажется, работает забавно - PullRequest
5 голосов
/ 27 октября 2011

Я работал с ArrayWritable, в какой-то момент мне нужно было проверить, как Hadoop сериализует ArrayWritable, это то, что я получил, установив job.setNumReduceTasks(0):

0    IntArrayWritable@10f11b8
3    IntArrayWritable@544ec1
6    IntArrayWritable@fe748f
8    IntArrayWritable@1968e23
11    IntArrayWritable@14da8f4
14    IntArrayWritable@18f6235

и это тестовый картограф, который я использовал:

public static class MyMapper extends Mapper<LongWritable, Text, LongWritable, IntArrayWritable> {

    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        int red = Integer.parseInt(value.toString());
        IntWritable[] a = new IntWritable[100];

        for (int i =0;i<a.length;i++){
            a[i] = new IntWritable(red+i);
        }

        IntArrayWritable aw = new IntArrayWritable();
        aw.set(a);
        context.write(key, aw);
    }
}

IntArrayWritable взято из примера, приведенного в javadoc: ArrayWritable .

import org.apache.hadoop.io.ArrayWritable;
import org.apache.hadoop.io.IntWritable;

public class IntArrayWritable extends ArrayWritable {
    public IntArrayWritable() {
        super(IntWritable.class);
    }
}

Я действительно проверил исходный код Hadoop, и для меня это не имеет смысла. ArrayWritable не должен сериализовать имя класса, и массив 100 IntWritable не может быть сериализован с использованием шестнадцатеричных значений 6/7. На самом деле приложение работает нормально, а редуктор десериализует правильные значения ... Что происходит? Чего мне не хватает?

Ответы [ 4 ]

6 голосов
/ 15 марта 2012

Вы должны переопределить метод toString() по умолчанию.

Он вызывается TextOutputFormat для создания удобочитаемого формата.

Попробуйте следующий код и посмотрите результат:

public class IntArrayWritable extends ArrayWritable {
    public IntArrayWritable() {
        super(IntWritable.class);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (String s : super.toStrings())
        {
            sb.append(s).append(" ");
        }
        return sb.toString();
    }
}
4 голосов
/ 27 октября 2011

Проблема в том, что вывод, который вы получаете из задания MapReduce, не является сериализованной версией этих данных.Это что-то, что переводится в симпатичную печатную строку.

Когда вы устанавливаете число редукторов на ноль, ваши преобразователи теперь проходят через выходной формат, который отформатирует ваши данные, вероятно, преобразовав их в читабельный.строка. Он не выводит его серийно, как если бы его собирал редуктор.

3 голосов
/ 25 января 2012

Вы смотрели в SequenceFileInputFormat и SequenceFileOutputFormat? Вы можете настроить их с помощью:

job.setInputFormatClass(SequenceFileInputFormat.class); 

и

job.setOutputFormatClass(TextOutputFormat.class);
0 голосов
/ 12 ноября 2014

Это очень просто. Hadoop использует метод write (DataOutput out) для записи объекта в сериализованную версию (для получения дополнительной информации см. Документ документации hadoop ArrayWritable). Когда вы расширяете ArrayWritable с помощью IntArrayWritable, ваш собственный класс будет использовать эти методы из унаследованного класса. Bye.

...