Подтвердить что ты не робот

Должен ли я изучать/использовать MapReduce или какой-либо другой тип распараллеливания для этой задачи?

После разговора с моим другом из Google я хотел бы реализовать какую-то модель Job/Worker для обновления моего набора данных.

Этот набор данных отражает данные сторонних служб, поэтому для выполнения обновления мне нужно сделать несколько удаленных вызовов в их API. Я думаю, что много времени будет потрачено на ожидание ответов от этого стороннего сервиса. Я хотел бы ускорить работу и лучше использовать свои вычислительные часы, распараллеливая эти запросы и удерживая многие из них открытыми сразу, так как они ждут своих индивидуальных ответов.

Прежде чем я объясню свой конкретный набор данных и попаду в проблему, я хотел бы уточнить, какие ответы я ищу:

  • Это поток, который хорошо подходит для распараллеливания с MapReduce?
  • Если да, будет ли это экономически выгодно работать на модуле MapAddirect Amazon, который оплачивается по часам и в течение часа после завершения задания? (Я не уверен точно, что считается "Job", поэтому я точно не знаю, как мне будет выставлен счет)
  • Если нет, есть ли другая система/шаблон, который я должен использовать? и Есть ли библиотека, которая поможет мне сделать это в python (на AWS, usign EC2 + EBS)?
  • Есть ли проблемы, которые вы видите, с тем, как я разработал этот поток работы?

Хорошо, теперь на детали:

Набор данных состоит из пользователей, у которых есть любимые предметы и которые следуют за другими пользователями. Цель состоит в том, чтобы иметь возможность обновлять каждую пользовательскую очередь - список элементов, которые пользователь увидит при загрузке страницы, на основе избранных элементов пользователей, которых она следует. Но, прежде чем я смогу переломить данные и обновить очередь пользователей, мне нужно убедиться, что у меня есть самые современные данные, в которые входят вызовы API.

Есть два вызова, которые я могу сделать:

  • Получить следующих пользователей - что возвращает всех пользователей, за которыми следует запрашиваемый пользователь, и
  • Получить избранные элементы - возвращает все любимые элементы запрашиваемого пользователя.

После того, как я позвоню, следуйте за пользователями для обновляемого пользователя, мне нужно обновить любимые элементы для каждого пользователя. Только после того, как все избранные будут возвращены для всех пользователей, которых следует следовать, я могу начать обработку очереди для этого оригинального пользователя. Этот поток выглядит следующим образом:

Updating UserX's Queue

Работа в этом потоке включает:

  • Начать обновление очереди для пользователя - начать процесс, извлекая пользователей, за которыми следует обновляемый пользователь, сохраняя их, а затем создавая задания "Избранное" для каждого пользователя.
  • Получить Избранное для пользователя - запрашивает и сохраняет список избранных для указанного пользователя из сторонней службы.
  • Вычислить новую очередь для пользователя - обрабатывает новую очередь, теперь, когда все данные были извлечены, а затем сохраняет результаты в кеше, который используется прикладным уровнем.

Итак, опять мои вопросы:

  • Это поток, который хорошо подходит для распараллеливания с MapReduce? Я не знаю, разрешит ли я запустить процесс для UserX, получить все связанные данные и вернуться к обработке очереди UserX только после этого.
  • Если да, будет ли это экономически выгодно работать на модуле MapAddirect Amazon, который оплачивается по часам и в течение часа после завершения задания? Есть ли ограничение на количество "потоков", которые я могу ожидать от открытых запросов API, если я использую их модуль?
  • Если нет, есть ли другая система/шаблон, который я должен использовать? и Есть ли библиотека, которая поможет мне сделать это в python (на AWS, usign EC2 + EBS?)?
  • Есть ли проблемы, которые вы видите, с тем, как я разработал этот поток работы?

Спасибо за чтение, я с нетерпением жду обсуждения с вами.

Изменить, в ответ на JimR:

Спасибо за солидный ответ. В моем чтении, так как я написал исходный вопрос, я отступил от использования MapReduce. Я еще не решил точно, как я хочу это сделать, но я начинаю чувствовать, что MapReduce лучше распространяет/распараллеливает вычислительную нагрузку, когда я действительно просто ищу, чтобы распараллелить HTTP-запросы.

