14、缓存预热+缓存雪崩+缓存击穿+缓存穿透

缓存预热+缓存雪崩+缓存击穿+缓存穿透

● 缓存预热、雪崩、穿透、击穿分别是什么?你遇到过那几个情况?
● 缓存预热你是怎么做到的?
● 如何避免或者减少缓存雪崩?
● 穿透和击穿有什么区别?它两一个意思还是截然不同?
● 穿透和击穿你有什么解决方案?如何避免?
● 加入出现了缓存不一致,你有哪些修补方案?

1、缓存预热
在这里插入图片描述
2、缓存雪崩
发生原因
● Redis主机挂了,Redis全盘崩溃,偏硬件运维。
● Redis中有大量key同时过期大面积失效,偏软件开发。
预防+解决
● Redis中key设置为永不过期or过期时间错开
● Redis缓存集群实现高可用
○ 主从+哨兵
○ Redis Cluster
○ 开启Redis持久化机制RDB/AOF,尽快恢复缓存集群
● 多缓存结合预防雪崩
○ ehcache本地缓存+redis缓存
● 服务降级
○ Hystrix或者案例sentinel限流&降级

3、缓存穿透
发生原因
请求去查一条记录,先查Redis无,后查MySQL无,都查不到该条记录,但是请求每次都会打到数据库上面去,导致后台数据库压力暴增,这种就是缓存穿透。
简单来说就是本来无一物,两库都没有,既不在Redis缓存库,也不再MySQL,数据库存在被多次暴击风险

解决方案
在这里插入图片描述

方案一:空对象缓存或者缺省值
一般正常情况下使用回写增强:mysql也查不到的话就让redis存入刚刚查不到的key并保护mysql,第一次来查询没有查询到,redis和mysql都没有,返回null给调用者,但是增强回写后第二次查同样的key,此时redis就有值了,可以直接从redis中读取default缺省值返回给业务程序,避免了把大量请求发送给mysql处理,打爆mysql------------>此种方法架不住黑客的恶意攻击,有缺陷…只能解决key相同的情况。
黑客或者恶意攻击:黑客会对你的系统进行攻击,拿一个不存在的id去查询数据,会产生大量的请求到数据库查询,可能会导致你的数据库由于压力过大而宕机。
key相同—>第一次达到mysql,空对象缓存后第二次就返回default缺省值,避免mysql再被攻击,不用再到数据库中走一圈了。
key不同—>由于存在空对象缓存和缓存回写(看自己的业务),redis中无关紧张的key也会越来越多(记得设置redis过期时间)。

方案二:Google布隆过滤器Guava解决缓存穿透
Guava中布隆过滤器的实现算是比较权威的,所以实际项目中可以直接采用Guava布隆过滤器

在这里插入图片描述

白名单过滤器实战
白名单那过滤器架构说明
误判问题:概率小还可以接受,不能从布隆过滤器中删除
全部合法的key都需要放入Guava版布隆过滤器+Redis里面,不然数据就是返回null
改POM

        <!--  Guava  Google开源的Guava中自带的布隆过滤器--><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>23.0</version></dependency>

业务类
我们的目的是再白名单里面设置100w的数据,然后再额外加入10w的数据,看一下误判率是多少

/*** @author Guanghao Wei* @create 2023-04-25 14:51*/
@Service
@Slf4j
public class GuavaWithBloomFilterService {//定义常量public static final int _1W = 10000;//定义guava布隆过滤器初始容量public static final int SIZE = 100 * _1W;//误判率,它越小,误判个数越少public static double fpp = 0.03;//创建guava布隆过滤器private BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), SIZE, fpp);public void guavaBloomFilter() {//先让bloomFilter加入100w数据for (int i = 1; i <= SIZE; i++) {bloomFilter.put(i);}//故意取10w个不在合法范围内的数据ArrayList<Object> list = new ArrayList<>(10 * _1W);//验证for (int i = SIZE + 1; i <= SIZE + (10 * _1W); i++) {if (bloomFilter.mightContain(i)) {log.info("被误判了:{}", i);list.add(i);}}log.info("误判总数量:{}", list.size());}
}
/*** @author Guanghao Wei* @create 2023-04-25 14:51*/
@Api(tags = "google工具Guava处理布隆过滤器")
@RestController
@Slf4j
public class GuavaWithBloomFilterController {@Autowiredprivate GuavaWithBloomFilterService guavaWithBloomFilterService;@ApiOperation("guava布隆过滤器插入100万样本数据并额外添加10w测试是否存在")@GetMapping("guavafilter")public void guavaBloomFilter() {guavaWithBloomFilterService.guavaBloomFilter();}
}

