Celery4.1.0搭配Redis≥3.0.0报错AttributeError求解决(Python3.6)
解决Celery 4.1.0 + Redis-py ≥3.0.0 兼容问题(Python3.6环境)
错误原因
Celery 4.1.0依赖的kombu版本(4.1.x)使用了Redis-py 2.x的zadd语法(位置参数:zadd(key, score, value)),但Redis-py 3.0+修改了zadd的参数要求,必须传入字典格式(zadd(key, {value: score})),导致调用时触发AttributeError: 'float' object has no attribute 'items'。
解决方案
方案1:升级Celery到兼容版本(优先推荐)
Celery 4.4.x系列完全支持Python3.6,且修复了与Redis-py 3.x的兼容问题。直接升级Celery即可:
pip install celery==4.4.7
该版本无需修改项目代码,可直接搭配Redis-py 4.3.6使用。
方案2:修改kombu库的Redis传输代码
如果无法升级Celery,可手动修改kombu的Redis传输文件:
- 找到Python3.6环境下的kombu Redis传输文件,路径一般为
/usr/local/lib/python3.6/site-packages/kombu/transport/redis.py - 找到
QoS类的append方法,将:
修改为:pipe.zadd(self.unacked_index_key, time(), delivery_tag) \pipe.zadd(self.unacked_index_key, {delivery_tag: time()}) \ - 同时找到
_restore_unacked方法中的类似调用,将:
修改为:pipe.zadd(self.unacked_index_key, time(), tag)pipe.zadd(self.unacked_index_key, {tag: time()})
方案3:使用Monkey Patch动态修复代码
如果不想修改库文件,可在项目启动代码(如Celery入口文件、settings文件)中加入以下补丁代码:
import time from kombu.transport.redis import QoS # 保存原方法 original_append = QoS.append def patched_qos_append(self, message, delivery_tag): pipe = self.connection.pipeline() pipe.zadd(self.unacked_key, 1, delivery_tag) # 改用Redis-py 3.x兼容的zadd格式 pipe.zadd(self.unacked_index_key, {delivery_tag: time()}) pipe.execute() # 替换原方法 QoS.append = patched_qos_append
确保这段代码在Celery Worker启动前执行。
内容的提问来源于stack exchange,提问作者Алексей Заикин
相关产品推荐
相关产品推荐

