29.Redis在大模型应用中有哪些用途缓存会话与限流

Redis 在大模型应用中有哪些用途?缓存、会话与限流

码海寻道 · 大模型、智能体与 RAG 工程组件系列第 29 篇

大模型应用通常比普通 CRUD 服务更容易遇到高延迟、高成本和突发流量:一次回答可能要调用 Embedding、向量数据库、Reranker 和大模型。Redis 可以把热点数据、会话状态和限流计数放到内存中,减少重复计算并保护后端服务。

Redis 在这里更像"加速器和保护层",不是 PostgreSQL、对象存储或 Milvus 的事实源。缓存键必须包含租户、用户、模型、知识库版本和权限范围等影响结果的维度,否则很容易把一个用户的结果返回给另一个用户。

一、Redis 在架构中的位置

text 复制代码
用户请求
   ↓
API 服务
   ├── Redis:缓存、会话、限流、短期状态
   ├── PostgreSQL:业务事实和审计
   ├── Milvus:向量检索
   └── 大模型 API:生成答案

Redis 不是 PostgreSQL 的永久替代品,也不是消息队列、对象存储和向量数据库的万能替代品。它适合保存可以快速读取、允许设置过期时间或需要高并发访问的数据。

二、用途一:缓存 Embedding 和检索结果

相同问题或相同文档内容可能被重复处理,可以缓存:

  • 文本的 Embedding;
  • 问题改写结果;
  • RAG 召回结果;
  • 热门问题的最终答案;
  • 模型配置和权限范围的短期结果。

缓存键必须包含影响结果的关键信息:

text 复制代码
rag:answer:{tenant_id}:{knowledge_version}:{model_version}:{query_hash}

如果只使用问题文本作为 Key,知识库更新、租户切换或模型升级后可能返回旧答案。

三、Cache-Aside 基本模式

python 复制代码
value = redis.get(cache_key)
if value is not None:
    return json.loads(value)

value = expensive_rag_query()
redis.set(cache_key, json.dumps(value), ex=300)
return value

缓存未命中时读取真实数据,再写入 Redis。生产实现还要处理并发击穿、异常不缓存、序列化版本和缓存大小。

四、用途二:保存会话和短期记忆

HTTP 请求本身无状态,多实例部署时不能把会话只放在某个应用进程内。Redis 可以保存:

  • 登录会话和 Token 状态;
  • 多轮对话的最近消息;
  • Agent 当前执行上下文;
  • 文件解析任务的临时状态;
  • 短期用户偏好。

示例:

python 复制代码
redis.hset(
    f"chat:session:{session_id}",
    mapping={
        "user_id": user_id,
        "messages": json.dumps(messages, ensure_ascii=False),
    },
)
redis.expire(f"chat:session:{session_id}", 3600)

对话历史不应无限增长。应设置消息数量、Token 预算和过期时间,长期记忆则应经过筛选后进入 PostgreSQL 或专门的记忆存储。

五、用途三:接口限流

大模型调用成本高,必须防止单个用户、租户或 IP 突发消耗资源。Redis 适合实现固定窗口、滑动窗口和令牌桶等限流算法。

一个简单的固定窗口示例:

python 复制代码
key = f"rate:{tenant_id}:{int(time.time()) // 60}"
count = redis.incr(key)
if count == 1:
    redis.expire(key, 60)
if count > 100:
    raise TooManyRequests()

这个示例容易理解,但窗口边界可能出现突刺。严格限流应使用 Lua 脚本或成熟组件保证计数与过期设置的原子性。

六、缓存一致性怎么处理?

缓存最大的问题不是读不到,而是读到旧数据。常见策略:

TTL

让缓存自动过期,适合可接受短暂陈旧的结果。

主动删除

文档发布、权限变化或模型升级时删除相关 Key。

版本化 Key

把知识库版本和模型版本放入 Key,让新版本自然使用新缓存。

事件失效

业务数据变化时发布事件,由缓存消费者删除或刷新对应 Key。

