FastAPI-cache2多用户独立缓存异常:清理Redis缓存后仍生效
问题排查与解决
1. Redis数据库实例不匹配(最可能)
你的清理函数使用的Redis连接是默认数据库(通常是db=0),但FastAPICache初始化时可能指定了不同的Redis数据库编号。比如:
- 初始化FastAPICache时用了
aioredis.from_url("redis://redis:6379/1")(指定db=1) - 清理函数用的是
aioredis.from_url("redis://redis:6379")(默认db=0)
这种情况下,你清理的是db=0的键,但FastAPICache实际使用的db=1里的缓存键还存在,导致路由仍返回旧数据。
解决方法:
确保清理函数使用的Redis数据库与FastAPICache初始化时一致:
async def clear_all_users_keys(user_id: int): # 使用和FastAPICache相同的Redis连接配置,包括db编号 redis = aioredis.from_url("redis://redis:6379/1", encoding="utf8") # 替换为你的实际db编号 keys = await redis.keys(f"{user_id}*") if keys: await redis.delete(*keys) # FastAPICache.clear(key=key) 已包含删除操作,无需重复调用 await redis.close()
2. 用户ID获取逻辑存在隐性问题
虽然你说密钥生成器可正确生成密钥,但切换用户后get_user_id(kwargs)可能没有正确获取到新用户的ID:
- 如果路由中的用户ID是通过依赖注入获取的位置参数,它会出现在
key_builder的args而非kwargs中,此时get_user_id(kwargs)会无法获取到正确值,导致不同用户共用同一个缓存键。
验证方法:
在key_builder中添加日志,打印每次生成的user_id和最终的cache_key,确认切换用户后user_id确实更新:
import logging def key_builder( func, namespace: str = "", *args, **kwargs, ): user_id = get_user_id(kwargs) cache_key = f"{user_id}:{settings.cache_key_prefix}:{func.__module__}:{func.__name__}:{args}:{kwargs}" logging.info(f"Generated cache key for user {user_id}: {cache_key}") return cache_key
如果发现user_id未更新,修改get_user_id函数,同时从args中提取用户ID:
def get_user_id(args, kwargs): # 从args中查找用户ID(假设路由参数中包含user_id) for arg in args: if isinstance(arg, int) and is_valid_user_id(arg): # 根据实际逻辑判断 return arg # 再从kwargs中查找 return kwargs.get("user_id")
3. 客户端缓存干扰
如果切换用户后客户端(如浏览器)仍返回旧数据,可能是客户端开启了缓存。检查路由响应头是否包含Cache-Control等缓存字段,确保服务端返回的响应头禁止客户端缓存:
from fastapi import Response @cache(expire=60) async def your_route(user_id: int, response: Response): response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" response.headers["Pragma"] = "no-cache" response.headers["Expires"] = "0" # 你的路由逻辑
内容的提问来源于stack exchange,提问作者Mihail Poritskii
相关产品推荐
相关产品推荐

