【问题标题】:Celery/Redis task expirationCelery/Redis 任务过期
【发布时间】:2018-08-06 14:14:32
【问题描述】:

我正在使用 Celery,主管运行工作程序,Redis 作为代理,我遇到了一个 Celery 工作程序明显冻结的问题,使其无法处理更多任务并导致其在 Redis 中的任务队列被填满直到导致一些内存问题。我在调用任务时尝试设置 expires 选项,认为这将利用 Redis 对密钥到期的支持:

some_task.apply_async(args=('foo',), expires=60)

但这不起作用,当我在 Redis CLI 中检查相应的列表时,它只是不断扩大——也许并不奇怪,因为它在 Redis 中听起来像 list expiry is not built-in functionalityCelery docs 说到期时间对应于“发布”任务后的时间,但我找不到任何提及“发布”的实际含义。我以为它是指将任务添加到 Redis 列表,所以要么这个假设是错误的,要么发生了我不理解的其他事情(或两者兼而有之)。

我对任务到期时间有误吗?如果是这样,有什么方法可以让消息在 Redis 中过期?

【问题讨论】:

    标签: python redis celery celeryd


    【解决方案1】:

    上下文比问题更令人费解。您可以使用 redis-cli 并检查了 redis 密钥。在 redis-cli 中,您可以输入 ttl sexykey 并且如果密钥在 Celery 那里写入时设置为过期,您应该已经看到剩余的秒数,因此回答您对此事的特定不确定性。

    首先,让我们明确有一个message broker。其次,有一个result backend。 Celery 只有极少数message brokers,但很多result backends。代理列表为 here。支持的后端列表位于第 10 页(截至 2018 年 3 月 24 日Transport and Backends部分here。我认为result backend 会填满,因为这也是我所看到的。

    Celery 可以将相同的 Redis 实例用作message brokerresult backend。 Celery 将执行任务的结果存储为 Redis 键,无论任务是否成功,此 Redis 键的默认到期时间为 1 天(86400 秒)。所以如果你有很多由 Celery 执行的函数调用,那么你的 Redis 内存缓存就会被填满,因为 86400 秒的密钥过期不会赶上任务结果的传入记录。

    为了将密钥过期时间缩短到 60 秒,这里是 python sn -p:

    app = Celery('justdoit',
        broker='redis://172.17.0.2',
        backend='redis://172.17.0.2')
    
    app.conf.result_expires = 60
    

    PS:几个小时前我刚刚学习 Celery,我立即意识到(在它发生之前)与描述的 Redis 填充场景完全相同。我已经使用 Redis 一年了,所以我知道它的一些特点。

    【讨论】:

      猜你喜欢
      • 2012-01-22
      • 2016-10-30
      • 2018-10-11
      • 2015-12-18
      • 2017-10-29
      • 2018-05-03
      • 2014-12-10
      • 1970-01-01
      • 2014-01-27
      相关资源
      最近更新 更多