任务队列
核心观点:Redis 解决的不是“CPU 忙不忙”,而是“HTTP 连接能不能等”。
我们把你的 RAG 系统拆解来看:
场景一:CPU 密集型任务(PDF 解析、OCR)
现象:服务器 CPU 飙升到 100%,风扇狂转。
如果不加 Redis:
- Python 的 GIL(全局解释器锁)会导致主线程卡死。
- API 服务器完全失去响应,连简单的“健康检查”接口都回不了。
- 后果:系统崩溃(Crash / Unresponsive)。
Redis 的作用:“隔离”。把重活扔给 Worker 进程,保住 API 服务器的命。
场景二:I/O 密集型任务(DeepSeek / OpenAI 生成方案)
- 现象:CPU 占用率极低(可能只有 1%),因为服务器只是在傻傻地等待 DeepSeek 返回数据。
- 如果不加 Redis:
- HTTP 超时(Timeouts):这是最致命的。浏览器、Nginx 网关、负载均衡器通常都有 60秒 的默认超时时间。如果 DeepSeek 生成一个长方案需要 90秒,前端连接会被直接切断,用户看到“504 Gateway Timeout”,虽然你的后端还在跑,但结果发不回去了。
- Worker 耗尽(Worker Starvation):假设你用
uvicorn启动了 4 个 Worker。如果来了 4 个用户做长文本分析,这 4 个 Worker 虽然 CPU 不累,但都处于“占线”状态(Pending)。第 5 个用户想登录,发现没人理他。 - 任务中断风险:用户觉得慢,手滑关掉了浏览器页面。如果是纯 API 连接,连接断开可能导致后端任务取消(浪费了 API 调用的钱)。
- Redis 的作用:“解耦”。
- API 服务器收到请求,0.1秒返回“任务ID”,连接结束。
- Worker 在后台慢慢等 DeepSeek,等 5 分钟都没关系,反正不需要维持 HTTP 连接。
- 用户关掉网页,Worker 依然在跑,结果存入数据库,用户下次回来还能看到。
场景三:流量整形(Traffic Shaping / Rate Limiting)
- 现象:你的 API Key 每分钟只能调用 60 次。突然来了 1000 个用户请求。
- 如果不加 Redis:
- 即使你用了
asyncio.Semaphore,这 1000 个 HTTP 请求也会堆积在你的服务器内存里,消耗大量文件句柄(File Descriptors)和内存。 - 一旦服务器重启,这 1000 个请求全部丢失。
- 即使你用了
- Redis 的作用:“削峰”。
- 1000 个任务瞬间进入 Redis 队列(Redis 每秒能处理 10万+ 写入,毫无压力)。
- 后台 Worker 只有 5 个,它们会慢条斯理地每次取 5 个任务做。
- 结果:用户感觉“排队中”,但系统稳如泰山,绝对不会触发 API 限流报错。
本地跑通Redis
但是我在论文向量化搜索以及LLM精读的时候,就不需要使用Redis,主要在于区分在线任务和离线任务
1. 为什么搜索不适合用 Redis?
(1) 用户体验:即时性 vs. 轮询
- 搜索场景(Search/Rerank):
- 用户在搜索框输入关键词,按回车。
- 心理预期:“马上给我结果”(1-3秒,最多5秒)。
- Asyncio 模式:请求发出去 -> 所有的等待都在 Socket 层 -> 结果直接返回。耗时 = LLM 响应时间。
- Redis 模式:请求 -> 入队 -> Worker 抢单 -> 执行 -> 写入 Redis -> 前端轮询(Polling)
- 前端每隔 1 秒查一次:“好了吗?”
- 这会引入不必要的 轮询延迟。原本 2.1 秒能做完的事,可能因为轮询间隔变成 3.0 秒。
(2) 数据传输开销 (Serialization Overhead)
- 流程对比:
- Asyncio:向量搜出的 20 篇论文对象(Dict)直接在内存里传递给
score_papers_listwise。零拷贝,零开销。 - Redis:你需要把这 20 篇论文(包含摘要、标题等)序列化成 JSON/Pickle -> 通过网络发给 Redis -> Worker 从 Redis 拉取并反序列化。
- 后果:这增加了不必要的 CPU 开销和 Redis 带宽压力。
- Asyncio:向量搜出的 20 篇论文对象(Dict)直接在内存里传递给
(3) 复杂性爆炸
- 如果你把搜索也做成异步 Task,前端逻辑会变得极度复杂:
- 用户点搜索 -> 拿到 Task ID -> 显示加载条 -> 轮询状态 -> 拿到结果列表。
- 对于一个“搜索框”来说,这太重了。
2. 什么时候搜索才需要 Redis?
只有当你的搜索不是普通的 RAG,而是 Deep Research(深度研究) 模式时,才需要 Redis。
对比一下:
| 特征 | 普通搜索 / Rerank (你现在的) | 深度研究 (Deep Research) |
|---|---|---|
| 动作 | 搜向量库 + LLM 给前10名打个分 | 联网搜 Google + 爬取 50 个网页 + 阅读 + 写报告 |
| 耗时 | 1 ~ 5 秒 | 30 秒 ~ 5 分钟 |
| 瓶颈 | LLM API 响应速度 | 网络带宽 + 网页解析 + 多轮 LLM 推理 |
| 架构 | Asyncio (FastAPI 原地处理) | Redis 任务队列 |
| UX | 菊花转圈,直接出结果 | 进度条,分步显示 |
在本地跑通
1 | ~ ▓▒░ sudo service redis-server start ░▒▓ ✔ │ root@gyx │ 19:35:37 |
1 | server Test-NetConnection -ComputerName localhost -Port 6379 |
说明Windows 可以通过 IPv4 (127.0.0.1) 连通 Redis,但无法通过 IPv6 (::1) 连通。
1 | # 探测本地 Redis 是否可用 |
Python 的 aioredis 库解析 "localhost" 时,往往会**优先尝试 IPv6 (::1)**。
所以把所有localhost改成127.0.0.1
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Comments


