Redis(十六)缓存预热+缓存雪崩+缓存击穿+缓存穿透

文章目录

  • 面试题
  • 缓存预热
  • 缓存雪崩
    • 解决方案
  • 缓存穿透
    • 解决方案
  • 缓存击穿
    • 解决方案
    • 案例:高并发聚划算业务
  • 总结表格

面试题

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

缓存预热

@PostConstruct初始化数据

缓存雪崩

大量key同时过期

解决方案

  1. redis中key设置为永不过期 or 过期时间错开
  2. redis缓存集群实现高可用

主从+哨兵
Redis Cluster
开启Redis持久化机制aof/rdb,尽快恢复缓存集群

  1. 多缓存结合预防雪崩

ehcache本地缓存+redis缓存

  1. 服务降级

Hystrix或者阿里sentinel限流&降级

  1. 服务提供商

阿里云-云数据库Redis版

缓存穿透

先查redis无,后查mysql无,都查询不到该条记录,但是请求每次都会打到数据库上面去,导致后台数据库压力暴增

解决方案

  1. 空对象缓存或者缺省值

恶意攻击:不同key打入缓存,由于存在空对象缓存和缓存回写(看自己业务需求),redis中的无关紧要的key也会越写越多(设置缓存过期时间)

  1. Google布隆过滤器Guava解决(较为权威

Guava’s BloomFilter源码

白名单案例
全部合法的key都需要放入Guava版布隆过滤器+redis里面,不然数据就是返回nul
在这里插入图片描述
POM

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

YML

server.port=7777spring.application.name=redis# ========================logging=====================
logging.level.root=info
logging.level.com.atguigu.redis7=info
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n logging.file.name=redis.log
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n# ========================swagger=====================
spring.swagger2.enabled=true
#在springboot2.6.X结合swagger2.9.X会提示documentationPluginsBootstrapper空指针异常,
#原因是在springboot2.6.X中将SpringMVC默认路径匹配策略从AntPathMatcher更改为PathPatternParser,
# 导致出错,解决办法是matching-strategy切换回之前ant_path_matcher
spring.mvc.pathmatch.matching-strategy=ant_path_matcher# ========================redis单机=====================
spring.redis.database=0
# 修改为自己真实IP
spring.redis.host=192.168.1.129
spring.redis.port=6379
spring.redis.password=111111
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0# ========================alibaba.druid=====================
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/datatest?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=111111
spring.datasource.druid.test-while-idle=false# ========================mybatis===================
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.atguigu.redis7.entities# ========================redis集群=====================
#spring.redis.password=111111
## 获取失败 最大重定向次数
#spring.redis.cluster.max-redirects=3
#spring.redis.lettuce.pool.max-active=8
#spring.redis.lettuce.pool.max-wait=-1ms
#spring.redis.lettuce.pool.max-idle=8
#spring.redis.lettuce.pool.min-idle=0
##支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭
#spring.redis.lettuce.cluster.refresh.adaptive=true
##定时刷新
#spring.redis.lettuce.cluster.refresh.period=2000
#spring.redis.cluster.nodes=192.168.111.185:6381,192.168.111.185:6382,192.168.111.172:6383,192.168.111.172:6384,192.168.111.184:6385,192.168.111.184:6386

案例

@Test
public void testGuavaWithBloomFilter()
{//1 创建guava版布隆过滤器BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), 100);//2 判断指定的元素是否存在System.out.println(bloomFilter.mightContain(1));System.out.println(bloomFilter.mightContain(2));System.out.println();//3 讲元素新增进入bloomfilterbloomFilter.put(1);bloomFilter.put(2);System.out.println(bloomFilter.mightContain(1));System.out.println(bloomFilter.mightContain(2));}

在这里插入图片描述
黑名单案例
在这里插入图片描述

缓存击穿

大量的请求同时查询一个 key 时,此时这个key正好失效了,就会导致大量的请求都打到数据库上面去

解决方案

常见问题:热点key失效

在这里插入图片描述

  1. 差异失效时间,对于访问频繁的热点key,干脆就不设置过期时间
  2. 互斥跟新,采用双检加锁策略(多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存)

案例:高并发聚划算业务

分析
问题:热点key突然失效导致缓存击穿

升级加固

  1. 双检加锁策略

多个线程同时去查询数据库的这条数据,在第一个查询数据的请求上使用一个互斥锁来锁住它。

其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。

  1. 差异失效时间
    在这里插入图片描述
// Controller method
@RequestMapping(value = "/pruduct/find",method = RequestMethod.GET)
@ApiOperation("聚划算案例,每次1页每页5条显示")
public List<Product> find(int page, int size) {List<Product> list=null;long start = (page - 1) * size;long end   = start + size - 1;try{// 采用redis list结构里面的lrang命令来实现加载和分页查询list = redisTemplate.opsForList().range(JHS_KEY,start,end);if(CollectionUtils.isEmpty(list)){//TODO 走mysql查询}log.info("参加活动的商家:{}",list);}catch (Exception e){// 出异常了,一般redis宕机了或者redis网络抖动导致timeoutlog.error("jhs exception:{}",e);e.printStackTrace();// ....再次查询mysql}return list;
}
// 模拟数据
@PostConstruct
public void initJHSAB(){log.info("启动AB定时器计划任务天猫聚划算功能模拟.........."+DateUtil.now());//1 用线程模拟定时任务,后台任务定时将mysql里面的参加活动的商品刷新到redis里new Thread(() -> {while (true){//2 模拟从mysql查出数据,用于加载到redis并给聚划算页面显示List<Product> list = this.getProductsFromMysql();//3 先更新B缓存且让B缓存过期时间超过A缓存,如果A突然失效了还有B兜底,防止击穿redisTemplate.delete(JHS_KEY_B);redisTemplate.opsForList().leftPushAll(JHS_KEY_B,list);redisTemplate.expire(JHS_KEY_B,86410L,TimeUnit.SECONDS);//4 再更新A缓存redisTemplate.delete(JHS_KEY_A);redisTemplate.opsForList().leftPushAll(JHS_KEY_A,list);redisTemplate.expire(JHS_KEY_A,86400L,TimeUnit.SECONDS);//5 定时更新缓存,模拟聚划算一天执行的参加活动的品牌try { TimeUnit.MINUTES.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }}},"t1").start();

总结表格

在这里插入图片描述

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

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

相关文章

基于大数据的智能家居销量数据分析

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

[HTML]Web前端开发技术28(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;佬佬会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

HTTP概要

文章目录 什么是HTTP?URL的结构请求报文结构请求方法GETHEADPOSTPUTDELETETRACEOPTIONSCONNECTPATCH解释 请求头字段 响应报文结构响应状态响应头字段 HTTP会话3次握手无状态协议 什么是HTTP? HTTP&#xff0c;即Hypertext Transfer Protocol(超文本传输协议) 它是一个”请…

Linux——简单的Shell程序

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、Shell程序思路二、Shell代码展示 一、Shell程序思路 用下图的时间轴来表示事件的发生次序…

XUbuntu22.04之解决:systemd-journald占用cpu过高问题(二百一十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Linux运维-Web服务器的配置与管理(PHP)

Web服务器的配置与管理(PHP) 项目场景 某企业在CentOS上搭建Web服务系统&#xff0c;以PHP作为网页开发环境&#xff0c;以MySQL为后台数据库。 基础知识 PHP PHP原始为Personal Home Page的缩写&#xff0c;已经正式更名为 “PHP: Hypertext Preprocessor”&#xff08;超…

iOS面试:4.多线程GCD

一、多线程基础知识 1.1 什么是进程&#xff1f; 进程是指在系统中正在运行的一个应用程序。对于电脑而已&#xff0c;你打开一个软件&#xff0c;就相当于开启了一个进程。对于手机而已&#xff0c;你打开了一个APP&#xff0c;就相当于开启了一个进程。 1.2 什么是线程&am…

算法题目中图和树的存储

邻接表的方式存储图和树 这就是邻接表&#xff0c;就是将每个结点的孩子结点用链表表示出来&#xff0c;再将所有结点以数组形式连起来。 存储树和图我们需要三个数组&#xff0c;h[N], e[N], ne[N],分别表示邻接表&#xff0c;结点值&#xff0c;结点的next值&#xff0c;h[i…

面试经典150题——快乐数

​"Success is not final, failure is not fatal: It is the courage to continue that counts." - Winston Churchill 1. 题目描述 2. 题目分析与解析 2.1 思路一 还是最简单的&#xff0c;模拟最直观的思路&#xff0c;就是进行一个while循环。比如&#xff1a;…

yolov8-seg dnn调用

接上篇一直更换torch、opencv版本都无法解决这个问题&#xff08;seg调用dnn报错&#xff09;。那问题会不会出在yolov8源码本身呢。yolov8的讨论区基本都看过了&#xff0c;我决定尝试在其前身yolov5的讨论区上找找我不信没人遇到这个问题。很快找到下面的讨论第一个帖子&…

20个改善编码的Python异常处理技巧,让你的代码更高效

异常处理是写好代码的一个重要的方面&#xff0c;虽然许多开发人员都熟悉基本的try-except块&#xff0c;但是有很多更深入的知识可以使异常处理更高效、更可读和更python化。所以本文将介绍关于Python异常的20个可以显著改善编码的Python异常处理技巧&#xff0c;这些技巧可以…

软件性能测试和功能测试有何联系和区别?第三方软件检测机构简析

软件性能测试和功能测试是软件开发过程中非常重要的两个环节。从根本上说&#xff0c;它们都是为了保证软件质量和可靠性&#xff0c;但它们的目标和方法却有所不同。 软件性能测试是评估软件在特定负载下的性能表现&#xff0c;包括响应时间、吞吐量、并发能力等指标。它通过…

Jenkins详解

目录 一、Jenkins CI/CD 1、 Jenkins CI/CD 流程图 2、介绍 Jenkins 1、Jenkins概念 2、Jenkins目的 3、特性 4、产品发布流程 3、安装Jenkins 1、安装JDK 2、安装tomcat 3.安装maven 4安装jenkins 5.启动tomcat&#xff0c;并页面访问 5.添加节点 一、Jenkins CI/…

Opencv实战(2)绘图与图像操作

Opencv实战(2)绘图与图像操作 指路前文&#xff1a;Opencv实战(1)读取与像素操作 三、基本绘图 文章目录 Opencv实战(2)绘图与图像操作三、基本绘图(1).line(2).rectangle(3).circle 四、图像处理(1).颜色空间1.意义2.cvtColor()3.inRange()4.适应光线 (2).形态操作1.腐蚀2.膨…

Python语句(一)【条件语句】

条件语句&#xff1a;通过一条或多条语句的执行结果&#xff08;True或者False&#xff09;来决定执行的代码块。 其程序流程图如下&#xff1a; 条件语句包括&#xff1a;if 判断条件&#xff1a;执行语句…… else&#xff1a;执行语句……orif 判断条件1:执行语句1…… el…

电商+支付双系统项目------项目部署到服务器

我已经把这个项目的所有模块都做好了。那么&#xff0c;现在我们要做的就是将这个项目部署发布了。其实关于部署发布网上有很多的文章都会教&#xff0c;我就不写哪些很具体的步骤了&#xff0c;我就简单的总结一下怎么部署这个项目&#xff0c;让大家对项目部署有一个整体的认…

kubernetes的网络flannel与caclio

flannel网络 跨主机通信的一个解决方案是Flannel&#xff0c;由CoreOS推出&#xff0c;支持3种实现&#xff1a;UDP、VXLAN、host-gw udp模式&#xff1a;使用设备flannel.0进行封包解包&#xff0c;不是内核原生支持&#xff0c;上下文切换较大&#xff0c;性能非常差 vxlan模…

瑞_23种设计模式_装饰者模式

文章目录 1 装饰者模式&#xff08;Decorator Pattern&#xff09;1.1 介绍1.2 概述1.3 装饰者模式的结构 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代码实现 4 JDK源码解析5 总结5.1 装饰者模式的优缺点5.2 装饰者模式的使用场景5.3 装饰者模式 VS 代理模式 &#x…

dpdk环境搭建和工作原理

文章目录 1、DPDK环境搭建1.1、环境搭建1.2、编译DPDK 2、DPDK工作原理 1、DPDK环境搭建 1.1、环境搭建 工具准备&#xff1a;VMware、ubuntu16.04。 &#xff08;1&#xff09;VMware添加两个网卡。桥接网卡作为 DPDK 运行的网卡&#xff0c;NAT 网卡作为 ssh 连接的网卡。 …

【动态规划】【前缀和】【推荐】2463. 最小移动总距离

作者推荐 【广度优先搜索】【网格】【割点】【 推荐】1263. 推箱子 本文涉及知识点 动态规划汇总 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 2463. 最小移动总距离 X 轴上有一些机器人和工厂。给你一个整数数组 robot &#xff0c…