Стоимость записи вывода с использованием context.write () ИЛИ outputCollector.collect () в Hadoop?

1

Я только начал изучать Hadoop и все еще экспериментировал и пытался понять вещи, мне действительно интересно узнать об использовании метода collectCollection класса OutputCollector, все примеры, которые я нашел, теперь вызывают этот метод только один раз. Если стоимость вызова этого метода действительно высок (поскольку он записывает вывод в файл)? размышляя о разных сценариях, я попал в ситуацию, когда я нахожу необходимость называть ее более одного раза. подобный мудрый ниже приведенный фрагмент кода

public static class Reduce extends MapReduceBase implements
        Reducer<IntWritable, Text, Text, NullWritable> {
    public void reduce(IntWritable key, Iterator<Text> values,
            OutputCollector<Text, NullWritable> output, Reporter reporter)
            throws IOException {
        Text outData = null;
            while (values.hasNext()) {
                outData = new Text();
                outData.set(values.next().toString());
                output.collect(outData, NullWritable.get());
            }
    }
}

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

public static class Reduce extends MapReduceBase implements
        Reducer<IntWritable, Text, Text, NullWritable> {
    public void reduce(IntWritable key, Iterator<Text> values,
            OutputCollector<Text, NullWritable> output, Reporter reporter)
            throws IOException {
        StringBuilder sb = new StringBuilder();
        while (values.hasNext()) {
            sb.append(values.next().toString() + "\r\n ");
        }
        Text outData = new Text();
        outData.set(sb.toString());
        output.collect(outData, NullWritable.get());
    }
}

Однако оба подхода отлично работают на моей настройке в режиме singlelenode для большого набора входных данных до 400 тыс. Записей и values содержащих около 70 тыс. Записей. Я хочу спросить, какой подход лучше? А также будет ли написанный выше код хорошо вести себя в многоузловом кластере? Любая помощь оценивается. Благодарю.

Теги:
hadoop
mapreduce

1 ответ

2
Лучший ответ

В конце концов, это сводит к минимуму количество данных (с точки зрения размера в байтах), которые вы пишете.

Оба решения имеют некоторые накладные расходы, в первом примере вы пишете несколько строк, у вас есть постоянные накладные расходы на сериализацию длины каждой строки. В другом решении вы пишете столько же накладных расходов, сколько и разделение строк.

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

Очень большая часть вашей проблемы - использование памяти, подумайте о очень большой итерации значений, ваш StringBuilder будет неэффективен из-за операций изменения размера и всей используемой памяти. Метод collect более умный и разливается на диск, если буфер записи заполнен. С другой стороны, если у вас есть много доступной памяти, и вы хотите записать одну огромную запись в одном go-, это также может быть столь же эффективным, как установка буфера записи одинакового размера.

  • 0
    спасибо @Thomas, так что в соответствии с функциональностью метода сбора, это кажется более эффективным в этом сценарии записи данных в Мб или больше. Я правильно понимаю?
  • 1
    Да, но это действительно общий совет, и hadoop позаботится о том, чтобы не пролить небольшой буфер.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню