You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Celery任务Redis存储结果调用get返回None,如何正确获取任务返回数据

问题根因

从你提供的Celery运行日志可以看到:

[2021-12-09 15:08:05,090: INFO/ForkPoolWorker-15] Task get_top_ten_gainers[26ce0da8-662c-4690-b95e-9d1e42e79e34] succeeded in 3.8531467270004214s: None

任务执行成功后返回给Celery的结果本身就是None,并非结果没有存入Redis后端,问题出在任务返回值没有被Celery正常接收。

排查步骤

  • 确认任务执行到了return语句:在return payload前加一行日志logger.info(f"返回payload:{payload}"),检查Worker日志中是否有这行输出,如果没有说明return前的代码出现了隐式中断,如果有则说明返回值被其他逻辑拦截。
  • 检查Celery全局配置:确认没有设置CELERY_IGNORE_RESULT = True,虽然你在任务装饰器中指定了ignore_result=False,部分版本的Celery存在全局配置优先级高于任务级配置的问题。
  • 检查任务是否有其他装饰器:如果get_top_ten_gainers上除了@shared_task还有其他自定义装饰器,要确保装饰器正确透传了原函数的返回值,否则会导致返回值被替换为None。
  • 验证结果序列化兼容性:你返回的嵌套列表是标准JSON可序列化结构,可手动测试json.dumps(payload)是否报错,排除序列化失败导致返回值被清空的可能。

适配你需求的最优方案

你原本的需求是每日执行一次任务缓存查询结果,不需要每次请求都触发任务运行,完全可以跳过Celery Result Backend的逻辑,直接手动操作Redis实现缓存,逻辑更可控,性能也更好:

  1. 在任务中拿到payload后直接写入Redis固定key,设置24小时过期:
import json
import redis
redis_client = redis.Redis(host='127.0.0.1', port=6379, db=0)

@shared_task(name='get_top_ten_gainers')
def get_top_ten_gainers():
    # 原有查询逻辑不变,拿到payload后
    redis_client.setex("top_ten_gainers", 86400, json.dumps(payload))
    return payload
  1. 用Celery Beat配置每日定时触发该任务,不需要在请求时调用任务。
  2. Flask端辅助函数直接读取Redis缓存即可:
def _top_ten_gainers():
    data = redis_client.get("top_ten_gainers")
    if not data:
        # 缓存失效时可选主动触发一次任务兜底
        get_top_ten_gainers.delay()
        return []
    total_payload['gainers'] = json.loads(data)

内容的提问来源于stack exchange,提问作者sat1017

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 11:24:03