在我们的网站上,我们希望为用户创建每小时报告,我们的第一个解决方案就是这个(我使用芹菜):
这是我用于为单个用户创建报告的内容:
@app.task
def create_report(user):
# this method creates report for given user
pass
然后我创建了这个cron任务,celery每60分钟运行一次这个任务:
@app.task
def report_cron():
for user in User.objects.all():
create_report.delay(user)
这个灵魂将整个用户表添加到芹菜队列中(我们使用的是rabbitmq)。
目前这个解决方案运行正常(我们没有很多用户)但是你能帮助解决这个问题吗?
答案 0 :(得分:2)
这种方法没有什么特别的错误,但它确实取决于每份报告需要多长时间。例如,如果每个报告需要一毫秒,那么它将花费绝大部分时间将消息放入队列和队列之外并建立数据库连接。关于我所做的唯一调整是允许批处理,因此您可以调整每个任务生成的报告数量。然后,您可以尝试不同的批量大小以找到最佳平衡。
以这种方式使用队列也很棒,因为您可以通过添加更多工作人员来扩展。
缺点是报告不会精确每小时,具体取决于消息等待处理的时间。
答案 1 :(得分:1)
我将不得不猜测一些事情,因为你的问题并没有很多信息。
我们假设您的报告是一个模型,您可以创建它们而不保存它们,然后使用bulk_create来生成一个请求。
假设您需要在用户模型上访问外键,您应该使用select_related和prefetch_related来优化您的请求。理想情况下,您的任务不应该为所有用户执行多个请求,而且每个多对多的字段需要一个请求,还有一个用于创建所有报告。
如果没有更多信息,我可以提供所有建议。也许您应该在每次用户迭代时添加一个测试,以确保您的任务不会花费超过一个小时的时间,因此如果发生这种情况,您不会感到惊讶。