Перекрестный продукт на карте Уменьшите использование потоковой передачи Hadoop и Python

Я изучаю Python и Hadoop. Я завершил установку и основные примеры, представленные на официальном сайте, используя потоки pythong + hadoop. Я рассмотрел возможность внедрения двух файлов. Я завершил equi-join, который проверяет, появляется ли тот же самый ключ в обоих входных файлах, затем выводит ключ вместе со значениями из файла 1 и файла 2 в этом порядке. Соединение равенства работает так, как предполагается.

Теперь я хочу сделать соединение неравенства, которое предполагает поиск Cross Product перед применением условия неравенства. Я использую тот же mapper (мне нужно его изменить), и я изменил редуктор так, чтобы он содержал вложенный цикл (так как каждая пара значений ключа в файле1 должна быть сопоставлена ​​со всеми парами значений ключа в файле2). Это не работает, так как вы можете проходить через поток только один раз. Теперь я подумал о возможности хранения "некоторых" значений в редукторе и их сравнении, но я понятия не имею, "как" многие. Наивный метод заключается в том, чтобы хранить весь контент file2 в массиве (или подобной структуре), но это глупо и противоречит идее распределенной обработки. Наконец, мои вопросы:

  • Как сохранить значения в редукторе, чтобы у меня было перекрестное произведение между двумя файлами?

  • В equi-join Hadoop, кажется, посылает все ключевые пары значений с одним и тем же ключом на тот же редуктор, который отлично работает и хорошо работает для этого случая. Однако как я могу изменить это поведение (если необходимо), так что требуемая группировка пар ключ-значение будет правильным редуктором?

Примеры файлов:   http://pastebin.com/ufYydiPu

Python Map/Reduce Scripts:   http://pastebin.com/kEJwd2u1

Команда Hadoop Я использую:

bin/hadoop jar contrib/streaming/hadoop-*streaming*.jar -file /home/hduser/mapper.py -mapper mapper.py -file /home/hduser/ireducer.py -reducer reducer.py -input /user/hduser/inputfiles/* -output /user/hduser/join-output

Любая помощь/подсказка очень ценится.

Ответ 1

Один из способов борьбы с несколькими комбинациями, которые могут быть очень полезны для предотвращения вложенных циклов, заключается в использовании модуля itertools. В частности, функция itertools.product, которая заботится о декартовом продукте с использованием генераторов. Это полезно для использования памяти, эффективности и может значительно упростить ваш код, если вам нужно объединить несколько наборов данных на одной карте, уменьшающей работу.

Что касается соответствия между данными, полученными картографом, и наборами данных, которые должны быть объединены в редукторе, если набор данных для каждого ключа не слишком велик, вы можете просто получить из mapper комбинацию, например:

{key, [origin_1, values]}
{key, [origin_2, values]}

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