Redis - 缓存访问 & 缓存穿透 & 缓存击穿 & 缓存雪崩

一、缓存访问

1、客户端发送请求

2、服务首先会请求 redis,查看请求的内容是否存在

3、redis 将请求结果返回给服务,如果返回的结果有数据则直接返回给客户端;如果没有数据则会继续往下执行

4、服务从数据库中查询请求的数据

5、数据库将查询的结果返回给服务

6、如果数据库有返回数据,则将返回的结果添加到 redis

7、将请求到的数据返回给客户端

二、缓存穿透

通过接口访问一个缓存和数据库都不存在的数据。

因为服务出于容错考虑,当请求从持久层查不到数据则不写入缓存,这将导致请求这个不存在的数据每次都要到持久层去查询,失去了缓存的意义。

此时,缓存起不到保护后端持久层的意义,就像被穿透了一样。导致数据库存在被打挂的风险。

解决办法

1、接口请求参数的校验。对请求的接口进行鉴权,数据合法性的校验等;比如查询的 userId 不能是负值或者包含非法字符等。

2、当数据库返回空值时,将空值缓存到 redis,并设置合理的过期时间。

3、布隆过滤器。使用布隆过滤器存储所有可能访问的 key,不存在的 key 直接被过滤,存在的 key 则再进一步查询缓存和数据库。(布隆过滤器存在一定误判情况:当判断不存在时一定不存在,当判断存在时极小可能不存在)

三、缓存击穿

某个热点 key,在缓存过期的一瞬间,同时有大量的请求打进来,由于此时缓存过期了,所以请求最终都会走到数据库,造成瞬时数据库请求量大、压力骤增,导致数据库存在被打挂的风险。

解决办法

1、加互斥锁。当热点 key 过期后,大量的请求涌入时,只有第一个请求能获取锁并阻塞,此时该请求查询数据库,并将查询结果写入 redis 后释放锁。后续的请求直接走缓存。

2、设置缓存不过期或者后台有线程一直给热点数据续期。

四、缓存雪崩

大量的热点数据过期时间相同,导致数据在同一时刻集体失效。造成瞬时数据库请求量大、压力骤增,引起雪崩,导致数据库存在被打挂的风险。

解决办法

1、将热点数据的过期时间打散。给热点数据设置过期时间时加个随机值。

2、加互斥锁。当热点 key 过期后,大量的请求涌入时,只有第一个请求能获取锁并阻塞,此时该请求查询数据库,并将查询结果写入 redis 后释放锁。后续的请求直接走缓存。

3、设置缓存不过期或者后台有线程一直给热点数据续期。

相关推荐
看山还是山,看水还是。35 分钟前
MySQL 管理
数据库·笔记·mysql·adb
fishmemory7sec41 分钟前
Koa2项目实战2(路由管理、项目结构优化)
数据库·mongodb·koa
momo小菜pa1 小时前
【MySQL 09】表的内外连接
数据库·mysql
Jasonakeke1 小时前
【重学 MySQL】四十九、阿里 MySQL 命名规范及 MySQL8 DDL 的原子化
数据库·mysql
程序猿小D1 小时前
第二百六十九节 JPA教程 - JPA查询OrderBy两个属性示例
java·开发语言·数据库·windows·jpa
小宇成长录1 小时前
Mysql:数据库和表增删查改基本语句
数据库·mysql·数据库备份
团儿.2 小时前
解锁MySQL高可用新境界:深入探索MHA架构的无限魅力与实战部署
数据库·mysql·架构·mysql之mha架构
程序猿小D2 小时前
第二百六十七节 JPA教程 - JPA查询AND条件示例
java·开发语言·前端·数据库·windows·python·jpa
权^3 小时前
MySQL--聚合查询、联合查询、子查询、合并查询(上万字超详解!!!)
大数据·数据库·学习·mysql
wclass-zhengge3 小时前
Redis篇(最佳实践)(持续更新迭代)
redis·缓存·bootstrap