Redis 缓存穿透、缓存雪崩、缓存击穿
文章目录
一、缓存穿透
1、什么是缓存穿透?
- 请求未命中缓存层,直接访问数据库的现象
- 有缓存层就会有缓存穿透,除非数据库的数据 全部 同步到缓存中,否则就一定会存在缓存穿透
- 只能尽量避免 高频 的缓存穿透,不能彻底解决低频的缓存穿透
2、造成缓存穿透的场景?
- ID 为 -1:
解决方案:
- 通过数据库查询没有该数据库后,在缓存层缓存为null值
- 查询数据库之前,过滤掉非法ID
- ID为 UUID:
解决方案:
- 将所有ID存在缓存层中,只有缓存中存在,才让该请求访问数据库;由于 所有 ID存在缓存中,缓存存储于内存中 ,所以存在内存不足问题 ;故 在缓存层和数据库之间添加 布隆过滤器
3、布隆过滤器(布隆算法)
-
核心思想:以一定的错误率换取空间
-
算法流程:
ID ➡️ hash算法(数组长度内、值分散)➡️ bit数组(hash值对应位置标记为1);判断ID是否存在时,通过以上流程,查看该数组位置上是否标记
-
存在错误率的原因:因为可能存在hash 碰撞
hash碰撞:不同的值通过hash计算之后,得出相同的值
-
降低错误率的方式
- 增加数组的长度,因为hash算法 取值在 算法长度内(一般hash取值后取模数组长度)
- 增加hash算法的个数(hash算法个数应该适量,例如:算法个数大于数组长度时,很容易缓存一个值就标记完数组中所有值)
二、缓存雪崩
1、什么是缓存雪崩?
缓存雪崩:缓存同一时间,大规模失效
2、造成缓存雪崩的场景
- 大量热点数据设置为相同过期时间
解决方案:
- 热点数据设置为不失效,只在修改的时候进行更新
- 设置过期时间时 + 随机数
- Redis 服务器宕机
- Redis 服务器集群:多个服务器存 相同 的数据
- Redis 服务器分布式:缓存 按照分片规则 分散存在不同的 redis服务器中
数据迁移:分布式 redis时,由于添加一台 redis 服务器后,存在 以前 服务器的 部分 数据 ,已经不符合分片规则;所以需要将不符合分片规则的数据 进行迁移,hash一致性算法是用来解决 数据迁移的方案
3、Hash 一致性算法
- Hash 一致性算法原理:redis 服务器节点通过 hash 计算出值(值范围为:0~232),映射到一个0~232的圆上;然后缓存的数据依旧通过hash计算出值,映射到该圆上;数据和节点都映射到圆上之后,数据应该存储的节点,就是数据顺时针的第一个节点
- 数据迁移:增加节点时只需要在 两个 节点之间迁移数据,其余节点不需要进行迁移
- 有待优化:当redis节点太少时,容易发生数据倾斜
4. 解决方案:添加虚拟节点,节点越多,发生数据倾斜的概率就越小
三、缓存击穿
1、什么是缓存击穿?
缓存击穿:高并发 场景下,单条 缓存失效后,大量 请求直接访问数据库
2、解决方案
添加分布式锁:
-
zookeeper:使用临时 有序 节点 来对请求进行排序;使用回调 来处理请求;使用zookeeper 心跳来处理 客户端宕机的情况
-
redis:请求进来时,添加一条数据(上锁),处理完成时删除该数据(解锁);其他请求进来的时候,查看是否存在该数据,存在则等待
四、总结
- 缓存穿透 是请求未命中缓存层,直接访问数据库的现象;
- 缓存雪崩 和 缓存击穿 本质上都是缓存穿透,他们是缓存穿透的特殊情况;
- 缓存雪崩:缓存层 多条 缓存失效时,大量 不同的 请求直接访问数据库
- 缓存击穿:高并发场景下,缓存层 单条 缓存失效时,大量 相同的 请求直接访问数据库