我有一个任务,我使用 celerybeat 每分钟执行一次。它工作正常。但有时,该任务需要几秒钟多于一分钟才能运行,因为该任务的两个实例会运行。这会导致一些混乱的竞争条件。
我可以(并且可能应该)修复我的任务以使其正常工作,但我想知道 celery 是否有任何内置方法来确保这一点。我粗略的 Google 搜索和 RTFM 没有产生任何结果。
我有一个任务,我使用 celerybeat 每分钟执行一次。它工作正常。但有时,该任务需要几秒钟多于一分钟才能运行,因为该任务的两个实例会运行。这会导致一些混乱的竞争条件。
我可以(并且可能应该)修复我的任务以使其正常工作,但我想知道 celery 是否有任何内置方法来确保这一点。我粗略的 Google 搜索和 RTFM 没有产生任何结果。
您可以添加一个 lock,使用 memcached 之类的东西或只是您的数据库。
如果您使用 cron 计划或时间间隔来运行定期任务,您仍然会遇到问题。您始终可以使用数据库或缓存甚至文件系统的锁定机制,或者还可以从前一个任务中安排下一个任务,这可能不是最好的方法。这个问题可能对你有帮助: django celery: how to set task to run at specific interval Programming
您可以尝试向包含您正在运行的函数的对象添加一个类字段,并将该字段用作“其他人是否正在工作”控件
锁定是使用 beat 或 cron 的好方法。
但是,请注意节拍作业在工作人员开始时运行,而不是在节拍运行时运行。
这导致我即使有锁也会出现竞争状况。假设工人关闭,并且 beat 将 10 个作业放入队列中。当 celery 启动 4 个进程时,所有 4 个进程都获取一个任务,在我的情况下,1 或 2 会同时获取并设置锁。
解决方案之一是使用带锁的 cron,因为 cron 将在那个时候执行,而不是在 worker 启动时间执行。
解决方案二是使用更高级的锁定机制来处理竞争条件。对于 redis,请查看setnx或更新的redlock。这篇博文非常好,并且包含一个使用 redis-py 锁定机制的装饰器模式:http: //loose-bits.com/2010/10/distributed-task-locking-in-celery.html。