python - 用户启动的后台进程数量有限

标签 python django asynchronous celery background-process

我需要允许用户提交对非常非常大的作业的请求。我们说的是 100 GB 的内存和 20 小时的计算时间。这让我们公司花了很多钱,所以规定任何时候只能运行2个作业,已经有2个作业再请求新的作业会被拒绝(并通知用户服务器忙)。

我当前的解决方案使用 concurrent.futures 中的执行器,并且需要将 Apache 服务器设置为仅运行一个进程,从而降低响应速度(当前用户数非常少,所以暂时没问题)。

如果可能的话,我想为此使用 Celery,但我没有在文档中看到任何方式来完成此特定设置。

如何在 Django 应用程序的后台运行有限数量的作业,并在作业因服务器繁忙而被拒绝时通知用户?

最佳答案

针对这种特殊情况,我有两种解决方案,一种是 celery 的现成解决方案,另一种是您自己实现的。

  1. 你可以对 celery worker 做这样的事情。特别是,您只创建两个并发=1 的工作进程(或者好吧,一个并发=2,但那将是线程,而不是不同的进程),这样,只能完成两个工作异步地。现在你需要一种方法来在两个工作都被占用时引发异常,然后你使用 inspect , 计算事件任务的数量并在需要时抛出异常。如需实现,您可以查看 this SO post .

您可能还对 rate limits 感兴趣.

  1. 您可以使用所选的锁定解决方案自行完成所有工作。特别是,确保只有两个进程与 redis(和 redis-py)一起运行的一个很好的实现就像下面这样简单。 (考虑到你知道 Redis,因为你知道 celery )

    from redis import StrictRedis
    
    redis = StrictRedis('localhost', '6379')
    locks = ['compute:lock1', 'compute:lock2']
    for key in locks:
        lock = redis.lock(key, blocking_timeout=5)
        acquired = lock.acquire()
        if acquired:
            do_huge_computation()
            lock.release()
            break
        print("Gonna try next possible slot")
    
    if not acquired:
        raise SystemLimitsReached("Already at max capacity !")
    

这样你就可以确保系统中只能存在两个正在运行的进程。第三个进程将在 lock.acquire() 行中阻塞 blocking_timeout 秒,如果锁定成功,则 acquired 将为 True,否则它是假的,你会告诉你的用户等待!

我过去某个时候有过同样的需求,我最终编写的代码类似于上面的解决方案。特别是

  1. 这具有尽可能少的竞争条件
  2. 易于阅读
  3. 不依赖于系统管理员,在负载下突然将工作人员的并发性增加一倍并炸毁整个系统。
  4. 您还可以实现每个用户的限制,这意味着每个用户可以有 2 个同时运行的作业,只需更改 compute:lock1< 中的锁定 key /em> 相应地 compute:userId:lock1 和 lock2。你不能用 Vanilla celery 做这个。

关于python - 用户启动的后台进程数量有限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39416623/

相关文章:

Python coverage.py exclude_lines

css - Django 。如何在 bool 表单字段上应用CSS样式?

node.js - 是否有替代已弃用的 deferred.callback 的替代品?

javascript - 我们可以设置javascript用javascript异步加载吗?

scala - Future[Future[T]] 到 Future[T] 在另一个 Future.map 中而不使用 Await?

python - 无法使用 Python 导出 Cassandra 表

python - Django 模板中 url 的 NoReverseMatch

python - 根据主表一列spark.sql验证两列中的数据

django - 如何将网站托管在 Heroku 上并将数据库本地存储在我的计算机上?

android - 获取 token 身份验证 View 时出现 Django REST HTTP 400 错误