首先,来画一张图了解下缓存处理的流程

一、缓存穿透

  描述:

 缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求查询该数据,导致数据库压力过大。

  解决方案:

  1、接口校验

如鉴权校验、数据合法性校验

  2、布隆过滤器

将数据库中所有的查询条件,放入布隆过滤器中,当一个查询请求过来时,先经过布隆过滤器进行查,如果判断请求查询值存在,则继续查;如果判断请求查询不存在,直接丢弃。

  3、缓存空结果

  当没有命中缓存时,也没有从数据库取到数据时,我们给它缓存一个空结果,并且设置一个较短的过期时间(例如30s),之后当有请求访问时,可以直接从缓存中获取,保护后端数据源。   

  这个解决方案会存在两个问题:

  1.会需要更多的空间来存储更多的键,因为这当中可能会产生很多的空值键;

  2.数据一致性的问题,即时给空值设定了过期时间,缓存层和存储层还有会有一定时间的不一致,这对需要保持数据一致性的业务会有影响。

  

二、缓存击穿

  描述:

  缓存击穿是缓存中没有但数据库有的数据(一般是“热点数据”缓存时间到期了),这个时候由于并发量特别大,读缓存的时候读取不到数据,都同时去数据库读取数据了,导致数据库的压力瞬间增大,

  解决方案:

   1、设置热点数据永不过期

  2、加互斥锁 

  当多个线程同时去数据库查询这一条数据时,我们可以在第一个查询时使用互斥锁来锁住它,其他的线程走到这一步拿不到锁就进入等待的状态,等第一个线程查完数据,写入缓存后。后面的线程进来就可以直接走缓存了。

  贴代码,仅供参考:

  1. 1 static Lock reenLock = new ReentrantLock();
  2. 2 public Object getData() throws InterruptedException{
  3. 3 //从缓存中获取数据
  4. 4 Object object = getDataFromRedis();
  5. 5 if(object == null){
  6. 6 if(reenLock.tryLock()){
  7. 7 try {
  8. 8 System.out.println("拿到锁,从数据库中获取数据并写入缓存中");
  9. 9 //从数据库中查询数据
  10. 10 object = getDataFromDB();
  11. 11 //写入缓存
  12. 12 setDataToRedis(object);
  13. 13 } finally {
  14. 14 reenLock.unlock();// 释放锁
  15. 15 }
  16. 16 }else{
  17. 17 object = getDataFromRedis();// 先查一下缓存
  18. 18 if (object == null) {
  19. 19 System.out.println("我没拿到锁,缓存也没数据,先等待一下");
  20. 20 Thread.sleep(100);
  21. 21 return getData();// 重试
  22. 22 }
  23. 23 }
  24. 24 }
  25. 25 return object;
  26. 26 } 

三、缓存雪崩

  描述:

  缓存雪崩与缓存击穿不同的一点是,缓存雪崩是指大量的热点Key设置了相同的过期时间,导致缓存在同一时刻大量失效,这时由于并发量过大,会导致所有的请求都需要到数据库去读取数据,数据库压力骤增,引起雪崩。

  解决方案:

  1、过期时间打散

  既然是因为大量缓存集中失效导致的,那第一想到的应该是让它们不要集中失效就好了。可以给缓存的过期时间加一个随机值时间,使得每一个Key的过期时间都错开来,不会在同一时刻失效。

  2、热点数据永不过期

  3、加互斥锁

  该方式和缓存击穿一样,按Key维度去加锁,同一个Key,指允许一个线程去请求数据库,后续的都从缓存中读取。

最后

欢迎补充,点个推荐鼓励一下吧!

