У меня огромное количество входных данных (именно поэтому я использую Hadoop), и есть несколько задач, которые можно решить с помощью различных шагов MapReduce, для которых первый маппер требует все данные в качестве ввода.
Моя цель: вычислить эти различные задачи как можно быстрее.
В настоящее время я позволяю им запускать последовательно каждое чтение во всех данных. Я предполагаю, что это будет быстрее, если объединить задачи и выполнить их похожие части (например, передать все данные в маппер) только один раз.
Мне было интересно, если и как я могу объединить эти задачи. Для каждой пары ключ / значение ввода преобразователь может выдавать «супер-ключ», который включает в себя идентификатор задачи и данные ключа конкретной задачи вместе со значением. Таким образом, редукторы получат пары ключ / значение для задачи и ключ, специфичный для задачи, и смогут при просмотре «суперключа» решить, какую задачу выполнить для включенного ключа и значений.
В псевдокоде:
map(key, value):
emit(SuperKey("Task 1", IncludedKey), value)
emit(SuperKey("Task 2", AnotherIncludedKey), value)
reduce(key, values):
if key.taskid == "Task 1":
for value in values:
// do stuff with key.includedkey and value
else:
// do something else
Ключом может быть WritableComparable
, который может содержать всю необходимую информацию.
Примечание: псевдокод предполагает ужасную архитектуру, и это определенно можно сделать более умным способом.
Мои вопросы:
- Разумный ли это подход?
- Есть ли лучшие альтернативы?
- Есть ли у него какой-то ужасный недостаток?
- Нужен ли класс
Partitioner
для этого подхода?
Контекст : Данные состоят из нескольких миллионов четвертей RDF, и задачи состоят в том, чтобы рассчитать кластеры, статистику и сходства. Некоторые задачи могут быть легко решены с помощью счетчиков Hadoop в редукторе, но некоторые требуют нескольких шагов MapReduce.
Вычисления в конечном итоге будут выполняться на Amazon Elastic MapReduce. Все задачи должны быть рассчитаны для всего набора данных и как можно быстрее.