这里有一个误判率的知识点我们通过debug源码来学习:
在这里插入图片描述

布隆过滤器说明
在这里插入图片描述

缓存击穿
是什么
大量的请求同时查询一个key时,此时这个key正好失效了,就会导致大量的请求都打到数据库上去
简单来说就是热点key突然失效了,暴打mysql。

穿透和击穿,截然不同
热点key为什么失效?

时间到了自然清除但还未被访问到
delete掉的key,刚巧又被访问

危害
会造成某一时刻数据库请求量过大,压力剧增
一般技术部门需要知道热点key是哪些,做到心里有数防止击穿

解决
方案一:差异失效时间
对于访问频繁的热点key,干脆就不设置过期时间

方案二:互斥更新
采用双检加锁策略
案例

天猫聚划算功能实现+防止缓存击穿
在这里插入图片描述
数据类型可以选用list和zset,但这类场景一般还是选择list

实体类

/*** @author Guanghao Wei* @create 2023-04-25 15:40*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "聚划算活动product信息")
public class Product {private Long id;private String name;private Integer price;private String detail;
}

service

/*** @author Guanghao Wei* @create 2023-04-25 15:42*/
@Service
@Slf4j
public class JHSTaskService {public static final String JHS_KEY = "jhs";public static final String JHS_KEY_A = "jhs:a";public static final String JHS_KEY_B = "jhs:b";@Autowiredprivate RedisTemplate redisTemplate;/*** 模拟从数据库读取20件特价商品,用于加载到聚划算的页面中** @return*/private List<Product> getProductsFromMysql() {List<Product> list = new ArrayList<>();for (int i = 1; i <= 20; i++) {Random random = new Random();int id = random.nextInt(10000);Product obj = new Product((long) id, "product" + i, i, "detail");list.add(obj);}return list;}@PostConstructpublic void init() {log.info("启动定时器天猫聚划算功能模拟开始.........O(∩_∩)O");//用线程模拟定时任务,后台任务定时将mysql里面的参加活动的商品刷进redisnew Thread(() -> {//模拟从mysql查出数据用于加载进redis,在页面展示List<Product> productList = this.getProductsFromMysql();//采用redis list数据结构的lpush命令来存储redisTemplate.delete(JHS_KEY);//加入最新的数据redisTemplate.opsForList().leftPushAll(JHS_KEY, productList);//暂停1分钟,间隔一分钟执行一次,模拟聚划算一天执行的参加活动的品牌try { TimeUnit.MINUTES.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }}, "t1").start();}
}

controller

/*** @author Guanghao Wei* @create 2023-04-25 15:42*/
@Api(tags = "聚划算页面展示控制器")
@RestController
@Slf4j
public class JHSProductController {public static final String JHS_KEY = "jhs";@Autowiredprivate RedisTemplate redisTemplate;/*** 分页查询,在高并发的情况下,只能走Redis查询,走db的话必定会吧db打垮** @param page* @param size* @return*/@ApiOperation("聚划算案例,每次1页展示5条数据")@GetMapping("product/find")public List<Product> find(int page, int size) {List<Product> list = null;long start = (page - 1) * size;long end = start + size - 1;try {list = redisTemplate.opsForList().range(JHS_KEY, start, end);if (CollectionUtils.isEmpty(list)) {//走数据库查询 TODO}log.info("参加活动的商家:{}",list);} catch (Exception e) {//出异常了,一般redis宕机了,或者redis网络抖动导致timeoutlog.error("jhs exception:{}",e);e.printStackTrace();//再次查询}return list;}}

至此步骤,上述聚划算的功能算是完成了,请思考在高并发情况下又会产生什么样的经典生产问题?
Bug和隐患说明
在这里插入图片描述

热点key突然失效导致可怕的缓存击穿:delete命令执行的一瞬间有空隙,其他请求线程找Redis为null,达到mysql,暴击mysql…
复习again
在这里插入图片描述

最终目的:2条命令原子性是其次的,主要是防止热点key突然失效暴击mysql打爆系统。
进一步升级加固案例
互斥更新—>双检加锁策略
在这里插入图片描述

差异失效时间,在本案例中给我们使用这个方式