Какова была бы моя задача "уменьшить", часть, которая берет все извлеченные данные и сует ее в результаты, не является интенсивной с вычислительной точки зрения. Я уверен, что это закончится тем, что это один большой SQL-запрос, который выполняется на секунду или два на пользователя.

Итак, к чему я склоняюсь:

  • Не-MapReduce Работа/Рабочиймодель, написанная на Python. Один мой друг Google превратил меня в изучение Python для этого, так как он низко накладные и хорошо масштабируется.
  • Использование Amazon EC2 в качестве вычислительного уровня. Я думаю, это означает, что мне также нужен кусок EBS для хранения моей базы данных.
  • Возможно, с помощью простой очереди сообщений Amazon Simple Message. Похоже, что этот 3-й виджет Amazon предназначен для отслеживания очередей заданий, перемещения результатов из одной задачи во входные данные другого и изящного решения неудачных задач. Это очень дешево. Возможно, стоит реализовать вместо собственной системы очереди заданий.
4b9b3361

Ответ 1

Кажется, что мы собираемся с Node.js и Seq библиотека управления потоками. Было очень легко перейти от моей карты/блок-схемы процесса к узлу кода, и теперь это просто вопрос заполнения кода для подключения к правильным API.

Спасибо за ответы, они очень помогли найти решение, которое я искал.

Ответ 2

Работа, которую вы описываете, вероятно, подходит для любой очереди или комбинации очереди и сервера заданий. Это, безусловно, может работать как набор шагов MapReduce.

Для сервера заданий я рекомендую посмотреть на Gearman. Документация не является удивительной, но презентации прекрасно документируют ее, и модуль Python также достаточно понятен.

В принципе, вы создаете функции на сервере заданий, и эти функции вызываются клиентами через API. Функции можно вызывать либо синхронно, либо асинхронно. В вашем примере вы, вероятно, хотите асинхронно добавить задание "Начать обновление". Это будет делать любые подготовительные задания, а затем асинхронно вызовет работу "Получить последовательных пользователей". Это задание выберет пользователей, а затем вызовет задание "Обновление последующих пользователей". Это обеспечит совместную работу "Избранное" для пользователей и друзей, а также синхронно дожидается результата всех из них. Когда все они вернутся, он вызовет задание "Рассчитать новую очередь".

Этот подход, основанный на использовании только для работы, изначально будет немного менее надежным, так как гарантирование того, что вы будете обрабатывать ошибки, и любые down-серверы и персистенция должным образом будет весело.

Для очереди SQS является очевидным выбором. Он прочный и очень быстрый доступ к EC2 и дешевый. И еще проще настроить и поддерживать, чем другие очереди, когда вы только начинаете.

В принципе, вы поместите сообщение в очередь, подобно тому, как вы отправляете задание на сервер заданий выше, за исключением того, что вы, вероятно, ничего не будете делать синхронно. Вместо того, чтобы делать "Получить избранное для пользователя" и т.д., Синхронно звонит, вы сделаете их асинхронно, а затем получите сообщение, в котором говорится, чтобы проверить, все ли они завершены. Вам потребуется какая-то настойчивость (база данных SQL, с которой вы знакомы, или Amazon SimpleDB, если вы хотите полностью перейти к AWS), чтобы отслеживать, выполнена ли работа - вы не можете проверить ход выполнения задания в SQS (хотя вы можете в других очередях). Сообщение, которое проверяет, все ли они закончены, проверит проверку - если они еще не закончены, ничего не делайте, а затем сообщение будет повторно проведено через несколько минут (на основе visibility_timeout). В противном случае вы можете поместить следующее сообщение в очередь.

Этот подход, основанный только на очереди, должен быть надежным, если вы не будете использовать сообщения очереди по ошибке, не выполняя работу. Сделать ошибку, как это трудно сделать с SQS - вы действительно должны попробовать. Не используйте автоматические очереди или протоколы - если вы ошибаетесь, возможно, вы не сможете гарантировать, что вы отправите замененное сообщение в очередь.

