缓存失效问题

news2024/12/24 9:13:32

目录

一、缓存穿透

二、缓存雪崩

三、缓存击穿

本地锁 

分布式锁-使用redis存储key

阶段一

阶段二

阶段三

阶段四


一、缓存穿透

缓存穿透 是指 查询一个一定不存在的数据 ,由于缓存是不命中,将去查询数据库,但是数据库也无此记录,我们没有将这次查询的 null 写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。
在流量大时 ,可能 DB 就挂掉了,要是有人利用不存在的 key 频繁攻击我们的应用,这就是漏洞。
解决:
缓存空结果、并且设置短的过期时间。

二、缓存雪崩

缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到 DB DB 瞬时压力过重雪崩。
解决:
原有的失效时间基础上增加一个随机值 ,比如 1-5 分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

三、缓存击穿

对于一些设置了过期时间的 key ,如果这些 key 可能会在某些时间点被超高并发地访问,是一种非常“ 热点 的数据。
这个时候,需要考虑一个问题:如果这个 key 在大量请求同时进来前正好失效,那么所有对这个 key 的数据查询都落到 db ,我们称为缓存击穿。
解决:
加锁,大量并发只让一个去查,其他人等待,查到以后释放锁,其他人获取到锁,先查缓存,就会有数据,不用去db
缓存
db
本地锁:synchronized,JUC(Lock),在分布式情况下,想要锁住所有的分布式服务,必须使用分布式锁

本地锁 

 本地锁流程如下:

       // 本地锁
        synchronized (this) {
            // 查询数据库前先再查一次缓存
            ......
            System.out.println("查询了数据库");
            // 查询数据库的业务
            ......

            // 在放开锁之前放入redis,因为存放进redis也是一次网络交互,如果放在锁外面也需要时间(此时可能被别的线程乘虚而入又查询数据库)
            ......
        }

 本地锁流程图如下:

分布式锁-使用redis存储key

锁即是lock,每次都往redis中存储key---使用setnu(原子操作),如果存放成功,那么就是拿到锁了

阶段一

问题:
1 setnx 占好了位,业务代码异常或者程序在页面过程中宕机。没有执行删除锁逻辑,这就造成了死锁
解决:
设置锁的自动过期,即使没有删除,会自动删除

阶段二

问题:
1 setnx 设置好,正要去设置过期时间,宕机。又死锁了。
解决:
设置过期时间和占位必须是原子的。 redis 支持使用 setnx ex命令(占位的同时设置过期时间)

阶段三

问题:
1 、删除锁直接删除???
如果由于业务时间很长,锁自己过期了,我们直接删除,有可能把别人正在持有的锁删除了。
解决:
占锁的时候,值指定为 uuid ,每个人匹配是自己的锁才删除

阶段四

问题:
1 、如果正好判断是当前值,正要删除锁的时候,锁已经过期,别人已经设置到了新的值。那么我们删除的是别人的锁
解决:
删除锁必须保证原子性。使用 redis+Lua 脚本完成
最终版本:
1、每个线程存放的锁要有自己的标识(uuid等)
2、占锁时存放和设置时间需要是原子性的(EX NX)
3、删锁时判断是否是自己的锁和删除操作需要是原子性的(LUA脚本,脚本一起成功或者一起失败)
        // TODO 本地锁:synchronized,JUC(Lock),在分布式情况下,想要锁住所有的分布式服务,必须使用分布式锁

        // 分布式锁 redis存lock Key来实现
        // 先去redis占坑
        String uuid = UUID.randomUUID().toString();
        Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 300, TimeUnit.SECONDS);
        if (lock) {
            Map<String, List<Catelog2Vo>> result ;
            //占坑成功
            try {
                result = getDataFromDb();
            } finally {
                String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
                // 删除key
                Long lock1 = redisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class),
                        Arrays.asList("lock"), uuid);
            }
            return result;
        } else {
            // 加锁失败  重试
            // 这里也可休眠一段时间
            return getCatelogJsonFromDBWithRedisLock(); //采用自旋的方式
        }

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

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

相关文章

matlab使用教程(10)—脚本和函数

1.概述 MATLAB 提供了一个强大的编程语言和交互式计算环境。您可以使用此语言在 MATLAB 命令行中一次输入一个命令&#xff0c;也可以向某个文件写入一系列命令&#xff0c;按照执行任何 MATLAB 函数的相同方式来执行这些命令。使用 MATLAB 编辑器或任何其他文件编辑器可以创建…

Swintransformer模型的优化

SwinTransformer模型优化 文章目录 SwinTransformer模型优化1.SwinTransformer概述2.性能瓶颈分析3.模型优化3.1.transpose消除3.2.更好的layergroup3.1.1.SliceOp3.1.2.SqueezeOp3.1.3.weight切分 4.优化效果 1.SwinTransformer概述 自从Transformer在NLP任务上取得突破性的进…

HikariDataSource类的作用和使用

HikariDataSource是一个Java数据库连接池的实现&#xff0c;它属于HikariCP连接池库。连接池是一个用于管理数据库连接的工具&#xff0c;它可以帮助优化数据库连接的创建和销毁过程&#xff0c;提高数据库操作的性能和效率。 HikariDataSource类的作用是创建和管理数据库连接…

为什么要选择文件传输软件?有哪些最佳高速文件传输软件?

是否经历过这样的场景&#xff0c;正在努力地完成工作任务&#xff0c;但是由于制作的数据无法及时传送给合作伙伴&#xff0c;工作流程被打断了&#xff1f;这听起来很令人沮丧&#xff0c;对吧&#xff1f;可是&#xff0c;这种情况在现实中并不罕见。 因此&#xff0c;需要…

