本文将介绍如何使用 FastAPI 异步访问 Redis,包括环境配置、连接创建、数据库初始化、增删查改操作、键过期、管道(pipeline)操作以及事务管理等内容。
环境准备
首先,我们需要安装必要的依赖包。Redis 是一个键值存储系统,而 aioredis
是一个支持异步访问 Redis 的 Python 客户端库。你可以使用以下命令安装 FastAPI、Uvicorn 和 aioredis:
bash
pip install fastapi
pip install uvicorn
pip install aioredis
在安装完成后,我们就可以开始编写代码了。
1. 配置 Redis 连接
首先,确保你已经安装并启动了 Redis 服务。可以通过以下命令启动 Redis:
bash
redis-server
然后,我们创建一个 Redis 连接。为了支持异步操作,我们使用 aioredis
包。
python
import aioredis
# 配置 Redis 连接
REDIS_URL = "redis://localhost:6379"
# 创建 Redis 连接
async def get_redis_connection():
redis = await aioredis.from_url(REDIS_URL, encoding="utf-8", decode_responses=True)
return redis
我们通过 aioredis.from_url
方法创建了一个 Redis 连接,它允许我们直接从指定的 Redis 服务 URL 中连接 Redis 服务器,并且设置编码和解码格式为 UTF-8,以便处理字符串数据。
2. FastAPI 实例化和数据库初始化
在 FastAPI 中,我们使用 Depends
依赖注入机制来获取 Redis 连接。通过 on_startup
事件,我们可以在 FastAPI 启动时进行一些初始化操作,如测试 Redis 连接。
python
from fastapi import FastAPI, Depends
app = FastAPI()
# 获取 Redis 连接
async def get_db():
redis = await get_redis_connection()
try:
yield redis
finally:
await redis.close()
# 在应用启动时初始化 Redis 连接
@app.on_event("startup")
async def on_startup():
redis = await get_redis_connection()
print("Redis connection initialized")
await redis.close()
3. 数据库的增删查改操作(CRUD)
我们现在将实现一些常见的 Redis 操作,如增、删、查、改。
创建/设置数据
我们使用 Redis 的 set
命令来设置键值对。为了简化操作,我们将设置数据的函数定义为一个 POST 请求:
python
from fastapi import HTTPException
@app.post("/set/{key}/{value}")
async def set_key(key: str, value: str, redis: aioredis.Redis = Depends(get_db)):
try:
await redis.set(key, value) # 设置键值对
return {"message": "Key set successfully"}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
await redis.set(key, value)
:在 Redis 中设置键值对。
获取数据
我们使用 Redis 的 get
命令来获取数据。通过 GET 请求来查询某个键的值:
python
@app.get("/get/{key}")
async def get_key(key: str, redis: aioredis.Redis = Depends(get_db)):
value = await redis.get(key) # 获取键对应的值
if value is None:
raise HTTPException(status_code=404, detail="Key not found")
return {"key": key, "value": value}
await redis.get(key)
:获取指定键的值,如果键不存在,则返回None
。
更新数据
Redis 是一个键值存储系统,我们可以通过 set
命令更新已经存在的键值对。如果键存在,值将被更新;如果不存在,则会创建新的键值对。
python
@app.put("/update/{key}/{value}")
async def update_key(key: str, value: str, redis: aioredis.Redis = Depends(get_db)):
exists = await redis.exists(key)
if not exists:
raise HTTPException(status_code=404, detail="Key not found")
await redis.set(key, value) # 更新键值对
return {"message": "Key updated successfully"}
await redis.exists(key)
:检查键是否存在。
删除数据
我们使用 Redis 的 delete
命令删除指定的键:
python
@app.delete("/delete/{key}")
async def delete_key(key: str, redis: aioredis.Redis = Depends(get_db)):
result = await redis.delete(key) # 删除指定键
if result == 0:
raise HTTPException(status_code=404, detail="Key not found")
return {"message": "Key deleted successfully"}
await redis.delete(key)
:删除指定的键,返回删除的键数量。
4. 设置键的过期时间
Redis 提供了 expire
命令来设置键的过期时间。通过 EX
参数,我们可以设置键的过期时间为秒数,或者通过 PX
设置毫秒。
python
@app.post("/set_with_expiration/{key}/{value}/{expiration}")
async def set_key_with_expiration(key: str, value: str, expiration: int, redis: aioredis.Redis = Depends(get_db)):
await redis.set(key, value, ex=expiration) # 设置过期时间
return {"message": f"Key will expire in {expiration} seconds"}
ex=expiration
:设置键的过期时间为expiration
秒。
5. 使用管道(Pipeline)
Redis 提供了管道(Pipeline)功能,可以将多个命令打包成一个批量请求发送,提高性能。以下是一个使用管道操作多个键值的示例:
python
@app.post("/set_multiple/{key}/{value}")
async def set_multiple_keys(key: str, value: str, redis: aioredis.Redis = Depends(get_db)):
async with redis.pipeline() as pipe:
for i in range(1, 6):
await pipe.set(f"{key}_{i}", f"{value}_{i}")
await pipe.execute() # 执行管道中的所有命令
return {"message": "Multiple keys set successfully"}
async with redis.pipeline()
:创建一个 Redis 管道。await pipe.set(f"{key}_{i}", f"{value}_{i}")
:向管道中添加多个设置命令。await pipe.execute()
:执行管道中的所有命令。
6. Redis 事务管理
Redis 本身支持事务机制。通过管道,我们可以执行事务。管道可以保证所有命令一起执行,要么全部成功,要么全部失败。
python
@app.post("/transaction/{key}/{value}")
async def redis_transaction(key: str, value: str, redis: aioredis.Redis = Depends(get_db)):
async with redis.pipeline() as pipe:
await pipe.set(key, value)
await pipe.expire(key, 60) # 设置过期时间为60秒
await pipe.execute() # 执行所有命令
return {"message": "Transaction executed successfully"}
async with redis.pipeline()
:开始一个事务。await pipe.set(key, value)
:设置键值对。await pipe.expire(key, 60)
:设置键的过期时间。await pipe.execute()
:执行事务。
完整代码示例
python
from fastapi import FastAPI, HTTPException, Depends
import aioredis
app = FastAPI()
REDIS_URL = "redis://localhost:6379"
# 获取 Redis 连接
async def get_db():
redis = await aioredis.from_url(REDIS_URL, encoding="utf-8", decode_responses=True)
try:
yield redis
finally:
await redis.close()
# 初始化 Redis 连接
@app.on_event("startup")
async def on_startup():
redis = await get_db()
print("Redis connection initialized")
await redis.close()
# 设置数据
@app.post("/set/{key}/{value}")
async def set_key(key: str, value: str, redis: aioredis.Redis = Depends(get_db)):
await redis.set(key, value)
return {"message": "Key set successfully"}
# 获取数据
@app.get("/get/{key}")
async def get_key(key: str, redis: aioredis.Redis = Depends(get_db)):
value = await redis.get(key)
if value is None:
raise HTTPException(status_code=404, detail="Key not found")
return {"key": key, "value": value}
# 更新数据
@app.put("/update/{key}/{value}")
async def update_key(key: str, value: str, redis: aioredis.Redis = Depends(get_db)):
exists = await redis.exists(key)
if not exists:
raise HTTPException(status_code=404, detail="Key not found")
await redis.set(key, value)
return {"message": "Key updated successfully"}
# 删除数据
@app.delete("/delete/{key}")
async def delete_key(key: str, redis: aioredis.Redis = Depends(get_db)):
result = await redis.delete(key)
if result == 0:
raise HTTPException(status_code=404, detail="Key not found")
return {"message": "Key deleted successfully"}
# 设置过期时间
@app.post("/set_with_expiration/{key}/{value}/{expiration}")
async def set_key_with_expiration(key: str, value: str, expiration: int, redis: aioredis.Redis = Depends(get_db)):
await redis.set(key, value, ex=expiration)
return {"message": f"Key will expire in {expiration} seconds"}
# 使用管道操作
@app.post("/set_multiple/{key}/{value}")
async def set_multiple_keys(key: str, value: str, redis: aioredis.Redis = Depends(get_db)):
async with redis.pipeline() as pipe:
for i in range(1, 6):
await pipe.set(f"{key}_{i}", f"{value}_{i}")
await pipe.execute()
return {"message": "Multiple keys set successfully"}
# Redis 事务
@app.post("/transaction/{key}/{value}")
async def redis_transaction(key: str, value: str, redis: aioredis.Redis = Depends(get_db)):
async with redis.pipeline() as pipe:
await pipe.set(key, value)
await pipe.expire(key, 60)
await pipe.execute()
return {"message": "Transaction executed successfully"}
总结
本文详细介绍了如何在 FastAPI 中使用异步方式访问 Redis,包括 Redis 连接的创建、数据的增删查改、键过期、使用管道操作和事务管理等内容。通过使用 aioredis
库,结合 FastAPI 提供的异步支持,可以高效地处理缓存数据,提升系统性能。希望本文对你在项目中使用 Redis 提供了帮助。