Redis落地那些事儿,怎么更高效用缓存模式来玩转数据存储
- 问答
- 2026-01-16 18:37:17
- 3
网络技术社区、博客园“程序员小灰”部分观点、以及《凤凰架构》一书中关于缓存模式的讨论)
Redis落地那些事儿,怎么更高效用缓存模式来玩转数据存储
直接用Redis,很多人觉得不就是读的时候先查缓存,缓存没有就查数据库然后塞回去,写的时候更新数据库再删缓存嘛,听起来简单,但真用起来,尤其是在用户量大、并发高的场景里,坑多得能让你怀疑人生,咱们今天就聊点实在的,怎么用几种常见的“套路”,也就是缓存模式,来更聪明、更稳妥地玩转Redis,而不是被它玩。
最基础的模式叫缓存旁路(Cache-Aside),这个模式就是你程序自己当家作主,完全掌控缓存和数据库,读操作:先问Redis要数据,有就直接返回(这叫缓存命中),没有(这叫缓存未命中),就去数据库里捞,捞出来之后,顺手塞一份到Redis里,下次就能命中了,写操作呢,直接更新数据库,注意了,是删除Redis里对应的缓存数据,而不是更新它,为啥是删不是更新?主要是为了避免数据不一致的麻烦,比如两个线程同时写,可能A线程先更新了数据库,B线程后更新了数据库,但B线程却先写入了缓存,A线程后写入缓存,结果缓存里存的是A线程的旧数据,直接删掉,下次读的时候自然就会从数据库加载最新的数据,这个模式简单直接,但有个小缺点,就是每次缓存未命中时,那个请求会稍微慢一点,因为它得等数据库返回。
当缓存里没数据,瞬间又来了超级多的请求同时去读同一个数据,这下好了,所有请求都发现缓存是空的,然后齐刷刷地冲向数据库,数据库压力陡增,严重的时候可能直接就挂掉了,这就是著名的缓存击穿问题,对付它,有个模式叫互斥锁(Mutex Key),思路很简单:当第一个发现缓存失效的请求来了,它不是在Redis里放数据,而是放一个特殊的“锁”(比如一个有过期时间的key),然后这个请求自己去数据库加载数据,其他请求再来的时候,发现这个“锁”存在,就知道已经有兄弟在加载数据了,它们就不去查数据库了,而是乖乖等待一小会儿(比如睡眠几毫秒),然后重新去缓存里查数据,等第一个请求把数据加载到缓存后,再删掉那个“锁”,这样就能避免数据库被重复查询打垮,不过这个方法有点复杂,要处理锁的获取和释放。
还有个更简单粗暴对付缓存击穿的方法,叫逻辑过期,这个思路来源于一些技术博客的分享,我们存到Redis里的数据,不直接设置Redis自带的有效期,而是在数据值里面自己加一个字段来表示过期时间,当读请求来时,即使从Redis里拿到了数据,程序也会检查一下这个自定义的过期时间,如果数据还没逻辑过期,直接返回,如果已经逻辑过期了,程序不会立马去查数据库,而是像互斥锁模式一样,先尝试在Redis里设一个“锁”,设成功了,说明我是第一个发现过期的,那我就另起一个线程(或异步任务)去数据库拉取新数据更新缓存,而当前请求呢,先把那个已经逻辑过期的旧数据返回给用户,虽然这会儿数据可能不是最新的,但总比报错或者让用户一直等着强,其他请求发现“锁”已经存在,就知道有更新任务在进行中了,它们也直接返回旧数据,这个方法用了一定的数据延迟,换来了系统的高可用性,适合对一致性要求不是那么极致的场景。
再说说写操作,缓存旁路模式是更新数据库后删除缓存,但如果删除缓存失败了,或者数据库主从同步有延迟,还是会读到旧数据,有个模式叫写穿透(Write-Through),这个在《凤凰架构》里提到过,这个模式下,程序不直接写数据库,而是先写缓存,然后由缓存组件自己(或者一个特定的服务)负责去更新数据库,这样能保证缓存和数据库的写操作是原子的,一致性更好,但对缓存组件的功能要求更高,通常需要专门的缓存服务支持,不像直接用Redis那么简单。
还有一种更复杂的叫写回(Write-Behind),它是先只写缓存,然后缓存异步地、批量地把数据更新到数据库,这样写的性能极高,因为应用程序不用等慢速的数据库磁盘操作,但风险也极大,万一缓存宕机,还没来及同步到数据库的数据就全丢了,这个一般用在能承受一定数据丢失的场景,比如用户的行为日志计数。
别忘了缓存预热,这是落地时非常实际的一步,总不能等用户来访问了才慢慢往缓存里加数据吧?尤其是新系统上线或者高峰期来临前,可以提前把热点数据加载到Redis里,比如通过跑个脚本,分析之前的日志,把最常被访问的数据提前塞进缓存,这样系统一上线,大部分请求就能直接命中缓存,体验丝滑。
没有一种模式是万能的,缓存旁路是基础,互斥锁和逻辑过期解决高并发读的痛点,写穿透和写回在写性能和一致性之间做权衡,真正落地的时候,得根据你自己的业务特点,比如数据一致性要求多高、读多频繁还是写多频繁、能不能容忍短暂的数据不一致,来选择合适的模式,甚至组合使用它们,玩转Redis的关键,不在于你会不会用那几个命令,而在于你能不能根据实际情况,设计出最能抗、最稳健的缓存策略。

本文由召安青于2026-01-16发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/81949.html
