主题切换
逻辑过期方案
一、核心思路
- Redis 不对 Key 设置物理过期时间,不会主动删除缓存数据,在缓存 Value 中额外存储
expire逻辑过期时间戳。 - 缓存数据永久驻留 Redis,从根源避免因物理过期引发的缓存击穿。
二、执行流程
线程1(成功获取分布式锁)
- 查询缓存,对比当前时间与逻辑过期时间戳,判定数据已逻辑过期。
- 成功获取分布式互斥锁。
- 开启异步子线程,查询数据库、更新Redis缓存并刷新逻辑过期时间戳。
- 主线程直接返回旧缓存数据,请求不阻塞。
线程2、线程3(抢锁失败)
无法获取分布式锁,直接返回当前旧缓存数据,全程不会访问数据库。
线程4(后续正常请求)
异步线程已完成缓存刷新,逻辑过期时间同步更新,请求直接命中最新有效缓存。
三、优缺点
优点
- 所有请求均不阻塞,接口吞吐量高,用户体验良好。
- 有效避免大量并发请求同时访问数据库,彻底解决缓存击穿问题。
缺点
会短暂返回过期数据,无法保证数据实时一致性。适用于商品首页、热点文章等可容忍短时脏读的业务场景。
四、与互斥锁方案对比
- 分布式互斥锁:抢锁失败的请求会阻塞等待,数据强一致,但会增加请求耗时、降低吞吐量。
- 逻辑过期:抢锁失败直接返回旧数据,请求无阻塞、吞吐能力强,需容忍短暂数据不一致。
五、补充说明
该方案底层依托 Redisson 分布式锁 实现。
六、面试高频问题解析
问:简述逻辑过期方案的实现思路?
答: 不给缓存Key设置物理过期时间,在数据中嵌入逻辑过期时间戳。数据逻辑过期后,仅一个线程获取锁并开启异步线程更新缓存,其余请求直接返回旧数据,以此防止大量请求击穿数据库。
问:逻辑过期方案有什么优缺点,适合哪些业务?
答: 优点是请求无阻塞、并发性能高;缺点是会短暂返回过期数据,无法做到强一致。适合商品展示、资讯文章等允许短时数据不一致的业务。
问:逻辑过期和分布式互斥锁两种方案怎么选型?
答: 对数据实时性要求高,优先使用分布式互斥锁;追求高并发吞吐量、可容忍短暂脏读,选择逻辑过期方案。
问:逻辑过期方案依赖什么组件?
答: 底层依赖 Redisson 实现分布式锁,控制只有一个线程执行缓存更新操作。