    @PostConstructpublic void initJHSAB() {log.info("启动AB定时器天猫聚划算功能模拟开始.........O(∩_∩)O" + DateUtil.now());//用线程模拟定时任务,后台任务定时将mysql里面的参加活动的商品刷进redisnew Thread(() -> {//模拟从mysql查出数据用于加载进redis,在页面展示List<Product> productList = this.getProductsFromMysql();//先更新B缓存,且让B过期时间超过A,B做兜底redisTemplate.delete(JHS_KEY_B);redisTemplate.opsForList().leftPushAll(JHS_KEY_B, productList);redisTemplate.expire(JHS_KEY_B, 86410L, TimeUnit.SECONDS);//在更新A缓存redisTemplate.delete(JHS_KEY_A);redisTemplate.opsForList().leftPushAll(JHS_KEY_A, productList);redisTemplate.expire(JHS_KEY_A, 86400L, TimeUnit.SECONDS);//暂停1分钟,间隔一分钟执行一次,模拟聚划算一天执行的参加活动的品牌try { TimeUnit.MINUTES.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }}, "t1").start();}
    @ApiOperation("AB双缓存架构,防止热点key突然失效")@GetMapping("product/findAB")public List<Product> findAB(int page, int size) {List<Product> list = null;long start = (page - 1) * size;long end = start + size - 1;try {list = redisTemplate.opsForList().range(JHS_KEY_A, start, end);if (CollectionUtils.isEmpty(list)) {log.info("-------A缓存已经失效或者过期了,记得人工修改,B缓存继续顶着");list = redisTemplate.opsForList().range(JHS_KEY_B, start, end);if (CollectionUtils.isEmpty(list)) {//TODO 走数据库查询}}} catch (Exception e) {//出异常了,一般redis宕机了,或者redis网络抖动导致timeoutlog.error("jhs exception:{}", e);e.printStackTrace();//再次查询}return list;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/50944.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JDBC详解

文章目录 一、引言1.1 如何操作数据库1.2 实际开发中&#xff0c;会采用客户端操作数据库吗&#xff1f; 二、JDBC&#xff08;Java Database Connectivity&#xff09;2.1 什么是 JDBC&#xff1f;2.2 JDBC 核心思想2.2.1 MySQL 数据库驱动2.2.2 JDBC API 2.3 环境搭建 三、JD…

面试官:请手写一个Promise

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 前言 面试官&#xff1a;请手写一个Promise&#xff1f;&#xff08;开门见山&#xff09; 我&#xff1a;既然说到Promise&#xff0c;那我肯定得先介…

RabbitMQ介绍

RabbitMQ的概念 RabbitMQ 是一个消息中间件&#xff1a;它接受并转发消息。你可以把它当做一个快递站点&#xff0c;当你要发送一个包裹时&#xff0c;你把你的包裹放到快递站&#xff0c;快递员最终会把你的快递送到收件人那里&#xff0c;按照这种逻辑 RabbitMQ 是 一个快递…

基于 Debian 12 的MX Linux 23 正式发布!

导读MX Linux 是基于 Debian 稳定分支的面向桌面的 Linux 发行&#xff0c;它是 antiX 及早先的 MEPIS Linux 社区合作的产物。它采用 Xfce 作为默认桌面环境&#xff0c;是一份中量级操作系统&#xff0c;并被设计为优雅而高效的桌面与如下特性的结合&#xff1a;配置简单、高…

微信开发之一键修改群聊备注的技术实现

修改群备注 修改群名备注后&#xff0c;如看到群备注未更改&#xff0c;是手机缓存问题&#xff0c;可以连续点击进入其他群&#xff0c;在点击进入修改的群&#xff0c;再返回即可看到修改后的群备注名&#xff0c;群名称的备注仅自己可见 请求URL&#xff1a; http://域名地…

ctfshow-红包题第二弹

0x00 前言 CTF 加解密合集CTF Web合集 0x01 题目 0x02 Write Up 同样&#xff0c;先看一下有没有注释的内容&#xff0c;可以看到有一个cmd的入参 执行之后可以看到文件代码&#xff0c;可以看到也是eval&#xff0c;但是中间对大部分的字符串都进行了过滤&#xff0c;留下了…

lvs实现DR模型搭建

目录 一&#xff0c;实现DR模型搭建 1&#xff0c; 负载调度器配置 1.1调整ARP参数 1.2 配置虚拟IP地址重启网卡 1.3 安装ipvsadm 1.4 加载ip_vs模块 1.5 启动ipvsadm服务 1.6 配置负载分配策略 1.7 保存策略 2&#xff0c; web节点配置 1.1 调整ARP参数 1.2 配置虚拟I…

Element Plus <el-table> 组件之展开行Table在项目中使用

目录 官方样式&#xff1a; 展开前&#xff1a; 展开&#xff1a; 原始代码&#xff1a; 代码详解&#xff1a; 项目使用场景&#xff1a; 完成效果&#xff1a; 具体实现范本&#xff1a; 1.调整数据结构 2. 修改标签和数据绑定 3. JavaScript 部分导入和创建对象 …

综合能源系统(8)——综合能源系统支撑技术

综合能源系统关键技术与典型案例  何泽家&#xff0c;李德智主编 1、大数据技术 1.1、大数据技术概述 大数据是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合&#xff0c;是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高…

wps设置其中几页为横版

问题&#xff1a;写文档的时候&#xff0c;有些表格列数太多&#xff0c;页面纵向显示内容不完整&#xff0c;可以给它改成横向显示。 将鼠标放在表格上一页的底部&#xff0c;点击‘插入-分页-下一页分节符’。 将鼠标放在表格页面的底部&#xff0c;点击‘插入-分页-下一页分…

【Docker入门第一篇】

Docker简介 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是完全使…

《数字图像处理-OpenCV/Python》连载(2)目录

《数字图像处理-OpenCV/Python》连载&#xff08;2&#xff09;目录 本书京东优惠购书链接&#xff1a;https://item.jd.com/14098452.html 本书CSDN独家连载专栏&#xff1a;https://blog.csdn.net/youcans/category_12418787.html 第一部分 OpenCV-Python的基本操作 第1章 …

Redis多机实现

Background 为啥要有多机--------------1.容错 2.从服务器分担读压力。 主从结构一大难题------------如何保障一致性&#xff0c;对这个一致性要求不是很高&#xff0c;因为redis是用来做缓存的 同时我们要自动化进行故障转移-------哨兵机制&#xff0c;同时哨兵也可能cra…

江西南昌电气机械三维测量仪机械零件3d扫描-CASAIM中科广电

精密机械零部件是指机械设备中起到特定功能的零件&#xff0c;其制造精度要求非常高。这些零部件通常由金属、塑料或陶瓷等材料制成&#xff0c;常见的精密机械零部件包括齿轮、轴承、螺丝、活塞、阀门等。精密机械零部件的制造需要高精度的加工设备和工艺&#xff0c;以确保其…

HJ31 单词倒排 题解

题目描述&#xff1a;单词倒排_牛客题霸_牛客网 (nowcoder.com) 对字符串中的所有单词进行倒排。 1、构成单词的字符只有26个大写或小写英文字母&#xff1b; 2、非构成单词的字符均视为单词间隔符&#xff1b; 3、要求倒排后的单词间隔符以一个空格表示&#xff1b;如果原字符…

opencv 车牌的定位与分割+UI界面

目录 一、实现和完整UI视频效果展示 主界面&#xff1a; 识别结果界面&#xff1a; 查看分割处理过程图片界面&#xff1a; 二、原理介绍&#xff1a; 加权灰度化 ​编辑 二值化 滤波降噪处理 锐化处理 边缘特征提取 图像分割 完整演示视频&#xff1a; 代码链接 …

musl libc ldso 动态加载研究笔记:动态库的搜索路径

前言 在手动设置动态库的存放路径的情况下&#xff0c;发现 musl ldso 依旧可以加载位于 /lib 目录下的 动态共享库 动态库的存放路径或者说搜索路径&#xff0c;是否可以手动配置&#xff1f;比如 Linux 上 有个配置文件可以配置&#xff0c;可以改变 动态库的搜索次序&#…

【1-3章】Spark编程基础(Python版)

课程资源&#xff1a;&#xff08;林子雨&#xff09;Spark编程基础(Python版)_哔哩哔哩_bilibili 第1章 大数据技术概述&#xff08;8节&#xff09; 第三次信息化浪潮&#xff1a;以物联网、云计算、大数据为标志 &#xff08;一&#xff09;大数据 大数据时代到来的原因…

Unity之 Vector3 的详细介绍以及方法的介绍

文章目录 总的介绍小试牛刀相关的描述的参数看个小例子 总的介绍 当涉及到Unity中的Vector3类时&#xff0c;以下是一些常用的方法和操作&#xff1a; magnitude 方法&#xff1a;返回向量的长度。 float length vector.magnitude;sqrMagnitude 方法&#xff1a;返回向量的平…

恒运资本:信创概念再度活跃,华是科技再创新高,南天信息等涨停

信创概念21日盘中再度活跃&#xff0c;截至发稿&#xff0c;华是科技涨超17%&#xff0c;盘中一度触及涨停再创新高&#xff0c;中亦科技涨超13%亦创出新高&#xff0c;久其软件、南天信息、新炬网络、英飞拓均涨停。 音讯面上&#xff0c;自8月3日以来&#xff0c;财政部官网连…