Redis缓存那点事儿,性能提升还有那些没说完的细节
- 问答
- 2025-12-28 17:07:47
- 3
上次聊了Redis缓存的基本用法和它能带来的巨大性能提升,但关于它的一些“坑”和更细节的玩法,还有很多没说完的地方,这些东西在实际项目中如果处理不好,性能提升没见到,反而会引来一堆麻烦,咱们接着往下聊。
缓存穿透:防的是“空”
缓存穿透这个词听起来有点玄乎,其实很简单,想象一下,你有一个查询用户信息的接口,正常情况是传入一个用户ID,但如果有人故意使坏,或者程序出了bug,一直用根本不存在用户ID(1,0,或者特别大的负数)来疯狂查询你的系统。
这时候,Redis里肯定没有这个ID对应的数据(因为用户不存在),所以每次请求都会“穿透”Redis缓存,直接打到后面脆弱的数据库上,短时间内海量的这种请求,数据库很可能就扛不住,直接挂掉了。
怎么防呢?有两个常见的土办法:
- 缓存空对象:就算查不到数据,我也在Redis里存一个空值(比如
user_id:-1 -> null),并且给它设置一个很短的过期时间,比如30秒,这样下一个同样的恶意请求过来,Redis就能拦住,直接返回空,不用再去查数据库了,但这样做的缺点是Redis里会多很多没用的键,浪费一点内存。 - 布隆过滤器:这是一个更高级的玩意儿,你可以把它理解成一个放在Redis前面的、非常节省内存的“筛子”,在把数据存入数据库的同时,我把这个数据的ID也放进布隆过滤器里,当有查询请求来时,先让布隆过滤器检查一下这个ID是否存在,如果布隆过滤器说“不存在”,那这个ID肯定不在数据库里,请求直接返回空,根本不用再查缓存和数据库,如果布隆过滤器说“存在”,那这个ID可能存在(有极小的误判率),这时才放行去查缓存/数据库,这个方法非常适合防止恶意攻击。
缓存雪崩:怕的是“
缓存雪崩比缓存穿透更可怕,想象一下,你的系统里有一大批缓存数据,好巧不巧,它们都设置了相同的过期时间,结果在某个时间点,这批缓存“集体失效”了。
这时候,所有原本该走缓存的请求,像雪崩一样瞬间全部涌向了数据库,数据库的压力陡增,很可能瞬间就被压垮了。

解决雪崩的关键在于“错开”。
- 设置不同的过期时间:这是最简单有效的方法,在给缓存数据设置过期时间时,不要都用一样的60分钟,可以在基础时间上加上一个随机的偏移量,比如
60分钟 + 随机0-5分钟,这样就能保证缓存不会在同一时刻大量失效,而是均匀地分布在一段时间内。 - 热点数据永不过期:对于一些极其热门、几乎不会改变的数据(比如省份城市列表),可以设置成永不过期,然后通过后台任务,在数据可能更新时,主动去更新缓存里的内容,这样就彻底避免了因过期导致的雪崩。
缓存击穿:倒霉的“热点”
缓存击穿有点像雪崩,但范围小很多,破坏力却可能很大,它指的是某一个热点数据(比如某个顶流明星的微博信息)过期了,但此时有大量并发请求同时来读取这个数据。
这个热点缓存一失效,大量的请求就像找到了一个突破口,集中火力全部打向数据库,把这个热点数据的查询压力全部转移给了数据库,导致数据库响应变慢甚至崩溃。
对付缓存击穿,常用的办法是“加锁”。

- 分布式锁:当第一个发现缓存失效的请求到来时,它不会立刻去查数据库,而是先在Redis里设置一个特殊的“锁”键,设置成功的那个请求,才有资格去数据库查询数据,并重建缓存,其他并发的请求看到这个“锁”键存在,就会等待一小段时间,然后重试去缓存里读取数据,等第一个请求重建好缓存后,删除“锁”键,所有等待的请求就能从缓存中拿到数据了,这样就保证了只有一个请求会去访问数据库。
数据一致性:这是个难题
用了缓存,就不得不面对一个问题:缓存里的数据和数据库里的数据,如何保持同步?当你更新了数据库后,是先删缓存,还是先更新数据库?这个顺序很有讲究,搞不好就会读到脏数据。
这是一个非常复杂的话题,没有银弹,常见的策略有:
- 先更新数据库,再删除缓存:这是更常用的策略,被称为
Cache-Aside模式,即使删除缓存失败了,也顶多是下次读到旧数据(有一定延迟),但不会造成持久性的数据错误,在极端的并发场景下,也可能出现短暂的不一致。 - 设置短暂的缓存过期时间:给缓存一个不过分长的过期时间,比如1分钟,这样即使出现不一致,也最多持续一分钟,数据最终会保持一致,这是一种用轻微的数据延迟来换取系统简单性和稳定性的权衡。
别把Redis当数据库
最后要提醒一点,虽然Redis性能极高,但千万不要把它当成主力数据库来用,它的主要价值在于“缓存”,即存放临时、热点的数据,所有在Redis里的数据,都应该有数据库作为背后的“靠山”,因为Redis的数据是存在内存里的,虽然有持久化机制(RDB快照和AOF日志),但在极端情况下(比如服务器突然断电且没来得及持久化),仍然有丢失数据的风险,如果你把唯一的数据副本放在Redis里,那将是灾难性的。
Redis是个好东西,但用起来有很多细节要注意,防穿透、防雪崩、防击穿是保证稳定性的关键,而数据一致性则是需要根据业务场景仔细权衡的难题,理解了这些,你才能真正玩转Redis缓存。
本文由畅苗于2025-12-28发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/70148.html
