【2】Redis 缓存击穿原理和解决方案
文章目录
- 一、缓存击穿原理
- 正常情况:Redis缓存流程
- 问题引出:Redis缓存击穿问题
- 二、解决方案
- 方案一:互斥锁
- 方案二:逻辑过期
一、缓存击穿原理
正常情况:Redis缓存流程
查询数据时,优先查询Redis:
- 命中:直接返回查询结果
- 未命中:查询数据库,返回数据并将数据写入到Redis中缓存起来方便下次查询
问题引出:Redis缓存击穿问题
给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把数据库压垮
二、解决方案
方案一:互斥锁
并发请求时:
请求1(线程1) 查询缓存中的数据,若未命中,则会获取互斥锁,然后查询数据库并写入缓存。
在数据写入缓存期间,其他线程(线程2)没查到缓存中的数据,也获取不到互斥锁时,则会进入休眠状态,一段时间后再重新查询缓存数据,如此反复
直到请求1(线程1) 将数据缓存完才会释放锁
数据缓存并释放锁后,此时其他线程(线程2)会在不断重试的过程中直到命中缓存数据,才会返回查询数据
- 优点:安全性高
强一致性
- 缺点:性能差
(因为其他线程都要休眠等待,直到命中缓存数据)
方案二:逻辑过期
不设置过期时间,采用逻辑过期时间
并发请求时:
请求1(线程1) 查询缓存数据,发现逻辑过期,则获取互斥锁,开启新线程后就直接返回过期数据。
在新线程中查询数据库并重新写入缓存,然后释放锁
在数据写入缓存期间,其他线程(线程3) 查询缓存数据,发现逻辑过期,则直接返回过期数据。
在数据写入缓存并释放锁后,**其他线程(线程4)**查询缓存数据,命中数据并未过期,则直接返回查询数据。
- 优点:
- 高可用
- 性能高
直接返回结果,无需等待缓存重新写入(更新)
- 缺点:不考虑数据一致性