删除已撤销的 Celery 任务

Jui*_*icy 5 celery python-3.x

根据文档task.revoke():​

所有工作节点都会保留已撤销任务 ID 的内存,无论是在内存中还是在磁盘上持久保存

撤销任务的工作原理是向所有工作人员发送广播消息,然后工作人员在内存中保存已撤销任务的列表。当一个worker启动时,它会将撤销的任务与集群中的其他worker同步。

这听起来好像任务在您撤销后仍然存在。我不明白为什么没有明确的方法来撤销任务并将其从队列中删除。

这些文档似乎暗示您需要无限期地保留已撤销任务的列表,以确保新工作人员在某些情况下不会接受它们。

我还知道有一个功能可以完全清除任务队列,但这不是我想要的。

有没有办法撤销任务并从 Celery 的任务队列中清除它(并且仅清除它)?

Eri*_*ran 2

除了使用或 中的手动命令删除所有消息之外,不可能只删除队列中的一条消息。purgebroker

但是,您可能不介意,因为一旦工作人员处理了已撤销的任务,就会从队列中删除。所以你不必维护一个永久的撤销id列表。

仅当工作人员因工作人员繁忙或任务安排在稍后时间而未处理该 ID 时,您才应在此列表中保留 ID。

如果您的所有工作人员可以同时停止并且您希望保留标记的已撤销任务,则该列表应该是持久的。否则,新工作人员会向已经运行的工作人员询问要标记为已撤销的任务。

注:我分析了一个以 Redis 作为代理和后端的案例来得到答案。被撤销的任务最终从队列中删除并可见(标记为已撤销)。

例子:

  1. ID 为“A”的任务被推送到队列中并计划在 1 小时内完成
  2. 任务“A”会revoke()向所有工作人员发送一条消息,以将该任务标记为已撤销。该id在每个worker的撤销列表中(参见log Tasks flagged as revoked: A
  3. 任务“A”仍在队列中等待其 ETA
  4. 一小时后,一名工人执行任务。由于任务被标记为已撤销,worker 不会执行该任务,而是立即将任务结果写入后端。结果表明该任务被撤销(因此未执行)。

我不知道为什么不能直接从队列中删除任务的确切原因。但我的直觉是:

  • 所有代理可能不允许删除队列中间的元素
  • 立即删除任务并让任务系统保持一致可能更困难。由于 Celery 团队的劳动力有限,如果更简单的解决方案可以完成工作,他们就不想支持复杂的东西