2015-07-24 7 views
6

Какой инструмент или набор инструментов вы бы использовали для горизонтального масштабирования scrapyd, добавляя новые машины в scrapyd-кластер динамически и имея N экземпляров на машину, если это необходимо. Не обязательно, чтобы все экземпляры делили общую очередь заданий, но это было бы потрясающе.Горизонтальное масштабирование Scrapyd

Scrapy-cluster кажется перспективным для работы, но я хочу решение на основе Scrapyd, поэтому я слушаю другие альтернативы и предложения.

+0

Вы найдете решение? – HamoonDBA

+0

@HamoonDBA Я написал свой собственный балансировщик нагрузки, стиль devOps для scrapyd, используя scrapyd api, и принимая во внимание количество заданий каждый раз, когда приходит новый, добавит образец кода позже. – gerosalesc

ответ

1

Я написал собственный балансировщик нагрузки для Scrapyd, используя его API и wrapper.

from random import shuffle 
from scrapyd_api.wrapper import ScrapydAPI 

class JobLoadBalancer(object): 

    @classmethod 
    def get_less_occupied(
      cls, 
      servers_urls=settings.SERVERS_URLS, 
      project=settings.DEFAULT_PROJECT, 
      acceptable=settings.ACCEPTABLE_PENDING): 

     free_runner = {'num_jobs': 9999, 'client': None} 
     # shuffle servers optimization 
     shuffle(servers_urls) 
     for url in servers_urls: 
      scrapyd = ScrapydAPI(target=url) 
      jobs = scrapyd.list_jobs(project) 
      num_jobs = len(jobs['pending']) 

      if free_runner['num_jobs'] > num_jobs: 
       free_runner['num_jobs'] = num_jobs 
       free_runner['client'] = scrapyd 
      # Optimization: if found acceptable pending operations in one server stop looking for another one 
      if free_runner['client'] and free_runner['num_jobs'] <= acceptable: 
       break 

     return free_runner['client'] 

испытания Единица измерения:

def setUp(self): 
     super(TestFactory, self).setUp() 
     # Make sure this servers are running 
     settings.SERVERS_URLS = [ 
      'http://localhost:6800', 
      'http://localhost:6900' 
     ] 
     self.project = 'dummy' 
     self.spider = 'dummy_spider' 
     self.acceptable = 0 

    def test_get_less_occupied(self): 
     # add new dummy jobs to first server so that choose the second one 
     scrapyd = ScrapydAPI(target=settings.SERVERS_URLS[0]) 
     scrapyd.schedule(project=self.project, spider=self.spider) 
     scrapyd.schedule(project=self.project, spider=self.spider) 
     second_server_url = settings.SERVERS_URLS[1] 
     scrapyd = JobLoadBalancer.get_less_occupied(
      servers_urls=settings.SERVERS_URLS, 
      project=self.project, 
      acceptable=self.acceptable) 
     self.assertEqual(scrapyd.target, second_server_url) 

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