Redis缓存穿透、缓存击穿、缓存雪崩的介绍及其解决方案的更多相关文章

  1. 【干货!!】三句话搞懂 Redis 缓存穿透、击穿、雪崩

    前言 如何有效的理解并且区分 Reids 穿透.击穿和雪崩之间的区别,一直以来都挺困扰我的.特别是穿透和击穿,过一段时间就稀里糊涂的分不清了. 为了有效的帮助笔者自己,以及拥有同样烦恼的朋友们区分这三 ...

  2. redis的缓存穿透、击穿、雪崩以及实用解决方案

    今天来聊聊redis的缓存穿透.击穿.雪崩以及解决方案,其中解决方案包括类似于布隆过滤器这种网上一搜一大片但是实际生产部署有一定复杂度的,也有基于spring注解通过一行代码就能解决的,其中各有优劣, ...

  3. Redis高级应用解析:缓存穿透、击穿、雪崩

    1 背景 像我们去面试一些大公司的时候,就会遇到一些关于缓存的问题.可能很多同学都是接触过,多多少少了解一些,但是如果没有好好记录这些内容,不熟练精通的话,在真正面试的时候,就很难答出来了. 在我们的 ...

  4. redis 缓存穿透、击穿、雪崩

    缓存穿透: 大量查询 redis 中不存在的key(用随救数进行查询),导致每次都会去查询数据库,造成数据库压力过大(甚至宕机). 解决办法: 1.对我们的 api 接口 进行限流处理.用户授权.黑名 ...

  5. Redis缓存穿透、击穿、雪崩,数据库与缓存一致性

    Redis作为高性能非关系型(NoSQL)的键值对数据库,受到了广大用户的喜爱和使用,大家在项目中都用到了Redis来做数据缓存,但有些问题我们在使用中不得不考虑,其中典型的问题就是:缓存穿透.缓存雪 ...

  6. 穿透、击穿、雪崩…Redis这么多问题,如何解决?

    摘要:什么是缓存穿透?什么是缓存击穿,又什么是缓存雪崩呢?它们是如何造成的?又该如何解决呢?今天,我们就一起来探讨这些问题. 本文分享自华为云社区<[高并发]什么是缓存穿透?击穿?雪崩?如何解决 ...

  7. Redsi缓存问题(穿透,击穿,雪崩)以及解决办法(分布式锁)【高并发问题】

    Redsi常见问题 缓存在高平发和安全压力下的一些问题 缓存击穿 是某一个热点key在高并发访问的情况下,突然失效,导致大量的并发大金mysql数据库的情况 缓存穿透 是利用redis和mysql的机 ...

  8. NoSQL & Redis 介绍、缓存穿透 & 击穿 & 雪崩

    1. NoSql 简介 2. Redis 简介 2.1 Redis 的起源 2.2 缓存过期 & 缓存淘汰 3. 缓存异常 1)缓存穿透 2)缓存击穿 3)缓存雪崩 4)总结 1. NoSQL ...

  9. redis缓存, 缓存击穿,缓存雪崩,缓存穿透

    在实际项目中,MySQL数据库服务器有时会位于另外一台主机,需要通过网络来访问数据库:即使应用程序与MySQL数据库在同一个主机中,访问MySQL也涉及到磁盘IO操作(MySQL也有一些数据预读技术, ...

随机推荐

  1. YARN的工作过程

    yarn的工作执行流程图 1.用户向YARN中提交应用程序 2.ResourceManager为该应用程序找到一个可用的NodeManager 并分配一个Container,然后在这个Containe ...

  2. Python - 面向对象编程 - @property

    前言 前面讲到实例属性的时候,我们可以通过 实例对象.实例属性 来访问对应的实例属性 但这种做法是不建议的,因为它破坏了类的封装原则 正常情况下,实例属性应该是隐藏的,只允许通过类提供的方法来间接实现 ...

  3. go实现堆排序

    package main import "fmt" func main(){ arr:=[]int{4,8,2,1,6,9,3,5,7,8,1,4} dui(arr) fmt.Pr ...

  4. ES6扩展——对象的扩展(简洁表示法与属性名表达式)

    1.简洁表达法. 当属性名与属性值相同时,可省略属性值:例如:{name : name}可以写成 {name} 属性方法中,可省略冒号与function,直接 属性名(){}即可.例如{say : f ...

  5. NVidia Jetson Ubuntu 18.04 安装ROS过程中运行sudo rosdep init指令出错

    参考:https://www.cnblogs.com/xuhaoforwards/p/9399744.html 安装ROS过程中运行sudo rosdep init后,出现如下错误LOG: ERROR ...

  6. Java反射的浅显理解

    一.回顾反射相关的知识 1.在xml文件中使用反射的好处: 1)代码更加灵活,后期维护只需要修改配置文件即可 · 初学者一般习惯于在代码本身上直接修改,后期也可以修改配置文件达到相同的目的 · 修改配 ...

  7. 如何实现CSS限制字数,超出部份显示省略号

    <div style="width:200px; white-space:nowrap;overflow:hidden;text-overflow:ellipsis; border:1 ...

  8. Kotlin之内联回调函数

    let 定义: let扩展函数的实际上是一个作用域函数,当你需要去定义一个变量在一个特定的作用域范围内,let函数的是一个不错的选择:let函数另一个作用就是可以避免写一些判断null的操作. 翻译: ...

  9. Sentry Web 性能监控 - Web Vitals

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  10. 2021 年 9 月 TIOBE 指数 C# 增长突破 1.2%

    TIOBE 编程社区指数是编程语言流行程度的指标.该指数每月更新一次.评级基于全球熟练工程师.课程和第三方供应商的数量.谷歌.必应.雅虎.维基百科.亚马逊.YouTube 和百度等流行搜索引擎用于计算 ...