1. celery(LIST) 是待领取队列,任务被 worker 取走后就会从这里移除。
2. unacked(HASH)+ unacked_index(ZSET) 是已被取走但未 ACK 的任务,文章说 worker 退出会自动回写队列,但实测只有正常退出(ctrl+c/stop)才会回写;如果是进程崩溃、kill -9、挂死,任务会一直留在 unacked,不会自动回到 celery 队列,必须等 visibility_timeout 或手动执行 celery inspect restore 才能恢复。
3. visibility_timeout 不是 Redis 自动执行,而是由活着的 worker 定时扫描才会把超时任务放回队列;如果全部 worker 都挂了,这个超时机制等于失效。
4. prefetch_multiplier(预取) 影响非常大:
5. 默认 prefetch_multiplier=4,worker 启动后会一次性把队列里的任务全部取到 unacked,队列瞬间变空;
6. 设为 1 时,worker 一次只取 1 个,执行完再取下一个,更安全,不会大量任务堆积在 unacked。
7. --pool=solo 与默认 prefork 区别:--pool=solo:不预取,一次只拿 1 个,unacked 最多 1 条;
默认 -c N:会批量预取,队列容易被一次性取空,unacked 会瞬间变多。
总结:想稳定不丢任务、不卡 unacked,建议用:--prefetch-multiplier=1 + 合理 visibility_timeout,崩溃后记得手动恢复任务
Celery + Redis 的探究文本尝试研究,使用 redis 作为 celery 的 broker 时,celery 的交互操作同 redis 中数据记录的关联关系。不在乎过程的,可以直接看最后的结论。 ...