【发布时间】:2014-03-01 08:36:53
【问题描述】:
我有 ETA 任务被发送到 Celery 的 Redis 代理。它是单个 celery 和 redis 实例,都在同一台机器上。
问题是,任务被多次执行。我见过任务执行了 4 到 11 次。
鉴于我的 ETA 介于 4-11 小时之间(在运行时确定),我将可见性超时设置为 12 小时:
BROKER_TRANSPORT_OPTIONS = {'visibility_timeout': 12 * 60 * 60}
即便如此,任务仍会执行多次。
最初,有问题的任务不是幂等的,所以我尝试添加数据库检查以使其具有幂等性。
看起来像这样:
@app.task
def foo(side_effect_action):
if side_effect_action.executed:
return ALREADY_EXECUTED
else:
do_side_effect()
side_effect_action.executed = True
side_effect_action.save() #hits the db
return JUST_EXECUTED
事实证明,celery 工作人员在 foo 能够调用 side_effect_action.save() 并保存状态之前到达任务,因此在所有情况下,当它正在寻找 side_effect_action.executed 时,它仍然是 False,因此会被执行多次。
有什么想法可以解决这个问题吗?
【问题讨论】:
-
当使用 Redis 作为代理时,显然这是一个未解决的问题:github.com/celery/celery/issues/4400