我们正在运行一个API服务器,用户在该服务器上提交作业进行计算,这需要1秒到1小时的时间。然后,他们请求检查状态并获得结果,这可能(很久(以后,甚至永远不会。
目前,作业被添加到发布/子队列中,并由各种工作进程进行处理。然后,这些工作人员将pub/sub消息发送回侦听器,侦听器将状态/结果存储在postgres数据库中。
我正在考虑使用Celery来简化事情,并允许更容易的扩展。
在使用celery_app.send_task
的Celery中,提交作业和获取结果不是问题。然而,我不知道如何最好地确保结果在何时存储,特别是对于长时间运行或可能被放弃的作业。
我考虑的一些解决方案包括:
-
允许所有工作人员访问数据库并让他们处理更新。对此的主要限制似乎是数据库连接池限制,因为在某些情况下,工作进程可以扩展到50个副本。
-
在一个单独的pod中监听celenie事件,并将基于此的更改写入jobs数据库。只需要1个连接,但据我所知,在重新部署这个pod时,这将错过事件。
-
只有在用户要求时才检查作业结果。当用户花费太长时间或缓慢堵塞结果缓存时,这似乎会导致结果丢失。
-
如(3(所示,但定期检查数据库中未标记为已完成的所有作业。有点复杂,但可行吗?
是否有标准模式,或者我是否试图用Celery做一些不寻常的事情?任何关于如何解决这一问题的建议都将不胜感激。
过去,我通过修改任务来解决类似的问题,不仅返回计算结果,而且在返回之前将其存储到缓存服务器(Redis(中。我有一项任务,定期(每5分钟(收集这些结果,并将数据(批量,非常有效(写入关系数据库。它非常有效,直到我们开始用数十万个结果填充缓存,所以我们实现了一个小型服务来完成这项工作,而不是周期性运行的任务。