2011-12-28 4 views
2

Я использую Python и celery в проекте. В проекте, у меня есть два файла:Проблемы с распределением переменных между сельдерием

celeryconfig.py

BROKER_URL = "amqp://guest:[email protected]:5672//" 
CELERY_RESULT_BACKEND = "amqp" 
CELERY_IMPORTS = ("example",) 
CELERYD_CONCURRENCY = 2 

и example.py

from celery.task import task 
import hashlib 

md5 = hashlib.md5() 

@task 
def getDigest(text): 
    print 'Using md5 - ',md5 
    md5.update(text) 
    return md5.digest() 

В celeryconfig.py я установил CELERYD_CONCURRENCY до , что означает, что он будет распределите задачи в моей очереди задач до различных процессов.

С консоли Python, я бегу:

from example import getDigest 
getDigest.delay('foo');getDigest.delay('bar') 

Это создает две задачи, которые одновременно выполняются двумя рабочими. Проблема заключается в том, что как рабочие процессы выполняют свои задачи [getDigest()], они, похоже, используют один и тот же объект-хэш (md5). Вывод celeryd подтверждает это, как вы можете видеть ниже.

[PoolWorker-2] Using md5 - 
[PoolWorker-2] <md5 HASH object @ 0x23e6870> 
[PoolWorker-1] Using md5 - 
[PoolWorker-1] <md5 HASH object @ 0x23e6870> 

Для простоты я использую объект md5 из hashlib, но в моем реальном проекте, я использую объект, который не может быть доступны и модифицированы более чем одним процессом. Это, как ожидается, приводит к крушению рабочих.

Это вызывает вопрос: как я могу изменить свой код, чтобы инициализировать рабочие процессы и использовать их собственный (md5) объект? Прямо сейчас, они делят один и тот же объект, из-за чего мое приложение терпит крах. Это возможно?

ответ

5

Они используют один и тот же объект, потому что вы явно говорите им в своем коде. Создавая объект вне области действия задачи и используя его внутри задачи, вы предоставляете всем рабочим доступ к общему объекту. Это проблема параллелизма, не обязательно проблема сельдерея. Вы можете использовать копию объекта, если он мал, или использовать собственную стратегию блокировки. В общем, хотя, если объект будет обновляться более чем одним процессом за раз, ему необходимо использовать какую-то синхронизацию, которая выходит за рамки Celery.

+2

Это не тот же объект. Сельдерей копирует процесс пр. который дает вам то же самое свойство объекта md5 в этом случае. –