rq最快上手,celery更适合长期演进;redis仅存储任务元数据和结果,真正执行靠worker进程;手写队列缺失重试、状态跟踪、幂等控制等基础设施能力,rq和celery已封装完备。

直接结论:用 RQ 最快上手,用 Celery 更适合长期演进;Redis 本身不直接“执行任务”,它只存任务元数据和结果,真正干活的是 rq worker 或 celery worker 进程。
为什么不能直接用 redis-py 写个队列就完事?
很多人尝试用 redis.lpush() + redis.blpop() 手写队列,结果卡在几个关键点上:
- 任务失败后没重试机制,
blpop拿到就删,崩了就丢 - 没有任务状态跟踪(queued / started / failed / finished),查都查不到
- 没法设置超时、重试次数、失败回调,线上出问题只能翻日志硬猜
- 多个 worker 并发消费时,没锁或幂等控制,同一任务可能被执行两次
这些不是“功能缺失”,而是分布式任务队列的基础设施需求。RQ 和 Celery 已经把这些封装好了,别重复造轮子。
RQ 的 enqueue() 调用后,任务到底存在 Redis 哪里?
RQ 把任务拆成三部分存进 Redis 不同结构里,理解这个能帮你快速 debug:
- 任务本身(函数名、参数、超时)序列化后存进
rq:queue:default这个 list —— 这就是你调用q.enqueue()后真正入队的地方 - 任务元数据(ID、状态、开始时间、结果)存在
rq:job:{job_id}这个 hash 里 - 如果任务失败,错误 traceback 存在
rq:failed这个 list,方便用rq info --failed查
所以如果你发现任务“没进去”,先 redis-cli 连上去 llen rq:queue:default 看长度;如果进了但没执行,hgetall rq:job:{id} 看 status 是不是 stuck 在 queued —— 那大概率是没起 worker,或者 worker 连的 Redis 地址和你代码连的不一致。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
Celery 的 broker 和 result_backend 必须分开配吗?
可以共用同一个 Redis 实例,但强烈建议用不同 db 分开:
-
broker='redis://localhost:6379/0'—— 任务分发走 db 0 -
result_backend='redis://localhost:6379/1'—— 结果存储走 db 1
原因很实际:任务队列高频写入(LPUSH/RPOP),结果存储是随机读写(HSET/HGET)。混在一个 db 容易因 key 冲突或过期策略互相干扰;更重要的是,Celery 的 result backend 如果和 broker 共 db,某些故障场景下(比如 flushdb)会清掉正在跑的任务。
worker 启动后没反应?检查这三件事
不是代码问题,大概率是环境链路断了:
- 确认
redis-server确实在跑:redis-cli ping返回PONG - 确认 worker 和你的应用代码用的是**完全相同的 Redis 连接参数**(host/port/db/password),尤其注意密码是否漏传
- 确认 worker 加载了正确的任务模块路径,比如你用
celery -A tasks worker,那tasks.py必须在当前目录或 PYTHONPATH 里,且里面定义了@app.task函数
一个容易被忽略的细节:RQ worker 默认只监听 default 队列,如果你用了 Queue('high'),启动时得加 rq worker high;Celery 同理,celery worker -Q high 才会消费 high 队列。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










