用redis做backend储存celery异步任务的结果,
可以看到任务成功存进去了,
127.0.0.1:6379[1]> keys *
celery-task-meta-31a89019-4106-4685-8a71-0075d976d91e
不过用这个key去查询的时候可以看到结果乱码:
127.0.0.1:6379[1]> get celery-task-meta-31a89019-4106-4685-8a71-0075d976d91e
�}q(UstatusqUSUCCESSqU tracebackqNUresultqchildrenq]u.
但是如果用官方AsyncResult提供的api是可以正常取到结果的。
python代码:
def get_result(task_id):
res = AsyncResult(task_id)
while True:
print(res.status)
if res.ready():
break
time.sleep(1)
print(res.result)
print(res.get()
顺着官方的res.status一路追踪源码,可以看到取数据的方法也是从redis中用key拿到原始数据,只不过在做了一些解码和序列化相关的操作。
拿到status的调用栈的过程大致是:state()->_get_task_meta()-get_task_meta()->_get_task_meta_for()->decode_result()->decode()->loads()->pickle_loads()
最终结果就是如果用的json序列化,会调用kombu库中serialization模块的pickle_loads方法。
所以我们也直接用pickle_loads这个方法就可以正常拿到redis中的数据。
代码如下:
# -*- coding: utf-8 -*-
import time
from kombu.serialization import pickle_loads
from redis import Redis
redis_client = Redis(db=1)
res= redis_client.get('celery-task-meta-31a89019-4106-4685-8a71-0075d976d91e')
#乱码结果
print "乱码结果:%s"%res
res = pickle_loads(res)
#正常结果
print "正常结果:%s"%res
输出:
乱码结果:�}q(UstatusqUSUCCESSqU tracebackqNUresultqchildrenq]u.
正常结果:{'status': 'SUCCESS', 'traceback': None, 'result': 8, 'children': []}