当前位置: 首页 > news >正文

Redis-预热雪崩击穿穿透

预热雪崩穿透击穿

缓存预热

缓存雪崩

有这两种原因

  1. redis key 永不过期or过期时间错开
  2. redis 缓存集群实现高可用
    1. 主从哨兵
    2. Redis Cluster
    3. 开启redis持久化aof,rdb,尽快恢复集群
  3. 多缓存结合预防雪崩:本地缓存 ehcache + redis 缓存
  4. 服务降级:Hystrix 或者 sentinel 限流降级
  5. 人民币玩家:阿里云给了你多少广告?笑

缓存穿透

恶意请求不存在的数据

  1. guava BloomFilter

  • 误判问题,但是概率小可以接受,不能从布隆过滤器删除 -> 布隆过滤器可能会错误地判断某个元素存在于集合中(称为误报),但不会错误地判断一个存在的元素不存在
  • 全部合法的key都需要放入 Guava布隆过滤器+redis里面,不然数据就是返回null

案例

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.1-jre</version>
</dependency>
@Service
@Slf4j
public class GuavaBloomFilterService {// 1.定义一个常量public static final int _1W = 10000;// 2.定义我们guava布隆过滤器,初始容量public static final int SIZE = 100 * _1W;// 3.误判率,它越小误判的个数也越少(思考:是否可以无限小? 没有误判岂不是更好)public static double fpp = 0.0000000000003;  // 这个数越小所用的hash函数越多,bitmap占用的位越多  默认的就是0.03,5个hash函数   0.01,7个函数// 4.创建guava布隆过滤器private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), SIZE, fpp);public void guavaBloomFilter() {// 1. 往 bloomFilter 中添加数据for (int i = 0; i < SIZE; i++) {bloomFilter.put(i);}// 2. 故意取10w个不在范围内的数据进行测试,来进行误判率演示List<Integer> list = new ArrayList<>(10 * _1W);// 3. 验证for (int i = SIZE; i < SIZE + (10 * _1W); i++) {if (bloomFilter.mightContain(i)) {
//                log.info("被误判了:{}", i);list.add(i);}}log.info("误判总数量:{}", list.size());log.info("误判率:{}", list.size() / (10 * _1W));}
}
@SpringBootTest
public class GuavaTest {@ResourceGuavaBloomFilterService guavaBloomFilterService;/*** guava版本布隆过滤器,helloworld 入门级演示*/@Testpublic void testGuavaWithBloomFilter() {System.out.println("testGuavaWithBloomFilter");// 1. 创建 guava版布隆过滤器BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), 100);//2. 判断指定的元素是否存在System.out.println(bloomFilter.mightContain(1));System.out.println(bloomFilter.mightContain(2));// 2. 添加数据bloomFilter.put(1);bloomFilter.put(2);System.out.println(bloomFilter.mightContain(1));System.out.println(bloomFilter.mightContain(2));}@Testpublic void testGuavaWithBloomFilter2() {guavaBloomFilterService.guavaBloomFilter();}}

fpp 默认 0.03

fpp要求越高,bit位数越多,hash函数越多

guava 黑名单使用

缓存击穿

对比穿透和击穿

互斥更新->对于更新的方法

聚划算案例

功能分析

数据结构使用 list

代码

@ApiModel(value = "聚划算活动product信息")
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Product {// 产品idprivate Long id;// 产品名称private String name;// 产品价格private Integer price;// 产品详情private String detail;
}
@Service
@Slf4j
public class JHSTaskService {private static final String JHS_KEY = "jhs";private static final String JHS_KEY_A = "jhs:a";private static final String JHS_KEY_B = "jhs:b";@AutowiredRedisTemplate redisTemplate;/*** 模拟从数据库读取20件特价商品* @return 商品列表*/private List<Product> getProductsFromMysql() {List<Product> list = new ArrayList<>();for (int i = 0; i < 20; i++) {Random random = new Random();int id = random.nextInt(1000);Product product = new Product((long) id, "product" + i, i, "detail");list.add(product);}log.info("模拟从数据库读取20件特价商品完成{}", list);return list;}@PostConstructpublic void initJHSAB() {log.info("启动AB的定时器 天猫聚划算模拟开始===========");new Thread(() -> {while (true) {// 2.模拟从mysql查到数据,加到 redis 并返回给页面List<Product> list = getProductsFromMysql();redisTemplate.delete(JHS_KEY);redisTemplate.opsForList().leftPushAll(JHS_KEY, list);redisTemplate.expire(JHS_KEY, 86410L, TimeUnit.SECONDS);// 5.暂停一分钟,间隔1分钟执行一次,模拟聚划算一天执行的参加活动的品牌try {Thread.sleep(1000* 60);} catch (InterruptedException e) {e.printStackTrace();}}}, "t1").start();}}

测试类

@SpringBootTest
@Slf4j
public class JhsTest {private static final String JHS_KEY = "jhs";private static final String JHS_KEY_A = "jhs:a";private static final String JHS_KEY_B = "jhs:b";@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void find() {int page = 1;int size = 10;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 走 mysql 查询}log.info("参加活动的商家={}", list);} catch (Exception e) {// 出异常了,一般 redis 宕机了或者redis网络抖动导致timeoutlog.error("jhs exception{}", e);e.printStackTrace();//  ..... 重试机制 再次查询 mysql}log.info(list.toString());}}

测试方法,先跑主启动类(后台更新聚划算商品信息),然后手动执行测试类测试查询

问题分析

delete 执行间隙,这一瞬间缓存击穿,打到mysql

解决

@PostConstructpublic void initJHSAB() {log.info("启动AB的定时器 天猫聚划算模拟开始===========");new Thread(() -> {while (true) {// 2.模拟从mysql查到数据,加到 redis 并返回给页面List<Product> list = getProductsFromMysql();//                redisTemplate.delete(JHS_KEY);
//                redisTemplate.opsForList().leftPushAll(JHS_KEY, list);
//                redisTemplate.expire(JHS_KEY, 86410L, TimeUnit.SECONDS);// 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.暂停一分钟,间隔1分钟执行一次,模拟聚划算一天执行的参加活动的品牌try {Thread.sleep(1000* 60);} catch (InterruptedException e) {e.printStackTrace();}}}, "t1").start();}
@Testpublic void findAB() {int page = 1;int size = 10;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缓存继续顶着");// A 没有来找 Blist = redisTemplate.opsForList().range(JHS_KEY_B, start, end);if (CollectionUtils.isEmpty(list)) {// TODO 走 mysql 查询}}log.info("参加活动的商家={}", list);} catch (Exception e) {// 出异常了,一般 redis 宕机了或者redis网络抖动导致timeoutlog.error("jhs exception{}", e);e.printStackTrace();//  ..... 重试机制 再次查询 mysql}log.info(list.toString());}

小总结

相关文章:

Redis-预热雪崩击穿穿透

预热雪崩穿透击穿 缓存预热 缓存雪崩 有这两种原因 redis key 永不过期or过期时间错开redis 缓存集群实现高可用 主从哨兵Redis Cluster开启redis持久化aof&#xff0c;rdb&#xff0c;尽快恢复集群 多缓存结合预防雪崩&#xff1a;本地缓存 ehcache redis 缓存服务降级&…...

jvisualvm学习

系列文章目录 JavaSE基础知识、数据类型学习万年历项目代码逻辑训练习题代码逻辑训练习题方法、数组学习图书管理系统项目面向对象编程&#xff1a;封装、继承、多态学习封装继承多态习题常用类、包装类、异常处理机制学习集合学习IO流、多线程学习仓库管理系统JavaSE项目员工…...

Gazebo环境下开源UAV与USV联合仿真平台

推荐一个ROS2下基于Gazebo环境的开源UAV与USV联合仿真平台。平台是由两个开源项目共同搭建的。首先是UAV仿真平台&#xff0c;是基于PX4官方仿真平台&#xff08;https://docs.px4.io/main/en/sim_gazebo_gz&#xff09;&#xff1b;其次是USV仿真平台&#xff0c;是基于VRX仿真…...

Linux进程调度和进程切换

并行&#xff08;Parallel&#xff09; 含义&#xff1a;并行是指多个任务在同一时刻同时执行。 硬件要求&#xff1a;需要多个处理器&#xff08;如多核CPU&#xff09;或者多台计算设备来实现&#xff0c;这些执行单元能够真正地同时处理不同的任务。例如&#xff0c;一个具…...

机器学习基本上就是特征工程——《特征工程训练营》

作为机器学习流程的一部分&#xff0c;特征工程是对数据进行转化以提高机器学习性能的艺术。 当前有关机器学习的讨论主要以模型为中心。更应该关注以数据为中心的机器学习方法。 本书旨在介绍流行的特征工程技术&#xff0c;讨论何时以及如何运用这些技术的框架。我发现&…...

Android Framework AMS(01)AMS启动及相关初始化1-4

该系列文章总纲链接&#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节主要涉及systemserver启动AMS及初始化AMS相关操作。同时由于该部分内容分析过多&#xff0c;因此拆成2个章节&#xff0c;本章节是第一章节&…...

基于基于微信小程序的社区订餐系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

[单master节点k8s部署]29.Istio流量管理(五)

测试istio熔断管理。 采用httpbin镜像和fortio镜像&#xff0c;其中httpbin作为服务端&#xff0c;fortio是请求端。这两个的配置yaml文件都在istio的samples/httpbin目录下&#xff0c;fortio的配置文件在samples-client目录下。 [rootmaster httpbin]# ls gateway-api ht…...

Something for 24OI

zyj老师希望我给24OI的同学们写一点东西&#xff0c;虽然感觉我也没有什么先进经验&#xff0c;还是尽力写一些主观的感受吧。 如何平衡文化课和竞赛的关系&#xff1f;不要以牺牲文化课的代价学习竞赛。首先&#xff0c;绝大多数的竞赛同学&#xff0c;或早或晚都会在退役后回…...

【React】事件机制

事件机制 react 基于浏览器的事件机制自身实现了一套事件机制&#xff0c;称为合成事件。比如&#xff1a;onclick -> onClick 获取原生事件&#xff1a;e.nativeEvent onClick 并不会将事件代理函数绑定到真实的 DOM节点上&#xff0c;而是将所有的事件绑定到结构的最外层…...

华为OD的职级与薪资

华为 OD 这几年随着招聘行情的日渐严峻&#xff0c;不少 985 高校出来的学生都开始放宽对"外包"的看法&#xff0c;其中华为 OD 以"待遇断层领先"的姿态成为不少求职者&#xff08;不得已&#xff09;的外包首选。 既然如此&#xff0c;我们就好好梳理一下…...

【HTML5】html5开篇基础(4)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…...

HTTP【网络】

文章目录 HTTPURL(Uniform Resource Lacator) HTTP协议格式HTTP的方法HTTP的状态码HTTP常见的Header HTTP 超文本传输协议&#xff0c;是一个简单的请求-响应协议&#xff0c;HTTP通常运行在TCP之上 URL(Uniform Resource Lacator) 一资源定位符&#xff0c;也就是通常所说的…...

MQ延迟消息:原理、实现与应用

在现代分布式系统中&#xff0c;消息队列&#xff08;Message Queue&#xff0c;简称MQ&#xff09;已经成为实现异步通信、解耦服务和削峰填谷的重要工具。延迟消息&#xff08;Delayed Message&#xff09;作为MQ的一种高级特性&#xff0c;允许消息在指定的延迟时间后投递到…...

计算机网络—大端序和小端序

大端序和小端序 大端序&#xff08;Big-endian&#xff09;和小端序&#xff08;Little-endian&#xff09;是指在多字节数据类型&#xff08;如整数或浮点数&#xff09;的存储和表示方式上的不同。以下是关于大端序和小端序的详细解释&#xff1a; 一、定义 大端序&#xf…...

《OpenCV 计算机视觉》—— Harris角点检测、SIFT特征检测

文章目录 一、Harris 角点检测1.基本思想2.检测步骤3.OpenCV实现 二、SIFT特征检测1. SIFT特征检测的基本原理2. SIFT特征检测的特点3. OpenCV 实现 一、Harris 角点检测 OpenCV中的Harris角点检测是一种基于图像灰度值变化的角点提取算法&#xff0c;它通过计算每个像素点的响…...

rtmp协议转websocketflv的去队列积压

websocket server的优点 websocket server的好处&#xff1a;WebSocket 服务器能够实现实时的数据推送&#xff0c;服务器可以主动向客户端发送数据 1 不需要客户端不断轮询。 2 不需要实现httpserver跨域。 在需要修改协议的时候比较灵活&#xff0c;我们发送数据的时候比较…...

Elasticsearch实战应用:构建高效搜索引擎

在大数据时代&#xff0c;如何高效存储和检索海量信息成为了一个重要课题。Elasticsearch作为一个开源的分布式搜索引擎&#xff0c;以其强大的搜索能力和灵活的扩展性&#xff0c;成为了许多企业和开发者的首选。本文将深入探讨Elasticsearch的实战应用&#xff0c;包括基本概…...

Hive数仓操作(四)

一、Hive 创建表案例一&#xff08;ARRAY数组类型&#xff09; 1. 准备数据文件 首先&#xff0c;准备一个名为 stu2.txt 的文件&#xff0c;文件内容示例如下&#xff1a; 1001 Alice fish,cat 1002 Bob dog,rabbit 1003 Charlie bird注意&#xff1a; …...

《C++跨平台开发:突破界限,释放无限可能》

在当今的软件开发领域&#xff0c;跨平台开发已成为一种重要趋势。它允许开发者编写一次代码&#xff0c;然后在多个不同的操作系统和硬件平台上运行&#xff0c;极大地提高了开发效率和软件的可扩展性。而 C作为一种强大的编程语言&#xff0c;也具备实现跨平台开发的能力。本…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...