Redis缓存击穿、缓存雪崩、缓存穿透,缓存一致性问题

一、缓存击穿

缓存击穿是指:某一热点 key 在缓存和数据库中都存在,它过期时,这时由于并发用户特别多,同时读缓存没读到,又同时去数据库去读,压垮数据库

解决方法

1. 热点数据不过期
2. 查询缓存没有,查询数据库,结果放入缓存 这三步进行加锁,这时只有一个客户端能获得锁,其它客户端会被阻塞,等锁释放开,缓存已有了数据,其它客户端就不必访问数据库了。但会影响吞吐量(有损方案)

 Redis缓存击穿、缓存雪崩、缓存穿透,缓存一致性问题_第1张图片

二、缓存雪崩 

情况1:由于大量 key 设置了相同的过期时间(数据在缓存和数据库都存在),一旦到达过期时间点,这些 key 集体失效,造成访问这些 key 的请求全部进入数据库。

给某个 key 加锁能解决雪崩吗?

解决方法:

1. 错开过期时间:在过期时间上加上随机值(比如 1~5 分钟)
2. 服务降级:暂停非核心数据查询缓存,返回预定义信息(错误页面,空值等)

情况2Redis 实例宕机,大量请求进入数据库

解决方法:

1. 事前预防:搭建高可用集群
2. 多级缓存:缺点是实现复杂度高
3. 熔断:通过监控一旦雪崩出现,暂停缓存访问待实例恢复,返回预定义信息(有损方案)
4. 限流:通过监控一旦发现数据库访问量超过阈值,限制访问数据库的请求数(有损方案)

三、缓存穿透

缓存穿透是指:如果一个 key 在缓存和数据库都不存在,那么访问这个 key 每次都会进入数据库

        很可能被恶意请求利用

        缓存雪崩与缓存击穿都是数据库中有,但缓存暂时缺失

        缓存雪崩与缓存击穿都能自然恢复,但缓存穿透则不能

解决方法:

1.如果数据库没有,也将此不存在的 key 关联 null 值放入缓存,缺点是这样的 key 没有任何业务作用,白占空间

2.布隆过滤器

        ①过滤器可以用来判定 key 不存在,发现这些不存在的 key,把它们过滤掉就好

        ②需要将所有的 key 都预先加载至布隆过滤器

        ③布隆过滤器不能删除,因此查询删除的数据一定会发生穿透

Redis缓存击穿、缓存雪崩、缓存穿透,缓存一致性问题_第2张图片

四、缓存一致性问题

何为旁路缓存(Cache Aside),它是一种使用缓存的策略

查询时的规则
先读缓存
如果命中,直接返回
如果缺失,查 DB 并将结果放入缓存,再返回
增、删、改的规则
新增数据,直接存 DB
修改、删除数据, 更新 DB 删缓存
为什么要先操作库,再操作缓存?
假设操作库和缓存均能成功,仍会出现数据库与缓存不一致的情况

分析1 先清缓存,再更新库

有问题

Redis缓存击穿、缓存雪崩、缓存穿透,缓存一致性问题_第3张图片

分析2 – 先更新库,再清缓存

 会有短暂不一致,但最终会一致

 Redis缓存击穿、缓存雪崩、缓存穿透,缓存一致性问题_第4张图片

分析3 – 先更新库,再清缓存

 假设查询线程 A 查询数据时恰好缓存数据由于时间到期失效,或是第一次查询,但这种几率出现机会很小

Redis缓存击穿、缓存雪崩、缓存穿透,缓存一致性问题_第5张图片

分析4 – 用锁解决 

Redis缓存击穿、缓存雪崩、缓存穿透,缓存一致性问题_第6张图片

 

你可能感兴趣的:(redis,redis,缓存,java)