Flask-Caching 配 Redis 需显式配置 CACHE_TYPE='redis' 及 CACHE_REDIS_URL(如 redis://localhost:6379/1),否则回退默认库0;@cache.cached 仅基于 URL 和查询参数生成 key,POST 或依赖 header/session 时需手动缓存;缓存前应序列化非 JSON 对象(如用 json.dumps(..., default=str));key 应含版本号或哈希以避免语义错配。

Flask-Caching 怎么配 Redis 作为后端
不配对后端,Flask-Caching 默认用内存缓存,进程一重启就全丢,根本没法在生产环境用。Redis 是最常用也最稳妥的选择,但得手动指定 CACHE_TYPE 和连接参数。
常见错误是只写 CACHE_TYPE = 'redis' 就以为完事了——其实 Flask-Caching 2.0+ 默认不自动加载 Redis 连接,必须显式提供 CACHE_REDIS_URL 或拆开写 CACHE_REDIS_HOST/CACHE_REDIS_PORT 等。
-
CACHE_TYPE必须设为'redis'(字符串,不是模块名) - 推荐用
CACHE_REDIS_URL,比如redis://localhost:6379/1,路径末尾的/1指数据库编号,别漏掉 - 如果 Redis 需密码,写成
redis://:mypass@localhost:6379/1;URL 中冒号前空着表示无用户名 - 没配
CACHE_REDIS_URL时,它会 fallback 到localhost:6379,但默认库是 0,容易和别的服务冲突
@cache.cached 怎么用在耗时视图上才真正生效
加了装饰器却没走缓存?大概率是视图函数参数没处理好。@cache.cached 默认按请求 URL + 查询参数生成 key,但如果你的视图依赖 session、header 或 request body(比如 POST 提交 JSON),它压根不感知,缓存 key 完全一样,结果就是“缓存了,但缓存的是错的”。
典型场景:一个计算用户报表的 GET 接口,带 ?user_id=123,没问题;但如果是 POST /report,body 里传 {"start": "2024-01", "mode": "detail"},那必须手动构造 key。
立即学习“Python免费学习笔记(深入)”;
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- GET 请求且参数都在 URL 上,直接
@cache.cached(timeout=300)即可 - 需要基于 request body 或 header 定制 key,用
@cache.cached(timeout=300, key_prefix='report')+ 在函数内手动调用cache.get()/cache.set() - 别在函数里用
request.args.to_dict()拼 key 后再查缓存——@cache.cached的 key 生成逻辑是固定的,改不了;真要细粒度控制,就别用装饰器,改用手动缓存 - timeout 设太长(比如 86400)会导致数据陈旧;设太短(比如 1)又几乎没效果,建议从 60 开始试,看业务容忍度
缓存复杂计算结果时,怎么避免 JSON 序列化失败
Flask-Caching 存进 Redis 的值必须能被序列化,默认用 pickle,但很多对象(比如 SQLAlchemy 模型实例、datetime、自定义类)直接塞进去会报 PicklingError 或 TypeError。
错误现象通常是:TypeError: Object of type datetime is not JSON serializable,或者缓存读出来是 None —— 其实是写入阶段就静默失败了。
- 最稳做法:缓存前先转成 dict 或 JSON 字符串,比如
json.dumps(data, default=str),取出来再json.loads() - 别依赖
cache.set(key, obj)自动序列化,尤其当obj含datetime、Decimal、SQLAlchemy 对象时 - 如果坚持用 pickle(仅限可信内部环境),确保所有被缓存对象都支持 pickle 协议,且部署环境 Python 版本一致,否则反序列化会出错
- Redis 本身不区分类型,
cache.get()返回的就是你set()时给它的原类型——所以存字符串就取字符串,存字典就取字典,别假设它会自动转
本地开发用 Redis 缓存,为什么有时候 key 不更新
开发时改了代码、清了浏览器缓存,但接口返回还是旧结果,大概率是 Redis 里缓存 key 没删干净,或者新请求命中了老 key。
根本原因:key 命名逻辑没随业务变化同步更新。比如一开始按 user_report_123 缓存,后来加了时间范围参数,但 key 还是这个,导致不同时间范围共用一个缓存值。
- 上线新逻辑前,手动执行
redis-cli -n 1 FLUSHDB(注意匹配你用的 db 编号) - 关键缓存 key 建议加入版本号或哈希,比如
f'report_v2_{hash_key}',改逻辑时只动版本号,旧 key 自然失效 - 别用
cache.clear()全局清——它会干掉所有缓存,包括其他视图的,影响面太大 - 开发时打开
app.config['CACHE_KEY_PREFIX'] = 'dev_',和生产环境隔离,避免互相污染
缓存的坑不在配置多难,而在 key 的语义是否和业务严格对齐。一个 key 对应什么数据、何时失效、谁负责清理——这些比选 Redis 还重要。


















