Redis缓存穿透、缓存击穿、缓存雪崩的介绍及其解决方案
首先,来画一张图了解下缓存处理的流程
一、缓存穿透
描述:
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求查询该数据,导致数据库压力过大。
解决方案:
1、接口校验
如鉴权校验、数据合法性校验
2、布隆过滤器
将数据库中所有的查询条件,放入布隆过滤器中,当一个查询请求过来时,先经过布隆过滤器进行查,如果判断请求查询值存在,则继续查;如果判断请求查询不存在,直接丢弃。
3、缓存空结果
当没有命中缓存时,也没有从数据库取到数据时,我们给它缓存一个空结果,并且设置一个较短的过期时间(例如30s),之后当有请求访问时,可以直接从缓存中获取,保护后端数据源。
这个解决方案会存在两个问题:
1.会需要更多的空间来存储更多的键,因为这当中可能会产生很多的空值键;
2.数据一致性的问题,即时给空值设定了过期时间,缓存层和存储层还有会有一定时间的不一致,这对需要保持数据一致性的业务会有影响。
二、缓存击穿
描述:
缓存击穿是缓存中没有但数据库有的数据(一般是“热点数据”缓存时间到期了),这个时候由于并发量特别大,读缓存的时候读取不到数据,都同时去数据库读取数据了,导致数据库的压力瞬间增大,
解决方案:
1、设置热点数据永不过期
2、加互斥锁
当多个线程同时去数据库查询这一条数据时,我们可以在第一个查询时使用互斥锁来锁住它,其他的线程走到这一步拿不到锁就进入等待的状态,等第一个线程查完数据,写入缓存后。后面的线程进来就可以直接走缓存了。
贴代码,仅供参考:
1 static Lock reenLock = new ReentrantLock();
2 public Object getData() throws InterruptedException{
3 //从缓存中获取数据
4 Object object = getDataFromRedis();
5 if(object == null){
6 if(reenLock.tryLock()){
7 try {
8 System.out.println("拿到锁,从数据库中获取数据并写入缓存中");
9 //从数据库中查询数据
10 object = getDataFromDB();
11 //写入缓存
12 setDataToRedis(object);
13 } finally {
14 reenLock.unlock();// 释放锁
15 }
16 }else{
17 object = getDataFromRedis();// 先查一下缓存
18 if (object == null) {
19 System.out.println("我没拿到锁,缓存也没数据,先等待一下");
20 Thread.sleep(100);
21 return getData();// 重试
22 }
23 }
24 }
25 return object;
26 }
三、缓存雪崩
描述:
缓存雪崩与缓存击穿不同的一点是,缓存雪崩是指大量的热点Key设置了相同的过期时间,导致缓存在同一时刻大量失效,这时由于并发量过大,会导致所有的请求都需要到数据库去读取数据,数据库压力骤增,引起雪崩。
解决方案:
1、过期时间打散
既然是因为大量缓存集中失效导致的,那第一想到的应该是让它们不要集中失效就好了。可以给缓存的过期时间加一个随机值时间,使得每一个Key的过期时间都错开来,不会在同一时刻失效。
2、热点数据永不过期
3、加互斥锁
该方式和缓存击穿一样,按Key维度去加锁,同一个Key,指允许一个线程去请求数据库,后续的都从缓存中读取。
最后
欢迎补充,点个推荐鼓励一下吧!
Redis缓存穿透、缓存击穿、缓存雪崩的介绍及其解决方案的更多相关文章
- 【干货!!】三句话搞懂 Redis 缓存穿透、击穿、雪崩
前言 如何有效的理解并且区分 Reids 穿透.击穿和雪崩之间的区别,一直以来都挺困扰我的.特别是穿透和击穿,过一段时间就稀里糊涂的分不清了. 为了有效的帮助笔者自己,以及拥有同样烦恼的朋友们区分这三 ...
- redis的缓存穿透、击穿、雪崩以及实用解决方案
今天来聊聊redis的缓存穿透.击穿.雪崩以及解决方案,其中解决方案包括类似于布隆过滤器这种网上一搜一大片但是实际生产部署有一定复杂度的,也有基于spring注解通过一行代码就能解决的,其中各有优劣, ...
- Redis高级应用解析:缓存穿透、击穿、雪崩
1 背景 像我们去面试一些大公司的时候,就会遇到一些关于缓存的问题.可能很多同学都是接触过,多多少少了解一些,但是如果没有好好记录这些内容,不熟练精通的话,在真正面试的时候,就很难答出来了. 在我们的 ...
- redis 缓存穿透、击穿、雪崩
缓存穿透: 大量查询 redis 中不存在的key(用随救数进行查询),导致每次都会去查询数据库,造成数据库压力过大(甚至宕机). 解决办法: 1.对我们的 api 接口 进行限流处理.用户授权.黑名 ...
- Redis缓存穿透、击穿、雪崩,数据库与缓存一致性
Redis作为高性能非关系型(NoSQL)的键值对数据库,受到了广大用户的喜爱和使用,大家在项目中都用到了Redis来做数据缓存,但有些问题我们在使用中不得不考虑,其中典型的问题就是:缓存穿透.缓存雪 ...
- 穿透、击穿、雪崩…Redis这么多问题,如何解决?
摘要:什么是缓存穿透?什么是缓存击穿,又什么是缓存雪崩呢?它们是如何造成的?又该如何解决呢?今天,我们就一起来探讨这些问题. 本文分享自华为云社区<[高并发]什么是缓存穿透?击穿?雪崩?如何解决 ...
- Redsi缓存问题(穿透,击穿,雪崩)以及解决办法(分布式锁)【高并发问题】
Redsi常见问题 缓存在高平发和安全压力下的一些问题 缓存击穿 是某一个热点key在高并发访问的情况下,突然失效,导致大量的并发大金mysql数据库的情况 缓存穿透 是利用redis和mysql的机 ...
- NoSQL & Redis 介绍、缓存穿透 & 击穿 & 雪崩
1. NoSql 简介 2. Redis 简介 2.1 Redis 的起源 2.2 缓存过期 & 缓存淘汰 3. 缓存异常 1)缓存穿透 2)缓存击穿 3)缓存雪崩 4)总结 1. NoSQL ...
- redis缓存, 缓存击穿,缓存雪崩,缓存穿透
在实际项目中,MySQL数据库服务器有时会位于另外一台主机,需要通过网络来访问数据库:即使应用程序与MySQL数据库在同一个主机中,访问MySQL也涉及到磁盘IO操作(MySQL也有一些数据预读技术, ...
随机推荐
- mysql 用 source 导入备份数据
输入命令:source E:/proDB/start2.sql;
- ES6基础之let、const
es6的块级作用域通俗的讲就是一对花括号中的区域(声明对象的花括号不是块级作用域),块级作用域可以嵌套. let: 1.le声明的变量只在当前(块级)作用域内有效. 2.let声明的变量不能被重复声明 ...
- 重启网络服务 network 出现问题
2021-08-24 地址冲突了,因为想要设置成静态 ip 一直都不对,情急之下就将本地 ip 设置成了虚拟机的 ip,故出现此错误 后将地址改掉,重启网络服务就没有错误了 一开始我设置的虚拟网卡 n ...
- Vue 组件通信方案
父组件--> 子组件 1. 属性设置 父组件关键代码如下: <template> <Child :child-msg="msg"></Child ...
- Eclipse中安装配置Gradle
Gradle是以Groovy语言为基础,面向Java应用为主.基于DSL(领域特定语言)语法的自动化构建工具. gradle对多工程的构建支持很出色,工程依赖是gradle的第一功能. gradle支 ...
- FPGA nios通过驱动LCD12864实现菜单界面和uart串口通信
因为csdn无法插入视频,无法展示我这个实现的效果,这里我截了一些图,应该基本上也能明白了: 基本功能就是如图片所示,里面采用了菜单结构(这里编程需要一定得c语言编程技巧与数据结构知识),gpa是什么 ...
- 为开源项目 go-gin-api 增加后台任务模块
目录 任务管理界面 (WEB) 任务调度器 任务执行器 小结 推荐阅读 任务管理界面 (WEB) 支持在 WEB 界面 中对任务进行管理,例如:新增任务.编辑任务.启用/禁用任务.手动执行任务 等. ...
- try/catch捕获处理异常
1.throws是中断处理,后续代码不能执行 try/catch方法体之后的后续代码有没有异常都可以继续执行: 2.当try方法体中出现异常才会执行catch方法体中代码
- MySQL索引、事务、存储引擎
一.MySQL 索引 1.索引的概念 ●索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址(类似于C语言的链表通过指针指向数据记录的内存地址).●使用索引后可以不用扫描 ...
- 本地Markdown文件上传到博客
本地Markdown文件上传到博客 参考:https://www.cnblogs.com/ccylhw/p/13954153.html 1.Typora 最漂亮的写作APPhttps://www.ty ...