对于 RAG 结果缓存,推荐把知识库版本放进 Key:

text 复制代码
rag:{tenant_id}:{kb_id}:{serving_version}:{query_hash}:{model_version}

文档发布时切换 serving_version,新请求自然使用新 Key,旧缓存可以异步过期。不要只依赖删除所有旧 Key,因为大规模模糊删除可能阻塞 Redis 或误删其他租户数据。

七、缓存穿透、击穿和雪崩

穿透

请求查询一个根本不存在的数据。可以缓存空结果,但要设置较短 TTL,并防止用户输入直接构造任意 Key。

击穿

热点 Key 同时过期,大量请求一起访问后端。可以使用互斥锁、单飞机制或提前刷新。

雪崩

大量 Key 在同一时间过期。设置 TTL 随机抖动,并分批预热和删除。

八、Redis 不是最终事实来源

以下数据不要只存 Redis:

  • 账单和计费记录;
  • 审计日志;
  • 文档发布状态;
  • 权限策略;
  • 不可恢复的任务结果。

还要明确 Redis 故障时的降级路径:Embedding 缓存失效后重新计算,检索缓存失效后回源 Milvus/pgvector,会话缓存失效后从 PostgreSQL 恢复或要求重新建立会话。降级逻辑应设置超时和并发上限,避免 Redis 故障把压力瞬间传导给所有下游。

Redis 可以保存访问加速所需的副本,但关键事实仍应写入持久化数据库或对象存储。

九、上线检查清单

  • Key 包含租户、版本和模型等必要维度;
  • 所有缓存都有合理 TTL 或失效策略;
  • 缓存命中不会绕过权限校验;
  • 限流计数具有原子性;
  • 大对象不会无限写入 Redis;
  • Redis 故障时有降级或明确失败策略;
  • 关键数据不会只存在 Redis;
  • 监控命中率、内存、连接数和淘汰数量。
  • 已设置最大内存、淘汰策略和高峰期降级方案;
  • Redis Streams 若承载任务,已设计 ACK、Pending 和重领机制;

结语

Redis 在大模型应用中最常见的角色是"加速器和保护层":缓存减少重复调用,会话支撑多实例协作,限流控制成本和风险。真正可靠的设计,还要同时考虑失效、一致性、降级和持久化事实来源。

下一篇将讨论 RAG 原始文件应该放在哪里,以及 MinIO、S3 和 OSS 的职责差异。

参考资料

  1. Redis 官方文档:Data Types
  2. Redis 官方文档:Use Cases
  3. Redis 官方文档:Session Store
  4. Redis 官方文档:Key Eviction

本文为"码海寻道"原创技术文章。缓存策略需要结合业务数据新鲜度、成本和故障降级要求设计。

相关推荐
DP DPharness1 小时前
装完看不到模型?dsh-commandcode-provider 排错速查
人工智能·dpharness
天国梦1 小时前
哪个英语教学软件功能比较全面?我按五个维度拆了一遍
人工智能·机器学习
写后端的胖头鱼1 小时前
【高频面试题】FullText 全文索引(MySQL)
数据库·mysql·索引·全文索引
tomlone1 小时前
AI 实践:OpenClaw + 本地 Ollama + Qwen3.5
人工智能·自然语言处理·ai写作
盘古开天16661 小时前
windows鱼塘可交互鱼群动态桌面资源
人工智能·chatgpt·开源
路远的数据库笔记1 小时前
SQL Server迁移国产数据库怎么做?九套口岸库零停机割接实战
数据库·经验分享·sqlserver·dba
樱花落木兰1 小时前
分布式登录实战:Session 会话共享改造,Redis 存储用户登录状态
java·javascript·数据库·redis·分布式·缓存
kaiyou20262 小时前
用户研究岗秋招,统计分析能力怎么学习和证明?
数据库·python·学习
零基础1232 小时前
Agentic Identity:智能体身份识别的核心技术、应用场景与实践指南
人工智能