Hadoop поиска слов из одного файла в другом файле - PullRequest
2 голосов
/ 24 января 2010

Я хочу создать приложение hadoop, которое может читать слова из одного файла и искать в другом файле.

Если слово существует - оно должно записать в один выходной файл Если слово не существует - оно должно записать в другой выходной файл

Я попробовал несколько примеров в hadoop. У меня два вопроса

Два файла по 200 МБ каждый. Проверка каждого слова в другом файле может привести к нехватке памяти. Есть ли альтернативный способ сделать это?

Как записать данные в разные файлы, поскольку вывод фазы сокращения hadoop записывает только в один файл. Можно ли использовать фильтр для уменьшения фазы для записи данных в разные выходные файлы?

Спасибо.

Ответы [ 3 ]

8 голосов
/ 25 января 2010

Как бы я это сделал:

  1. разделить значение в 'map' по словам, emit (,
  2. вы попадете в 'Reduce': (, <список источников>)
  3. проверить список источников (может быть длинным для обоих / всех источников)
  4. если НЕ все источники в списке, генерировать каждый раз (, )
  5. job2: job.setNumReduceTasks ()
  6. job2: выброс в 'map' (, )
  7. job2: испускать для каждого в «уменьшить» все (ноль, )

В итоге вы получите столько же сокращений, сколько и разных , каждый из которых содержит пропущенные слова для документа. Вы можете выписать ONCE в начале слова «Reduce», чтобы пометить файлы.

(* 1) Как узнать источник на карте (0,20):

private String localname;
private Text outkey = new Text();   
private Text outvalue = new Text();
...
public void setup(Context context) throws InterruptedException, IOException {
    super.setup(context);

    localname = ((FileSplit)context.getInputSplit()).getPath().toString();
}

public void map(Object key, Text value, Context context)
    throws IOException, InterruptedException {
...
    outkey.set(...);
    outvalue.set(localname);
    context.write(outkey, outvalue);
}
1 голос
/ 25 января 2010

Используете ли вы Hadoop / MapReduce по определенной причине для решения этой проблемы? Это звучит как нечто более подходящее для приложений Lucene , чем Hadoop.

Если вам нужно использовать Hadoop, у меня есть несколько предложений:

  1. Ваши «документы» должны быть в формате, с которым MapReduce может работать. Самый простой формат для использования - это файл на основе CSV с каждым словом в документе в строке. Наличие PDF и т. Д. Не сработает.

  2. Чтобы принять набор слов в качестве входных данных для задания MapReduce для сравнения с данными, которые обрабатывает MapReduce, вы можете использовать Distributed Cache , чтобы каждый картограф мог создать набор слов хочу найти на входе. Однако, если ваш список слов, чтобы найти его большим (вы упоминаете 200 МБ), я сомневаюсь, что это будет работать Однако этот метод является одним из основных способов объединения в MapReduce.

Метод индексации, упомянутый в другом ответе здесь, также предлагает возможности. Опять же, термины, индексирующие документ, заставляют меня думать о Lucene, а не о hadoop. Если вы использовали этот метод, вам необходимо убедиться, что значение ключа содержит идентификатор документа, а также слово, чтобы в каждом документе содержалось количество слов.

Я не думаю, что когда-либо создавал несколько выходных файлов из задания MapReduce. Вам нужно было бы написать некоторый (и это было бы очень просто) код для обработки индексированного вывода в несколько файлов.

0 голосов
/ 24 января 2010

На мой взгляд, вы захотите сделать это в два этапа. Запустите программу wordcount (входит в jar примеров hadoop) для двух исходных документов, и вы получите два файла, каждый из которых содержит уникальный список (с количеством) слов в каждом документе. Оттуда, вместо использования hadoop, сделайте простой diff для двух файлов, который должен ответить на ваш вопрос,

...