一、前言
在高并发、高流量的业务场景中,数据库的IO性能往往是系统的最大瓶颈。传统数据库基于磁盘读写,无法支撑海量高频的查询请求,而Redis基于内存运行、读写速度极快。
二、缓存基础认知
2.1 什么是缓存?
缓存是位于数据源头(数据库)与业务服务之间的高速临时存储层,核心思想是利用空间换时间。将高频查询、低频变更的热点数据提前存储在内存中,用户请求优先读取缓存,避免频繁查询磁盘数据库,大幅提升接口响应速度、降低数据库压力。
2.2 为什么选择Redis做缓存?
1,高性能:纯内存操作,单机QPS可达10W+,毫秒级响应
2,分布式共享:多服务实例可共享缓存数据,解决本地缓存数据不一致问题
3,丰富数据结构:支持String、Hash、List、ZSet等,适配各类缓存场景
4,持久化机制:支持RDB/AOF持久化,避免断电数据丢失
5,高可用:支持主从同步、哨兵、集群部署,保障缓存服务的稳定
三、Redis缓存核心工作模式
3.1 读流程
-
客户端发起查询请求,服务优先查询Redis缓存
-
缓存命中:直接返回缓存数据,无需操作数据库
-
缓存未命中:查询数据库,将结果写入Redis,再返回数据给客户端
3.2 写流程
业务更新数据时,优先更新数据库,再删除缓存,防止数据不一致问题。不推荐更新缓存,避免无效缓存更新、缓存脏数据堆积。
-
客户端发起数据更新/删除请求
-
更新对应数据库数据
-
删除Redis中对应的旧缓存数据
-
下次查询自动从DB加载最新数据,刷新缓存
3.3 缓存过期与淘汰机制
3.3.1 TTL过期机制
所有业务缓存必须设置过期时间,避免缓存无限堆积、内存溢出。不同场景适配不同过期时间,Redis采用惰性删除+定期删除结合的方式清理数据。
3.3.2 内存淘汰策略
通用的淘汰策略也就一下四种:
1,FIFO(先进先出)
把缓存中存在时间最久的(最先来的数据)淘汰掉
2,LRU(淘汰最久未使用的)
记录每个key的最近访问时间,把最近访问时间最老的key给淘汰掉
3,LFU(访问次最少的)
记录每个key最近一段时间的访问次数,把访问次数最少的key给淘汰掉
4,random(随机淘汰)
在所有key中随机进行淘汰
reids也内置了几种淘汰策略,当达到配置文件中的maxmemory时进行淘汰

四、Redis缓存三大经典问题及解决方案
5.1 缓存穿透
问题描述:访问的key在redis和数据库中都不存在,因此这样的数据就永远不会被放到缓存上,缓存永久为空,后续请求直接访问数据库,数据库承担请求太多,压力变大。
导致原因:数据库数据被误删,缺少参数校验环节,导致使用非法的key查询数据库
解决方案:
1,空值缓存:查询为空时,缓存空数据,设置短期过期时间,避免频繁访问数据库
2,使用布隆过滤器:提前过滤不存在的key,拦截非法请求
3,校验参数的合法性
5.2 缓存击穿
问题描述:单个热点key缓存过期瞬间,海量并发请求同时打到数据库,瞬时压垮数据库。
解决方案:
1,使用分布式锁,保证同一时间只有一个请求查询数据库、刷新缓存,限制同时请求数据库的并发数。热点key过期之后,请求查询redis未命中时,使用
2,针对热点key设置永不过期,适合更新频率低的key
5.3 缓存雪崩
问题描述:大量缓存key同时过期 / Redis宕机,所有请求全部访问数据库,导致数据库雪崩瘫痪。
解决方案:
1,对key的过期时间加随机值:避免批量key同时过期
2,Redis高可用部署:主从+哨兵/集群,避免单点故障,导致大量key同时失效
3,服务降级:缓存失效时,限流降级,保护数据库
4,多级缓存:服务器本地缓存+Redis分布式缓存,双层兜底
五、Redis缓存最佳实践总结
-
能缓存则缓存:高频查询、低频变更数据优先缓存,减少数据库压力
-
必设过期时间:所有业务缓存配置TTL(缓存过期时间),杜绝内存泄漏
-
统一读写策略:读走旁路缓存,写先DB后删缓存
-
做好三大问题防护:穿透、击穿、雪崩提前兜底防护
-
规范key与序列化:统一开发规范,便于维护排查
-
高可用兜底:集群部署+多级缓存+熔断降级,保障服务稳定