微服务与Nacos概述

微服务概述 软件架构的演变&#xff1a;单体架构、垂直应用架构、流式计算架构 SOA、微服务架构和服务网格。 微服务是一种软件开发架构&#xff0c;它将一个大型应用程序拆分为一系列小型、独立的服务。每个服务都可以独立开发、部署和扩展&#xff0c;并通过轻量级的通信机…

C++ 派生类成员的标识与访问——虚基类及其派生类构造函数

虚基类的使用非常方便&#xff0c;简单&#xff0c;这是由于程序中所有类使用的都是自动生成的默认构造函数。如果虚基类声明有非默认的&#xff08;即带参的&#xff09;构造函数&#xff0c;并且没有声明默认形式的构造函数。这时&#xff0c;在整个继承关系中&#xff0c;直…

1 swagger简单案例

1.1 加入依赖 <!--swagger图形化接口--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version> </dependency><dependency><groupId>io.spri…

通过Idea部署Tomcat服务器(详细图文教学)

1.在idea中创建项目 有maven构建工具就创建maven&#xff0c;没有就正常创建一个普通的java程序 创建普通java项目 2.添加框架 3.配置 Tomcat 注意&#xff1a;创建web项目后我们需要配置tomcat才能运行&#xff0c;下面我们来进行配置。 4.添加部署 回到服务器 5.完善配置 6…

·[K8S:使用calico网络插件]:解决集群节点NotReady问题

文章目录 一&#xff1a;安装calico&#xff1a;1.1&#xff1a;weget安装Colico网络通信插件&#xff1a;1.2&#xff1a;修改calico.yaml网卡相关配置&#xff1a;1.2.1&#xff1a;查看本机ip 网卡相关信息&#xff1a;1.2.2&#xff1a;修改calico.yaml网卡interface相关信…

TEC半导体热电冷却技术在高速电主轴热变形补偿中的应用

摘要&#xff1a;电主轴Z向热变形是影响高速数控机床加工精度的主要因素&#xff0c;目前常用的补偿技术是流体介质形式的液冷和风冷&#xff0c;也出现了基于帕尔贴原理的TEC半导体冷却技术。目前TEC冷却技术在电主轴热变形补偿中存在的主要问题是无法对主轴热变形量进行直接调…

LeetCode 热题 100 JavaScript--142. 环形链表 II

给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数…

【Redis】项目使用redis做缓存除了击穿穿透雪崩我们还要考虑哪些?

文章目录 前言高并发写高并发读总结 前言 相信大家在项目中都是用过redis&#xff0c;比如用来做一个分布式缓存来提高程序的性能。 当使用到了redis来做缓存&#xff0c;那么我们就必须要考虑几个问题&#xff0c;除了缓存击穿&#xff0c;缓存穿透&#xff0c;缓存雪崩&…

【Linux命令详解 | cat命令】用于显示或连接文件

文章标题 简介一&#xff0c;参数列表二&#xff0c;使用介绍1. 显示文件内容2. 创建文件3. 连接文件4. 显示行号5. 压缩空行6. 显示特殊字符7. 显示行号和特殊字符8. 从标准输入读取9. 显示文件开头或结尾10. 备份文件11. 显示文件内容至多屏幕大小12. 转义正则表达式13. 显示…

集成学习:机器学习模型如何“博采众长”

前置概念 偏差 指模型的预测值与真实值之间的差异&#xff0c;它反映了模型的拟合能力。 方差 指模型在不同的训练集上产生的预测结果的差异&#xff0c;它反映了模型的稳定性。 方差和偏差对预测结果所造成的影响 在机器学习中&#xff0c;我们通常希望模型的偏差和方差都…

ffmpeg源码编译成功,但是引用生成的静态库(.a)报错,报错位置在xxx_list.c,报错信息为某变量未定义

背景&#xff1a;本文是对上一个文章的补充&#xff0c;在源码编译之前&#xff0c;项目是有完整的ffmpeg编译脚本的&#xff0c;只不过新增了断点调试ffmpeg&#xff0c;所以产生的上面的文章&#xff0c;也就是说&#xff0c;我在用make编译成功后&#xff0c;再去做的源码编…

快速上手React:从概述到组件与事件处理

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

3.4 网络安全管理设备

数据参考&#xff1a;CISP官方 目录 IDS (入侵检测系统)网络安全审计漏洞扫描系统VPN&#xff08;虚拟专网&#xff09;堡垒主机安全管理平台 一、IDS (入侵检测系统) 入侵检测系统&#xff08;IDS&#xff09;是一种网络安全设备&#xff0c;用于监测和检测网络中的入侵行…

OLTP和OLAP的区别以及使用场景

1、什么是OLTP&#xff1f; 全称OnLine Transaction Processing&#xff0c;联机事务处理系统&#xff0c;就是对数据的增删改查等操作 存储的是业务数据&#xff0c;来记录某类业务事件的发生&#xff0c;比如下单、支付、注册等 典型代表有Mysql、Oracle等数据库&#xff…

微服务 云原生:基于 Gogs + Drone 进行项目 CI/CD

传统构建部署 以一个简单的前后端项目来说&#xff0c;分别编写前后端的 Dockerfile 文件并构建镜像&#xff0c;然后编写 docker-compose.yml 构建部署&#xff0c;启动运行。 一个简单的例子&#xff1a; 前端&#xff1a; 项目名&#xff1a;kubemanagement-web技术栈&am…

【雕爷学编程】Arduino动手做(193)---移远 BC20 NB+GNSS模块10

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…