缓存问题
视频参考黑马的Redis教程
缓存穿透
缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库
如果放任这种请求不断访问,就很容易搞垮数据库T_T,于是有了两种常见的解决方案
缓存空对象
- 思路:缓存空对象到
Redis中,这样下次再请求就不会到达数据库 - 优点:
- 实现简单,维护方便
- 缺点:
- 额外的内存消耗
- 可能造成短期的不一致
常见的解决办法就是为null设置TTL(有效时间),避免存太多了null垃圾
- 业务中实现流程:
- 在数据库查询为空的时候向
Redis添加空值,并设置TTL - 向
Redis请求时对空值做判断
- 在数据库查询为空的时候向
布隆过滤
- 思路:在客户端与
Redis之间再加入一层布隆过滤器,如果不存在数据,直接拒绝请求返回,有才继续- 布隆过滤器:基于某种哈希算法去计算出数据对应的hash值,再转换为二进制保存到布隆过滤器中
- 所以布隆过滤器可以看作一个二进制的数组,而布隆过滤实际是一种算法
- 优点:
- 内存占用较少,没有多余的key
- 缺点:
- 实现复杂
- 存在误判的可能
这里可以看出布隆过滤器借助了哈希,也就意味着不存在时真不存在,但布隆过滤器查询存在时并非一定存在,还是有击穿的风险
非常见方案(主动)
- 增加id的复杂度,避免被猜测id规律
- 做好数据的基础格式的校验
- 加强用户权限校验
- 做好热点参数的限流(TO DO见springcloud)
缓存雪崩
缓存雪崩是指在同意时段大量的缓存key同时失效或者Redis服务宕机,导致大量的请求到达数据库,带来巨大压力
解决方案
- 给不同的Key的TTL添加随机值
- 利用Redis集群提高服务的可用性
- 给缓存业务添加降级限流策略
- 给业务添加多级缓存
缓存击穿
缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击
互斥锁
- 悲观锁的机制,参考我的另一篇文章乐观锁、悲观锁

- 优点:
- 没有额外的内存消耗
- 保持一致性
- 实现简单
- 缺点:
- 线程需要等待,性能受到影响
- 可能会有死锁的风险
逻辑过期
- 思路:不设置TTL,设置逻辑过期(例如在value中添加一个expire),过期后获取到互斥锁,会开启到新的线程去操作写入缓存,重置逻辑过期时间,同时返回旧数据

- 优点:
- 线程无需等待,性能较好
- 缺点
- 不保持一致性
- 有额外的内存消耗
- 实现复杂
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Blog of Sof!
评论






