django / celery: лучшие практики для запуска задач на объектах Django 150k? - PullRequest
9 голосов
/ 21 сентября 2011

Мне нужно запускать задания примерно на 150 тыс. Объектов Django.Каков наилучший способ сделать это?Я использую Django ORM в качестве брокера.Бэкэнд базы данных - MySQL, он задыхается и умирает во время task.delay () всех задач.В связи с этим я также хотел начать это с представления формы, но полученный запрос дал очень большое время ответа очень , которое истекло.

Ответы [ 3 ]

10 голосов
/ 21 сентября 2011

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

Хотя некоторые из этих издержек можно вывести из цикла запрос / ответ, запустив задачу для создания других задач:

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()

Кроме того, поскольку у вас, вероятно, нет 15000 процессоров для параллельной обработки всех этих объектов, вы можете разбить объекты на куски, скажем, 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()
2 голосов
/ 21 сентября 2011

Попробуйте вместо этого использовать RabbitMQ.

RabbitMQ используется во многих крупных компаниях, и люди действительно полагаются на него, поскольку он такой замечательный брокер.

Вот отличныйучебник о том, как начать работу с ним.

1 голос
/ 21 сентября 2011

Я использую beanstalkd (http://kr.github.com/beanstalkd/) в качестве двигателя.Добавить работника и задачу довольно просто для Django, если вы используете 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')

(источник взят из примера приложения django-beanstalkd)

Наслаждайтесь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...