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、设置缓存不过期或者后台有线程一直给热点数据续期。

相关推荐
郑州光合科技余经理1 小时前
PHP构建:支撑欧美澳市场的同城生活服务平台开发
java·开发语言·数据库·uni-app·php·排序算法·生活
JIngJaneIL9 小时前
基于springboot + vue古城景区管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
微学AI10 小时前
复杂时序场景的突围:金仓数据库是凭借什么超越InfluxDB?
数据库
廋到被风吹走10 小时前
【数据库】【Redis】定位、优势、场景与持久化机制解析
数据库·redis·缓存
有想法的py工程师11 小时前
PostgreSQL + Debezium CDC 踩坑总结
数据库·postgresql
Nandeska11 小时前
2、数据库的索引与底层数据结构
数据结构·数据库
小卒过河010412 小时前
使用apache nifi 从数据库文件表路径拉取远程文件至远程服务器目的地址
运维·服务器·数据库
过期动态12 小时前
JDBC高级篇:优化、封装与事务全流程指南
android·java·开发语言·数据库·python·mysql
Mr.朱鹏12 小时前
SQL深度分页问题案例实战
java·数据库·spring boot·sql·spring·spring cloud·kafka
一位代码12 小时前
mysql | 常见日期函数使用及格式转换方法
数据库·mysql