目录
[1. 节省内存,防止数据堆积](#1. 节省内存,防止数据堆积)
[2. 保证数据时效性](#2. 保证数据时效性)
[3. 模拟会话(Session)行为](#3. 模拟会话(Session)行为)
[4. 无需手动维护清理任务](#4. 无需手动维护清理任务)
[5. 典型应用场景](#5. 典型应用场景)
[Python 操作 Redis](#Python 操作 Redis)
[FastAPI + Redis 简单实战](#FastAPI + Redis 简单实战)
[考察:用 Redis 缓存 API 结果,提升性能。](#考察:用 Redis 缓存 API 结果,提升性能。)
参考资料:
Redis介绍:
与MySQL数据库不同,MySQL数据库有表、有字段、有记录,Redis没有这些东西,就是一个名称对应一个值,并且数据以存储在内存中使用为主。
Redis自身并不是为了数据持久化而生的,主要是在内存中保存数据,加速数据访问的。
Redis在AI Infra 里作用:
- 缓存大模型对话历史(用户和 AI 聊的内容存在 Redis,避免重复发送给模型)
- 缓存 Embedding 向量(文档转成的向量存在 Redis,下次查询直接用,省 GPU 钱)
- 缓存热点数据(比如频繁访问的模型配置、用户信息)
- 接口限流(防止模型被恶意调用刷爆)
Redis 中设置过期时间(TTL) 的核心作用是自动管理数据生命周期,具体到 AI 服务场景有以下关键用途:
1. 节省内存,防止数据堆积
对话历史、临时缓存等数据如果不删除,会无限占用 Redis 内存。设置过期时间(如 1 小时)后,数据到期自动释放,避免 OOM(内存溢出)。
2. 保证数据时效性
AI 对话通常只需保留最近一段时间(如 1 小时)的上下文。过期机制自动淘汰陈旧数据,防止模型读到过时的用户问题或已失效的配置。
3. 模拟会话(Session)行为
就像 Web 应用的 Session 过期一样,用户对话无活动一段时间后,Redis 自动清除该会话的历史记录,下次用户访问会重新开始。
4. 无需手动维护清理任务
不需要写定时任务或后台脚本来扫描删除过期键,Redis 内部惰性删除 + 定期删除自动完成,简化代码逻辑。
5. 典型应用场景
-
限流计数器 :
expire(rate_limit_key, 60)让计数器每分钟自动重置。 -
临时授权码:验证码 5 分钟失效。
-
缓存 Embedding 向量:模型更新后,旧向量自动过期。
Python 操作 Redis
安装依赖:
python
pip install redis
string和hash操作
python
import redis
# 连接(decode_responses=True 让返回值是字符串,不是字节)
r=redis.Redis(host='localhost',port=6379,db=0,decode_responses=True)
# string操作
# 缓存模型配置
r.set("model:default","qwen-7b")
print(r.get("model:default"))
# 统计接口调用次数
r.set("api:call_count",0)
r.incr("api:call_count")#自增1
print(r.get("api:call_count"))
# hash操作
user_id="user_001"
conversation_key=f"conversation:{user_id}"
r.hset(conversation_key,mapping={
"user_question": "Redis 在 AI 服务里有什么用?",
"ai_answer": "缓存对话历史、Embedding 向量、接口限流...",
"timestamp": "2024-07-22 10:00:00"
})
#取对话
print(r.hgetall(conversation_key))
# 设置过期时间
r.expire(conversation_key,3600)
FastAPI + Redis 简单 实战
考察:用 Redis 缓存 API 结果,提升性能。
python
from fastapi import FastAPI
import redis
import time
import hashlib
app=FastAPI()
r=redis.Redis(host='localhost',port=6379,db=0,decode_responses=True)
# 模拟大模型生成回答的耗时操作
def generate_answer(question:str)->str:
time.sleep(2)
return f"AI 回答:{question}的答案。。。"
# 带ai缓存的ai回答接口
@app.get("/ai/ask/{question}")
def ask_ai(question:str):
# 生成缓存key(问题的MD5作为唯一标识)
cache_key=f"ai_answer:{hashlib.md5(question.encode()).hexdigest()}"
# 先查缓存
cache_answer=r.get(cache_key)
if cache_answer:
return{
"answer": cache_answer,
"source": "redis_cache", # 来源:缓存
"time": "0001s"
}
# 缓存没命中,调用大模型
start_time=time.time()
answer=generate_answer(question)
end_time=time.time()
# 把 AI 生成的答案,先存到 Redis 里,并且只保存 10 分钟。10 分钟后,自动删除。
r.set(cache_key,answer,ex=600)
return{
"answer": answer,
"source": "model_generated", # 来源:大模型
"time": f"{end_time - start_time:.3f}s"
}
启动:
用于启动 Uvicorn 服务器的命令,通常用来运行 FastAPI 或任何 ASGI 应用程序
python
uvicorn curd2:app --reload
| 部分 | 含义 |
|---|---|
uvicorn |
ASGI 服务器(支持异步 Python Web 框架,如 FastAPI、Starlette) |
curd2:app |
告诉 Uvicorn 去curd2.py 文件中寻找名为 app 的 ASGI 应用对象(通常是 FastAPI() 实例) |
--reload |
开启自动重载模式:代码文件修改后,服务器会自动重启,无需手动停止再启动(开发时非常方便)仅在开发环境使用,生产环境不会加此参数(因为会浪费资源且不够稳定) |
测试:
第一次访问:http:127.0.0.1:8000/ai/ask/提示信息

立即再次访问同一问题

实战项目
核心逻辑(高频框架):
-
客户端请求用户信息
-
先查 Redis 缓存
-
有数据 → 直接返回(极速)
-
无数据 → 查询 MySQL
-
查到数据 → 写入 Redis 缓存,设置过期时间
-
无数据 → 返回 404
python
from fastapi import FastAPI,HTTPException
from sqlalchemy import create_engine,Column,Integer,String,DateTime
from sqlalchemy.orm import declarative_base,sessionmaker
from datetime import datetime
import redis
mysql_url="mysql+pymysql://root:123456@localhost:3306/ai_infra"
# pool_pre_ping=True是否是后连接,扔掉死连接,创建活连接
engine=create_engine(mysql_url,pool_pre_ping=True)
# 创建会话:关闭自动提交, 不自动把临时数据同步到数据库,告诉会话要绑定到哪个数据库
SessionLocal=sessionmaker(autocommit=False,autoflush=False,bind=engine)
Base=declarative_base()
# redis配置
redis_client=redis.Redis(
host="localhost",
port=6379,
db=0,
decode_response=True
)
# FastApi实例
app=FastAPI(title="缓存未命中回写")
# 数据库模型
class User(Base):
__tablename__="user" #给 Python 类绑定 MySQL 表名
id=Column(Integer,primary_key=True,index=True)
username=Column(String(50),unique=True,nullable=False)
age=Column(Integer)
create_time=Column(DateTime,default=datetime.now)
# 不存在则自动建
Base.metadata.create.all(bind=engine)
# 数据库会话工具
def get_db():
db=SessionLocal()
try:
yield db
finally:
db.close()
# 缓存+数据库
@app.get("/api/user/{username}")
def get_user_info(username:str):
cache_key=f"user:info:{username}"
# 1.查询redis缓存
cache_data=redis_client.hgetall(cache_key)
if cache_data:
return{
"code": 200,
"msg": "缓存命中",
"data": cache_data,
"source": "Redis缓存"
}
# 2.缓存未命中,查询mysql
db=next(get_db())
user=db.query(User).filter(User.username==username).first()
if not user:
raise HTTPException(status_code=404,detail="用户不存在")
# 3.数据库数据写入Redis,设置缓存过期时间10分钟
user_dict={
"id":user.id,
"username":user.username,
"age":user.age
}
redis_client.hset(cache_key,mapping=user_dict)
redis_client.exprie(cache_key,600)
return {
"code":200,
"msg":"数据库查询成功",
"data":user_dict,
"source":"mysql数据库"
}
# 新增用户的接口
@app.post("/api/user/add")
def add_user(username:str,age:int,db=next(get_db())):
# 判断是否存在用户
exist_user=db.query(User).filter(User.username==username).first()
if exist_user:
raise HTTPException(status_code=400,detail="该用户名已经存在")
new_user=User(username=username,age=age)
db.add(new_user)
db.commit()
return {
"code":200,
"msg":"创建成功",
"username":"username"
}
测试
0.本地必须启动:MySQL 服务(根据引擎中的数据库信息创建数据库)、Redis 服务

终端启动服务,启动成功后

打开自动接口文档:http://127.0.0.1.800/docs
1.先调用/api/user/add 添加用户"偏偏意气用事"

2.再次添加,检查"判断是否存在"

3.调用/api/user/add第一次查用户:来源 = MySQL

4.第二次重复查询:来源 = Redis 缓存

5.查询用户名"不想睡觉",无数据 → 返回 404
