Python MapReduce Hadoop потоковое задание, которое требует нескольких входных файлов?
у меня есть два файла в моем кластере File A
и File B
со следующими данными -
Файл A
#Format:
#Food Item | Is_A_Fruit (BOOL)
Orange | Yes
Pineapple | Yes
Cucumber | No
Carrot | No
Mango | Yes
Файл B
#Format:
#Food Item | Vendor Name
Orange | Vendor A
Pineapple | Vendor B
Cucumber | Vendor B
Carrot | Vendor B
Mango | Vendor A
в основном я хочу узнать сколько фруктов продает каждый поставщик?
ожидаемый результат:
Vendor A | 2
Vendor B | 1
мне нужно сделать это с помощью Hadoop streaming python map reduce.
Я прочитал, как сделать основной подсчет слов, я читаю из sys.stdin
и испускают k,v
пар для редуктор, чтобы затем уменьшить.
как мне подойти к этой проблеме?
моя главная забота-как читать из нескольких файлов, а затем сравнивать их в потоковой передаче Hadoop.
Я могу сделать это в обычном python (i.e без MapReduce & Hadoop это просто.) но это невозможно из-за огромного объема данных, которые у меня есть.
4 ответов
пожалуйста, взгляните на этой пример, поскольку он относится в значительной степени непосредственно к тому, что вы ищете.
действительно ли файл A такой большой? Я бы положил его в DistributedCache и прочитал оттуда. Чтобы поместить его в распределенный кэш, используйте эту опцию в потоковом вызове Hadoop:
-cacheFile 'hdfs://namenode:port/the/hdfs/path/to/FileA#FileA'
(Я полагаю, что следующее тоже должно работать, но я не пробовал:)
-cacheFile '/the/hdfs/path/to/FileA#FileA'
отметим, что #fileA
- это имя, которое вы используете, чтобы сделать файл доступным для ваших картографов.
затем, в вашем картографе, вы будете читать FileB из sys.stdin
(asuming вы назвали Hadoop Потоковая передача с использованием -input '/user/foo/FileB'
) и, чтобы прочитать FileA, вы должны сделать что-то вроде этого:
f = open('FileA', 'r')
...
f.readline()
один подход состоит в том, чтобы сделать это на двух работах.
- фильтр FileB, так что сохраняются только строки, содержащие фрукты
- Map1: составной ключ "продовольственного товара" и из какого файла пришли данные. Раздел на "продукт питания", с вторичной сортировкой, содержит ли строка информацию" Is_A_Fruit " (чтобы убедиться, что это сначала читается редуктором для каждого элемента питания).
- Reduce1: при вторичной сортировке первая строка в отсортированных данных будет указывать является ли этот пищевой продукт плодом (в этом случае редуктор выведет его) или нет (в этом случае он не будет).
- используйте поставщика в качестве ключа для подсчета количества фруктов на поставщика.
- вывод MapReduce из первого задания теперь имеет ту же структуру, что и FileB, но все строки являются плодами, поэтому это больше похоже на wordcount, с именем поставщика в качестве ключа, а затем подсчитайте количество строк.
- Если вы хотите уникальные фрукты, вам может потребоваться использовать вторичная сортировка снова, чтобы устранить необходимость загрузки всех фруктов, связанных с каждым поставщиком в память.
Это говорит: решение @cabad предлагает лучше всего, если файл достаточно мал.
Если нет, подход со вторичными сортами лучше всего. Взгляните на в этом уроке предложено в ответе @Simplefish здесь для того, как делать вторичные сортировки в разделе (которые являются ключевыми словами, которые укажут вам на правильном направлении, чтобы сделать то, что вы хотите: сделать гарантии о порядке данных, связанных с данным ключом, который передается на редуктор).
последнее примечание: ваша проблема не "как читать из нескольких файлов", поскольку любое решение, которое вы разрабатываете, не может полагаться на знание того, из какого файла поступает вход (вам нужно будет полагаться на структуру данных, хотя это не проблема в этом примере).
вы предоставите только каталог, содержащий файлы, в hadoop. Hadoop framework будет читать их. Вы не.
Hadoop применит класс карты, который вы кодируете ко всему содержимому файлов.
тогда hadoop будет применяться уменьшить класс закодированный вами для всех выходных от класса карты.