我正在寻找推荐的解决方案来解决celerybeat是芹菜/ rabbitmq部署的单点故障。通过搜索网络,我没有发现任何有意义的东西。解决celerybeat是单点故障
就我而言,每天一次定时调度程序启动一系列可能运行半天或更长时间的作业。由于只能有一个celerybeat实例,所以如果它或它运行的服务器发生了问题,关键作业将不会运行。
我希望已经有一个工作解决方案,因为我不能是唯一需要可靠(集群或类似)调度程序的人。如果我不需要,我不想诉诸某种数据库支持的调度程序。
我正在寻找推荐的解决方案来解决celerybeat是芹菜/ rabbitmq部署的单点故障。通过搜索网络,我没有发现任何有意义的东西。解决celerybeat是单点故障
就我而言,每天一次定时调度程序启动一系列可能运行半天或更长时间的作业。由于只能有一个celerybeat实例,所以如果它或它运行的服务器发生了问题,关键作业将不会运行。
我希望已经有一个工作解决方案,因为我不能是唯一需要可靠(集群或类似)调度程序的人。如果我不需要,我不想诉诸某种数据库支持的调度程序。
芹菜github回购存在一个问题。不知道他们是否正在努力。
作为解决方法,您可以为任务添加一个锁,以便一次只运行特定PeriodicTask的一个实例。
喜欢的东西:
if not cache.add('My-unique-lock-name', True, timeout=lock_timeout):
return
搞清楚锁定超时是很好,很棘手。我们使用0.9 *任务run_every秒,如果不同的celerybeats会尝试在不同的时间运行它们。只是为了留下一些余量(例如,当芹菜稍微落后于一次计划时,那么它按计划会导致锁仍然活动)。
然后,您可以在所有机器上使用celerybeat实例。每个任务将为每个celerybeat实例排队,但只有一个任务会完成运行。
任务仍然遵循run_every这种方式 - 最坏的情况:任务将以0.9 * run_every速度运行。
这种情况下的一个问题是:如果任务在排定时间排队但未在预定时间处理(例如因为队列处理器不可用) - 则锁定可能放置在错误的时间,导致可能1个下一个任务无法运行。为了解决这个问题,你需要某种检测机制,无论任务是按时或多或少。
但是,在生产中使用时,这不应该是常见的情况。
另一种解决方案是将celerybeat调度器子类化并覆盖它的tick方法。然后在处理任务之前为每个滴答声添加一个锁。这确保了只有具有相同周期性任务的celerybeats才会多次排队同一个任务。每个勾号只有一个celerybeat(赢得比赛条件的人)将排队任务。在一个芹菜跳下去的时候,下一个跳动的另一个将赢得比赛。
这当然可以与第一个解决方案结合使用。
当然,对于这项工作,缓存后端需要为所有服务器进行复制和/或共享。
这是一个老问题,但我希望它可以帮助任何人。