Redis 会话缓存与接口限流
概述
Redis在AI智能体平台中主要承担两个核心职责:
- 会话缓存:多租户会话管理与快速验证
- 接口限流:保护系统不被刷爆
一、会话缓存(Session Cache)
解决什么问题
用户登录后,每次请求都要验证身份。如果每次都查MySQL验证,数据库压力很大。Redis把登录状态存内存,查询极快(微秒级 vs 毫秒级)。
工作流程
用户登录 → 生成Token/SessionId → 存到Redis(key=Token, value=用户信息)→ 返回给前端
后续请求 → 前端带Token → 后端查Redis验证 → 通过继续,不通过踢出
多租户场景下的应用
AI智能体平台支撑1000+租户,每个租户的数据必须隔离:
| 维度 | 实现方式 |
|---|---|
| 会话隔离 | 每个租户一个Redis Key,格式:session:{tenant_id}:{user_id} |
| 上下文存储 | 对话历史存Redis,大模型调用时取出拼接Context |
| 租户配置 | 套餐等级、调用限额、启用功能存Redis Hash |
缓存数据结构设计
# String类型:存简单值
session:tenant_001:user_001 = {name, avatar, plan, quota_left}
# Hash类型:存用户完整画像
user_profile:user_001 = {
tenant_id: "tenant_001",
name: "张三",
plan: "pro",
daily_limit: 600,
used_today: 42
}
# List类型:存对话历史(最新20条)
chat_history:session_001 = [msg1, msg2, msg3, ...]
二、接口限流(Rate Limiting)
解决什么问题
- 防止用户频繁调用接口,保护服务器
- 多租户环境下,按套餐等级分配不同调用额度
- 防止恶意刷接口、爬虫
滑动窗口限流原理
时间窗口:1分钟
限制:免费租户每分钟60次,付费租户600次
Redis Key设计:rate:{tenant_id}:{endpoint}:{window}
Value:时间戳集合(Sorted Set)
每次请求的处理流程:
1. ZREMRANGEBYSCORE key (当前时间 - 窗口时间) 清理过期时间戳
2. ZCARD key 统计当前窗口内请求数
3. 如果 < 限制数:ZADD key 当前时间戳 允许通过
4. 如果 ≥ 限制数:返回429拒绝 限流
5. EXPIRE key 窗口时间 设置过期
多维度限流
| 限流维度 | Key格式 | 说明 |
|---|---|---|
| 用户维度 | rate:user:{user_id} |
每个用户单独计数 |
| 租户维度 | rate:tenant:{tenant_id} |
按套餐等级设定不同阈值 |
| 接口维度 | rate:api:{endpoint} |
AI对话接口限流更严格 |
| IP维度 | rate:ip:{ip_address} |
防止单IP刷接口 |
不同套餐的限流配置
| 套餐 | 限制 |
|---|---|
| 免费版 | 60次/分钟 |
| 专业版 | 600次/分钟 |
| 企业版 | 6000次/分钟 |
限流后的处理
- 返回 HTTP 429 Too Many Requests
- 响应体:
{"error": "rate_limit_exceeded", "retry_after": 30} - 前端显示:"请求太频繁,请30秒后再试"
三、Redis在架构中的位置
用户请求 → 网关 → 限流检查(Redis)→ 会话验证(Redis)→ 业务处理 → 返回
四、为什么选Redis而不是MySQL做限流
| 维度 | MySQL | Redis |
|---|---|---|
| 速度 | 毫秒级 | 微秒级 |
| 原子操作 | 需要事务 | 单命令原子 |
| 集群支持 | 复杂 | 原生支持 |
| 过期自动清理 | 需定时任务 | EXPIRE自动过期 |
| 内存占用 | 高(要建索引) | 低 |
五、常见问题
Q:Redis挂了怎么办?
A:限流降级策略——Redis挂了则限流失效,放行所有请求(比直接拒绝好),同时告警通知运维。
Q:多服务器部署怎么保证限流一致性?
A:Redis集群部署,所有服务器连接同一个Redis,限流计数统一,不存在多服务器不一致的问题。
Q:会话数据丢了怎么办?
A:Session定期持久化到MySQL,Redis故障后可从MySQL恢复。