用Redis缓存高频查询结果可将响应从几十毫秒降至1毫秒内,关键点:键带业务前缀如user:profile:12345、设合理过期时间(如30分钟)、更新DB时先删缓存再操作并延时双删防脏读。

用Redis缓存高频查询结果,减少数据库压力
很多Web接口响应慢,根源不在代码逻辑,而在反复查数据库。比如用户个人资料页每次访问都查一次MySQL,QPS上去后数据库就成瓶颈。把这类稳定、读多写少的数据(如用户基础信息、配置项、热门商品列表)缓存到Redis里,能直接跳过DB,响应从几十毫秒降到1毫秒内。
关键点有三个:缓存键设计要带业务前缀和唯一标识(如red">user:profile:12345),避免冲突;设置合理过期时间(比如30分钟),防止数据长期不一致;更新数据库时同步删或更新对应缓存(推荐“先删缓存,再更DB”,配合延时双删防脏读)。
利用Redis原子操作实现计数与限流
点赞数、阅读量、接口调用频次这些场景,不适合每次请求都去DB update,容易产生并发覆盖或锁表。Redis的INCR、DECR、EXPIRE组合就能安全高效搞定。
例如统计某文章阅读量:
– 请求进来先执行 INCR article:views:789
– 同时用 EXPIRE article:views:789 86400 设置一天过期(防内存堆积)
– 每小时异步把Redis里的值批量回写到MySQL做持久化即可
限流也类似,用INCR + EXPIRE实现滑动窗口,比如限制用户每分钟最多调用10次API:键设为rate:limit:user_6789:20240520_14(含分钟级时间戳),每次INCR后检查值是否超限。
立即学习“Python免费学习笔记(深入)”;
序列化选型与连接管理直接影响性能
Python连Redis默认用redis-py,但默认序列化是字符串,传复杂结构(如字典、列表)得自己json.dumps/json.loads,既啰嗦又慢。建议统一用msgpack——体积比JSON小30%~50%,序列化/反序列化速度快2~5倍,且天然支持bytes、datetime等类型。
连接不能每次请求都新建:
– 用ConnectionPool复用连接,设置max_connections=20防耗尽
– Flask/FastAPI中初始化一次pool,全局复用
– 避免用redis.Redis(host=...)这种短连接写法
缓存穿透、雪崩、击穿不是理论问题,得提前防
真实线上环境这三类问题天天发生:
- 穿透:恶意查大量不存在的ID(如user:profile:-123456),缓存没命中,请求全打到DB。解决方案:对空结果也缓存(如set user:profile:999999 "null" ex 60),或用布隆过滤器前置拦截
- 雪崩:大量key在同一时刻过期,缓存集体失效,流量瞬间压垮DB。对策:过期时间加随机偏移(如 ex 3600 + random(0, 300)),或用永不过期+后台异步更新value
- 击穿:单个热点key(如首页banner)过期瞬间被高并发请求同时重建。用Redis分布式锁(SET key value EX 10 NX)或本地互斥锁(如functools.lru_cache)控制重建入口
不复杂但容易忽略。











