Подтвердить что ты не робот

Преимущества использования NullWritable в Hadoop

В чем преимущества использования NullWritable для null ключей/значений с использованием текстов null (т.е. new Text(null)). Я вижу следующее из книги "Hadoop: The Definitive Guide".

NullWritable является специальным типом Writable, так как он имеет сериализацию нулевой длины. Нет байтов записываются в поток или считываются с него. Он используется в качестве заполнителя; например, в MapReduce, ключ или значение можно объявить как NullWritable, когда вам не нужно для использования этой позиции - она ​​эффективно сохраняет постоянное пустое значение. NullWritable также может быть полезным в качестве ключа в SequenceFile, если вы хотите сохранить список значений, в противоположность для пар ключ-значение. Это неизменный синглтон: экземпляр можно получить, вызвав NullWritable.get()

Я не понимаю, как выписывается вывод с помощью NullWritable? Будет ли в исходном выходном файле одно постоянное значение, указывающее, что ключи или значения этого файла null, так что среда MapReduce может игнорировать чтение ключей/значений null (в зависимости от того, что null)? Кроме того, как на самом деле тексты null сериализованы?

Спасибо,

Венкат

4b9b3361

Ответ 1

Типы ключей/значений должны указываться во время выполнения, поэтому все записи или чтение NullWritables будут знать заранее, что он будет иметь дело с этим типом; в файле нет маркера или чего-либо еще. И технически NullWritables "читаются", просто "чтение" NullWritable на самом деле не-op. Вы сами можете убедиться, что ничего не написано или прочитано:

NullWritable nw = NullWritable.get();
ByteArrayOutputStream out = new ByteArrayOutputStream();
nw.write(new DataOutputStream(out));
System.out.println(Arrays.toString(out.toByteArray())); // prints "[]"

ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]);
nw.readFields(new DataInputStream(in)); // works just fine

И что касается вашего вопроса о new Text(null), повторите попытку:

Text text = new Text((String)null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
text.write(new DataOutputStream(out)); // throws NullPointerException
System.out.println(Arrays.toString(out.toByteArray()));

Text не будет работать вообще с null String.

Ответ 2

Я изменяю метод запуска. и успех

@Override
public int run(String[] strings) throws Exception {
    Configuration config = HBaseConfiguration.create();  
    //set job name
    Job job = new Job(config, "Import from file ");
    job.setJarByClass(LogRun.class);
    //set map class
    job.setMapperClass(LogMapper.class);

    //set output format and output table name
    //job.setOutputFormatClass(TableOutputFormat.class);
    //job.getConfiguration().set(TableOutputFormat.OUTPUT_TABLE, "crm_data");
    //job.setOutputKeyClass(ImmutableBytesWritable.class);
    //job.setOutputValueClass(Put.class);

    TableMapReduceUtil.initTableReducerJob("crm_data", null, job);
    job.setNumReduceTasks(0);
    TableMapReduceUtil.addDependencyJars(job);

    FileInputFormat.addInputPath(job, new Path(strings[0]));

    int ret = job.waitForCompletion(true) ? 0 : 1;
    return ret;
}

Ответ 3

Вы всегда можете обернуть свою строку в свой собственный класс Writable и иметь логическое значение, указывающее, что она имеет пустые строки или нет:

@Override
public void readFields(DataInput in) throws IOException { 
    ...
    boolean hasWord = in.readBoolean();
    if( hasWord ) {
        word = in.readUTF();
    }
    ...
}

и

@Override
public void write(DataOutput out) throws IOException {
    ...
    boolean hasWord = StringUtils.isNotBlank(word);
    out.writeBoolean(hasWord);
    if(hasWord) {
        out.writeUTF(word);
    }
    ...
}