2011-09-21 2 views
9

약 150k 장고 개체에서 작업을 실행해야합니다. 이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 브로커로 Django ORM을 사용하고 있습니다. 데이터베이스 백엔드는 MySQL이고 초크이며 모든 작업의 ​​task.delay() 중에 종료됩니다. 관련하여 양식 제출에서이 문제를 해결하고 싶지만 결과로 응답 시간이 인 매우 응답 시간이 길어졌습니다.django/celery : 150k 장고 개체에서 작업을 실행하는 모범 사례?

+1

이것은 정확히 ** 필요한 질문입니다. 대단히 감사합니다. – mlissner

답변

10

나는 또한 "브로커"로 데이터베이스를 사용하는 이외의 사용을 고려한다. 그것은 정말로 이런 종류의 일에 적합하지 않습니다. 당신은 아마 처리 15000 프로세서를 가지고 있지 않기 때문에, 또한

from celery.task import TaskSet, task 

from myapp.models import MyModel 

@task 
def process_object(pk): 
    obj = MyModel.objects.get(pk) 
    # do something with obj 

@task 
def process_lots_of_items(ids_to_process): 
    return TaskSet(process_object.subtask((id,)) 
         for id in ids_to_process).apply_async() 

:

비록, 당신은 다른 작업을 생성하는 작업을 실행하여 요청/응답주기에서 이러한 오버 헤드의 일부를 이동할 수 있습니다 병렬 이러한 개체 의 모든, 당신은 덩어리의 개체를 분할 수 있다고 말한다 100의 1000의 :

from itertools import islice 
from celery.task import TaskSet, task 
from myapp.models import MyModel 

def chunks(it, n): 
    for first in it: 
     yield [first] + list(islice(it, n - 1)) 

@task 
def process_chunk(pks): 
    objs = MyModel.objects.filter(pk__in=pks) 
    for obj in objs: 
     # do something with obj 

@task 
def process_lots_of_items(ids_to_process): 
    return TaskSet(process_chunk.subtask((chunk,)) 
         for chunk in chunks(iter(ids_to_process), 
              1000)).apply_async() 
+0

감사합니다. @ApPeL과 제안을 통해 RabbitMQ 브로커로 이동하여 즉각적인 이득을 얻었습니다. 또한, 이러한 작업을 통합하면 내가 성취하려는 것을 확립했습니다 !! –

+0

이 코드가 작동하는 방식과 생성되는 작업의 수를 설명해주십시오. 나는 지난 4 일 동안 그것을 시험해 보았고 나의 데이터베이스를 계속 가져왔다. 나는 80 %의 CPU만을 사용하고 있지만, "MySQL이 사라졌다"는 것을 깨닫고 약간의 실행 후 오류를 연결합니다. –

+0

데이터베이스가 오버로드되는 것 같습니다. 결과를 데이터베이스에 저장합니까? 이것은 django-celery의 기본값입니다. 그것들이 필요 없다면'@task (ignore_result = True)'를 설정하거나'CELERY_IGNORE_RESULT = True'를 사용하여 전역 적으로 사용 불가능하게해야합니다 – asksol

1

나는 엔진으로 beanstalkd (http://kr.github.com/beanstalkd/)를 사용합니다. django-beanstalkd를 사용하면 장고와 작업을 추가하는 것이 매우 간단합니다. https://github.com/jonasvp/django-beanstalkd/

이것은 내 용도에 대해 매우 신뢰할 만하다. 노동자의

예 :

import os 
import time 

from django_beanstalkd import beanstalk_job 


@beanstalk_job 
def background_counting(arg): 
    """ 
    Do some incredibly useful counting to the value of arg 
    """ 
    value = int(arg) 
    pid = os.getpid() 
    print "[%s] Counting from 1 to %d." % (pid, value) 
    for i in range(1, value+1): 
     print '[%s] %d' % (pid, i) 
     time.sleep(1) 

일/직원/작업을 시작하려면 :

from django_beanstalkd import BeanstalkClient 
client = BeanstalkClient() 

client.call('beanstalk_example.background_counting', '5') 

가 즐겨 (장고 - beanstalkd의 예를 들어 응용 프로그램에서 추출 소스)!