В этом случае может оказаться полезной комбинация очереди и сервера заданий. Вы можете уйти с отсутствием хранилища персистентности, чтобы проверить ход выполнения задания - сервер заданий позволит вам отслеживать ход работы. Ваше сообщение "получить избранное для пользователей" может помещать все задания "получить избранные для пользовательских /B/C " на сервер заданий. Затем добавьте сообщение "проверить все избранные извлечения" в очереди со списком задач, которые должны быть полными (и достаточно информации для перезапуска любых заданий, которые таинственно исчезают).

Для бонусных очков:

Выполнение этого как MapReduce должно быть довольно простым.

Ваш первый ввод задания будет списком всех ваших пользователей. Карта будет принимать каждого пользователя, получать следующих пользователей и выводить строки для каждого пользователя и последующего пользователя:

"UserX" "UserA"
"UserX" "UserB"
"UserX" "UserC"

Шаг сокращения идентичности оставит это неизменным. Это создаст второй ввод задания. Карта для второго задания получит фаворитов для каждой строки (вы можете использовать memcached для предотвращения выборки избранных для UserX/UserA combo и UserY/UserA через API) и вывод строки для каждого избранного:

"UserX" "UserA" "Favourite1"
"UserX" "UserA" "Favourite2"
"UserX" "UserA" "Favourite3"
"UserX" "UserB" "Favourite4"

Шаг уменьшения для этого задания преобразует это значение в:

 "UserX" [("UserA", "Favourite1"), ("UserA", "Favourite2"), ("UserA", "Favourite3"), ("UserB", "Favourite4")]

На этом этапе у вас может быть другое задание MapReduce для обновления вашей базы данных для каждого пользователя с этими значениями, или вы можете использовать некоторые из связанных с Hadoop инструментов, таких как Pig, Hive и HBase, для управления своей базой данных для вы.

Я бы рекомендовал использовать Cloudera Distribution для команд управления Hadoop ec2 для создания и срывания вашего кластера Hadoop на EC2 (их AMI установили на Python) и использовать что-то вроде Dumbo (на PyPI) для создания ваших заданий MapReduce, так как он позволяет протестировать ваши задания MapReduce на вашем локальном /dev компьютере без доступа к Hadoop.

Удачи!

Ответ 3

Я работаю с аналогичной проблемой, которую мне нужно решить. Я также рассматривал MapReduce и использовал сервис Elastic MapReduce от Amazon.

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

Я отвечу на ваши вопросы, поскольку я понимаю вашу (и мою) проблему, и, надеюсь, это помогает.

  • Да, я думаю, что это будет хорошо. Вы можете рассмотреть возможность использования опции нескольких шагов Elastic MapReduce. Вы можете использовать 1 шаг, чтобы получить людей, которых следует пользователю, и еще один шаг для составления списка треков для каждого из этих последователей, а редуктор для этого второго шага, вероятно, будет тем, который должен создать кеш.

  • Зависит от того, насколько велик ваш набор данных и как часто вы его запускаете. Трудно сказать, не зная, насколько большой набор данных (или собирается получить), если он будет экономически эффективным или нет. Первоначально это, вероятно, будет весьма рентабельным, так как вам не придется управлять собственным кластером hadoop и не оплачивать экземпляры EC2 (предполагая, что вы используете) все время. Как только вы достигнете точки, где вы на самом деле хрустете эти данные в течение длительного периода времени, вероятно, будет все меньше и меньше смысла использовать службу Amazon MapReduce, потому что вы постоянно будете иметь узлы в сети все время.

Работа - это в основном ваша задача MapReduce. Он может состоять из нескольких шагов (каждая задача MapReduce - это шаг). После того как ваши данные будут обработаны и все шаги будут выполнены, ваше задание будет выполнено. Таким образом, вы эффективно оплачиваете процессорное время для каждого node в кластере Hadoop. так что T * n, где T - время (в часах), которое требуется для обработки ваших данных, а n - количество узлов, на которые вы говорите, что Amazon вращается вверх.

Надеюсь, это поможет, удачи. Я хотел бы услышать, как вы в конечном итоге реализуете свои Mappers и Reducers, поскольку я решаю очень похожую проблему, и я не уверен, что мой подход действительно лучший.