Celery / Redis同时执行多次并行任务

时间:2014-07-23 13:55:44

标签: python django redis celery

我有2个自定义任务(TaskATaskB),都来自celery.Task。调度程序偶尔会启动TaskA,而TaskA每次都会使用不同的参数启动NTaskB。但由于某种原因,有时相同的TaskB具有相同的参数,同时执行两次,这会导致数据库出现不同的问题。

class TaskA(celery.Task):

    def run(self, *args, **kwargs):
        objects = MyModel.objects.filter(processed=False)\
                                 .values_list('id', flat=True)
        task_b = TaskB()
        for o in objects:
            o.apply_async(args=[o, ])

class TaskB(celery.Task):

    def run(self, obj_id, *args, **kwargs):
        obj = MyModel.objects.get(id=obj_id)
        # do some stuff with obj

我尝试过的事情

我尝试使用celery.group希望它能解决这些问题,但我得到的只是错误,并说run需要2个参数而且没有提供任何参数。

我尝试使用TaskB启动celery.group

# somewhere in TaskA
task_b = TaskB()
g = celery.group([task_b.s(id) for id in objects])
g.apply_async()

我也尝试过这样:

# somewhere in TaskA
task_b = TaskB()
g = celery.group([task_b.run(id) for id in objects])
g.apply_async()

g.apply_async()之前执行任务。

问题

问题是来自我如何启动任务还是其他什么?这是正常行为吗?

其他信息

在我的本地计算机上,我使用celery 3.1.13运行RabbitMQ 3.3.4,并在服务器celery 3.1.13上运行Redis 2.8.9。 在本地机器上,我看不到这样的行为,每个任务都执行一次。在服务器上,我看到1到10个这样的任务连续两次执行。

这是我在本地计算机和服务器上运行celery的方式:

celery_beat: celery -A proj beat -l info

celery1: celery -A proj worker -Q default -l info --purge -n default_worker -P eventlet -c 50

celery2: celery -A proj worker -Q long -l info --purge -n long_worker -P eventlet -c 200

可行的解决方法

我根据收到的参数引入了对TaskB的锁定。经过大约10个小时的测试,我看到究竟正在执行两次,但是锁可以防止数据库发生冲突。 这确实解决了我的问题,但我仍然想知道它为什么会发生。

1 个答案:

答案 0 :(得分:2)

您是否按照Celery的Using Redis文档中的说明设置了fanout_prefixfanout_patterns?我正在使用Celi和Redis,我没有遇到这个问题。

相关问题