потоковая передача hadoop: как передать список значений ключей редуктору? - PullRequest
2 голосов
/ 05 октября 2011

, поэтому, когда мы используем Java для написания map/reduce программы, карта собирает данные, а редуктор получает список значений по ключу, например

Map(k, v) -> k1, v1  
    then shuffle and sort happens  
    then reducer gets it  

reduce(k1, List<values>)  

для работы.но возможно ли сделать то же самое с python, используя streaming?Я использовал this в качестве эталона и похоже, что редуктор получает данные на строку, как указано в командной строке

Ответы [ 4 ]

5 голосов
/ 09 января 2012

Может быть, это может вам помочь. Я нашел это от apache ... org

Настройка способа разделения линий на пары ключ / значение Как отмечалось ранее, когда платформа Map / Reduce считывает строку из стандартного вывода преобразователя, она разбивает строку на пару ключ / значение. По умолчанию префикс строки до первого символа табуляции является ключом, а остальная часть строки (исключая символ табуляции) - значением.

Однако вы можете настроить этот параметр по умолчанию. Вы можете указать разделитель полей, отличный от символа табуляции (по умолчанию), и вы можете указать n-й (n> = 1) символ вместо первого символа в строке (по умолчанию) в качестве разделителя между ключом и значением. Например:

$HADOOP_HOME/bin/hadoop  jar $HADOOP_HOME/hadoop-streaming.jar \
    -input myInputDirs \
    -output myOutputDir \
    -mapper org.apache.hadoop.mapred.lib.IdentityMapper \
    -reducer org.apache.hadoop.mapred.lib.IdentityReducer \
    -D stream.map.output.field.separator=. \
    -D stream.num.map.output.key.fields=4 

В приведенном выше примере -D stream.map.output.field.separator=. указывает "." в качестве разделителя полей для выходных данных карты и префикса до четвертого "." в строке будет ключ, а остальная часть строки (исключая четвертое «.») будет значением. Если строка содержит менее четырех символов ".", Тогда ключом будет вся строка, а значением будет пустой текстовый объект (например, созданный новым текстом ("")).

Аналогично, вы можете использовать -D stream.reduce.output.field.separator=SEP и -D stream.num.reduce.output.fields=NUM, чтобы указать n-й разделитель полей в строке выходных сигналов уменьшения в качестве разделителя между ключом и значением.

Аналогично, вы можете указать stream.map.input.field.separator и stream.reduce.input.field.separator в качестве разделителя ввода для отображения / уменьшения входов. По умолчанию разделителем является символ табуляции.

1 голос
/ 06 октября 2011

PipeReducer - это реализация редуктора для потоковой передачи Hadoop. Редуктор получает ключ / значения , повторяет его и отправляет в STDIN как ключ / значение , а не ключ / значения . Это стандартное поведение потоковой передачи Hadoop. Я не вижу никакой возможности изменить это, если только код Hadoop не был изменен.

public void reduce(Object key, Iterator values, OutputCollector output,
                 Reporter reporter) throws IOException {

    .....
    while (values.hasNext()) {
    .....
        inWriter_.writeKey(key);
        inWriter_.writeValue(val);
    .....      
    }
}
1 голос
/ 05 октября 2011

В потоковой передаче Hadoop преобразователь записывает пары ключ-значение в sys.stdout. Hadoop выполняет перемешивание и сортировку и направляет результаты в маппер в sys.stdin. То, как вы на самом деле работаете с картой и уменьшением, зависит только от вас, если вы следуете этой модели (отображение на стандартный вывод, сокращение на стандартный вывод). Вот почему его можно протестировать независимо от Hadoop с помощью cat data | map | sort | reduce в командной строке.

Вход в редуктор - это те же пары ключ-значение, которые были сопоставлены, но отсортированы. Вы можете перебирать результаты и накапливать итоги, как показано в примере, или вы можете взять его дальше и передать ввод в itertools.groupby(), и это даст вам эквивалент ввода k1, List<values>, к которому вы привыкли и который работает хорошо, что reduce() встроенный.

Суть в том, что вы должны реализовать сокращение.

0 голосов
/ 15 апреля 2018

Согласно потоковым ссылкам Hadoop здесь :

  • Ключ по умолчанию является префиксом строки перед первой вкладкой.

когда каркас Map / Reduce считывает строку из стандартного вывода преобразователя, она разбивает строку на пару ключ / значение. По умолчанию префикс строки до первого символа табуляции является ключом, а остальная часть строки (исключая символ табуляции) - значением.

  • Разделители и положения клавиш можно настраивать.

Однако вы можете настроить этот параметр по умолчанию. Вы можете указать разделитель полей, отличный от символа табуляции (по умолчанию), и вы можете указать n-й (n> = 1) символ вместо первого символа в строке (по умолчанию) в качестве разделителя между ключом и значением. Например:

  • Пример кода:

    $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \ -D stream.map.output.field.separator=. \ -D stream.num.map.output.key.fields=4 \ -input myInputDirs \ -output myOutputDir \ -mapper org.apache.hadoop.mapred.lib.IdentityMapper \ -reducer org.apache.hadoop.mapred.lib.IdentityReducer

...