2014-02-04 4 views
1

RapGenius отправил this article о том, как они проверили все URL-адреса 170 тыс., Которые указывали на них, путем parellizing задачи очистки на рабочих динамиках на Heroku с использованием библиотеки Ruby Typhoeus.Распараллеливание Python в базу данных по всему Heroku

Я работаю над проектом, который включает в себя очищение (получение источника) для 1,5 миллионов URL-адресов, и я пытался ускорить его. Будучи более комфортным с Python, мне удалось взломать скребок, который распараллеливается на моем рабочем столе, используя redis и многопроцессорность python. Там, где я смущен, я должен изменить его, чтобы работать на Героку.

Вот как моя программа рассчитана прямо сейчас:

1) Сценарий инициализации работает, который хранит все адреса загодя в очереди Redis

2) сценарий, run_workers.py, работает , что запускает все процессы, как, например:

workers = [] 
q = get_redis_queue(name) 
for i in xrange(num_workers): 
    p = multiprocessing.Process(target=worker.scraper_worker, args=(i, q)) 
    p.start() 
    workers.append(p) 

for w in workers: 
    w.join() 

3) Рабочие, в worker.py, что делать выскабливание задача, как это:

def scraper_worker(worker_id, queue): 
    #consumes URL from redis queue, visits using python requests 
    #stores result into MySQL 
  • Может ли моя текущая структура программы быть перенесена непосредственно на Heroku? Что бы я добавил в Procfile? Моя первая догадка будет

    scrape: python init_scrape.py 
    

    Где init_scrape.py первым инициализирует очередь, затем запускает рабочий. Но у меня нет опыта, фактически распространяющего задачу python на облаке, и я хочу избежать дорогостоящих ошибок.

  • Выполнение этого локально, я нахожу, что хранение результатов непосредственно в базе данных (у которой есть 1,5 миллиона строк, для каждого URL-адреса и пустое место для кэширования), каждый запрос UPDATE выполняется медленно (требуется минут). Лучше ли хранить результаты во временной таблице, а затем объединить эти две таблицы позже?

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

ответ

2

Во-первых, если это «проект» недолговечна, или вообще не будет работать в производстве, я предлагаю вам не начать искать в «лучшие технологии», пока вы действительно не видите, что вам нужно к. Если вы только когда-нибудь будете запускать это 3 раза, это пустая трата времени.

К вашему последнему вопросу: Twisted - это асинхронная структура, очень похожая на «узел», которая позволит использовать более высокий коэффициент параллелизма на одной машине. Сельдерей - это распределенные задачи, это очень здорово, и оба они, как правило, заслуживают изучения и удовлетворения вам. (Я бы не стал беспокоиться с Twisted, если шкала не была огромная). Вместо сельдерея для вашего простого случая вы можете рассмотреть «RedisQ», модуль Python, который делает что-то подобное (и имеет очень краткую документацию) в Redis.

К вашему вопросу MySQL: этого не должно быть. Таблица строк 1.5M не мала, но вставки и обновления не обязательно должны занимать минуты. Начните расследование, отключив все ключи, индексы и первичные ключи, которые у вас есть.

К вашему вопросу архитектуры Heroku: у вас было бы два типа процессов: «веб-процесс» (который является вашим init_scrape.py), из которых у вас будет 1 (heroku ps:scale web=1) и «рабочий» процесс (из которого вы может иметь столько, сколько вы хотели бы, и это увеличивает ваш масштаб).

Ваш PROCFILE будет выглядеть примерно так:

web: python init_scrape.py 
worker: python worker.py 

Обратите внимание, что если вы хотите общаться с init_scrape.py процесса, вы должны называют его «паутина» в PROCFILE. Обратите также внимание на то, что в этом случае вы должны указать , чтобы связать прослушиватель TCP (в основном: прокрутите простой http-сервер) до порта os.environ['PORT']. Только «веб-процессы» получают маршрутизированные HTTP-запросы от «снаружи» от Heroku.

Также обратите внимание, что все ваши процессы никогда не должны «выходить» (или Heroku будет просто перекручивать их). Когда им нечего делать, они должны просто подождать/опросить задачи. Затем вы можете увеличить или уменьшить количество работников, используя heroku ps:scale.

Основная проблема здесь, в отношении того, что вы пишете, заключается в том, что ваш мастер будет не разворачивать рабочих. Рабочие процессы будут полностью разными. Работник будет просто инициализировать очередь redis (как вы, менион), и, возможно, разверните простой HTTP-сервер для связи, а затем сидите сложа руки.

Работникам необходимо будет передать имя очереди redis, и каждый работник будет в отдельности.

Удачи вам!

 Смежные вопросы

  • Нет связанных вопросов^_^