【Redis】什么是Redis缓存 雪崩、穿透、击穿?(一篇文章就够了)

目录

什么是Redis?

Redis的正常存储流程?

什么是Redis缓存雪崩?

缓存雪崩

缓存预热

缓存失效时间的随机性

什么是Redis缓存穿透?

缓存穿透

缓存空对象

BloomFilter(布隆过滤器)

什么是Redis缓存击穿?

缓存击穿

互斥锁

逻辑过期时间


什么是Redis?

        Redis:是一种高性能开源的基于内存的,采用键值对存储的非关系型数据库,不保证数据的ACID特性【事务一旦提交,都不会进行回滚】

        采用键值对存储数据在内存或磁盘中,可以对关系型数据库起到补充作用,同时支持持久化[可以将数据保存在可掉电设备中],可以将数据同步保存到磁盘。

说Redis很快是相对于关系型数据库如mysql来说的,主要有以下因素

    第一,数据结构简单,所以速度快【采用键值对的方式】;

    第二,基于内存进行存储,不需要存储数据库,所以速度快;

    第三,采用多路IO复用模型,减少网络IO的时间消耗,避免大量的无用操作,所以速度快;

    第四,单线程避免了线程切换和上下文切换产生的消耗,所以速度快;

Redis的正常存储流程?

        正常流程:当用户访问服务端时,服务端会去访问Redis缓存中是否有该数据的缓存,如果有,就直接返回;如果没有,就去数据库进行查询;查询到结果过后直接返回给客户端,并且将查询的结果数据同步到redis缓存当中。

 

什么是Redis缓存雪崩?

缓存雪崩

        是指在某一时刻缓存中的存储的数据同时大量地失效,而且这些数据都是经常被访问的数据(比如热点文章,热门商品等),这样就会导致大量的请求都会落到数据库上,造成数据库的压力瞬间增大,从而导致服务器宕机,形成一种“雪崩”效应。

        简单来说,就是大量的redis同一时间大面积的失效,大量的请求直接打到数据库上(导致数据库压力飙升),这种现象就是缓存雪崩。

        解决缓存雪崩的方法有很多,其中一种比较常见的方法是采用“缓存预热”和“缓存失效时间的随机性”两种手段来解决。

缓存预热

        是指系统上线后,将相关的缓存数据直接加载到缓存中,这样一来,第一个请求过来的时候,就可以直接在缓存中获取到数据,而不需要去数据库中查询。

缓存失效时间的随机性

        是指在设置缓存的失效时间时,不能够将所有缓存的失效时间都设置为相同的值,而是要在一个合理的时间范围内进行随机,这样可以避免缓存在某一时刻大量失效的情况。

下面是一个采用了缓存预热和缓存失效时间的随机性的Java代码:

public class UserService {private static final Random RANDOM = new Random();private RedisTemplate<String, User> redisTemplate;//可以将所有的初始化需要执行的代码放在一个单独的类中,使用@Scheduled或quartz或xxl-job定时控制执行public UserService(RedisTemplate<String, User> redisTemplate) {this.redisTemplate = redisTemplate;// 缓存预热,将所有用户数据加载到缓存中List<User> users = getUsersFromDB();for (User user : users) {redisTemplate.opsForValue().set(user.getId(), user, getExpireTime());}}public User getUser(String userId) {// 先从缓存中获取数据User user = redisTemplate.opsForValue().get(userId);if (user != null) {return user;}// 缓存中没有数据,则从数据库中查询user = getUserFromDB(userId);if (user != null) {// 将数据放入缓存,并且设置一个随机的失效时间redisTemplate.opsForValue().set(userId, user, getExpireTime());}return user;}private List<User> getUsersFromDB() {// 从数据库中查询所有用户数据// ...}private User getUserFromDB(String userId) {// 从数据库中查询用户数据// ...}private long getExpireTime() {// 在30分钟到1小时之间随机一个时间作为缓存的失效时间return 1800 + RANDOM.nextInt(1800);}}

 

什么是Redis缓存穿透?

缓存穿透

        是指恶意的请求,会故意查询数据库不存在的数据,而这些数据在Redis缓存中也不存在,这样就会导致大量的请求都会落到数据库上,造成数据库的压力瞬间增大,从而导致服务器宕机。

解决缓存穿透的方法有很多,其中一种比较常见的方法是采用“缓存空对象”和“BloomFilter(布隆过滤器)两种手段来解决。

缓存空对象

        是指在查询数据库时,如果发现查询的数据不存在,那么就将这个空对象也缓存起来,这样一来,下次再查询这个不存在的数据时,就可以直接在缓存中获取到空对象,而不需要去数据库中查询。

BloomFilter(布隆过滤器)

        【Redis】布隆过滤器_布隆过滤器需要保存-CSDN博客

        是一种概率性数据结构,可以用于判断一个元素是否存在于一个集合中,它的优势在于空间复杂度低、查询速度快。

下面是一个采用了缓存空对象和BloomFilter的Java代码:

public class UserService {private RedisTemplate<String, User> redisTemplate;private BloomFilter<String> bloomFilter;public UserService(RedisTemplate<String, User> redisTemplate, BloomFilter<String> bloomFilter) {this.redisTemplate = redisTemplate;this.bloomFilter = bloomFilter;// 将所有用户的ID都放入BloomFilter中List<User> users = getUsersFromDB();for (User user : users) {bloomFilter.add(user.getId());}}public User getUser(String userId) {// 先判断BloomFilter中是否存在该IDif (!bloomFilter.mightContain(userId)) {return null;}// 再从缓存中获取数据User user = redisTemplate.opsForValue().get(userId);if (user != null) {return user;}// 缓存中没有数据,则从数据库中查询user = getUserFromDB(userId);if (user != null) {// 将数据放入缓存redisTemplate.opsForValue().set(userId, user, 3600);} else {// 将空对象放入缓存redisTemplate.opsForValue().set(userId, null, 300);}return user;}private List<User> getUsersFromDB() {// 从数据库中查询所有用户数据// ...}private User getUserFromDB(String userId) {// 从数据库中查询用户数据// ...}}
``

 

什么是Redis缓存击穿?

缓存击穿

        是指某个热点数据在缓存中失效了,而且这个数据也是经常被访问的数据,这样就会导致大量的请求都会落到数据库上,造成数据库的压力瞬间增大,从而导致服务器宕机。

解决缓存击穿的方法有很多,其中一种比较常见的方法是采用“互斥锁”和“逻辑过期时间”两种手段来解决。

互斥锁

        是指在查询数据库时,如果发现缓存中的数据已经失效,那么就先获取一个互斥锁,然后再去查询数据库,这样一来,只有一个线程去访问数据库,将查询到的数据同步到缓存当中,其他线程就直接从缓存中获取了,就可以避免大量的请求都会落到数据库上。

逻辑过期时间

        是指在查询数据库时,如果发现缓存中的数据已经失效,那么就先将数据库中的数据缓存起来,但是不将这个数据的过期时间设置为实际的过期时间,而是将过期时间设置为一个较短的时间,这样一来,就可以避免缓存中的数据一直都是“冷”数据。

下面是一个采用了互斥锁和逻辑过期时间的Java代码:

public class UserService {private RedisTemplate<String, User> redisTemplate;private RedissonClient redissonClient;public UserService(RedisTemplate<String, User> redisTemplate, RedissonClient redissonClient) {this.redisTemplate = redisTemplate;this.redissonClient = redissonClient;}public User getUser(String userId) {// 先从缓存中获取数据User user = redisTemplate.opsForValue().get(userId);if (user != null && !user.isExpired()) {return user;}// 获取互斥锁RLock lock = redissonClient.getLock("user:" + userId);try {if (lock.tryLock(10, 5, TimeUnit.SECONDS)) {// 再次从缓存中获取数据user = redisTemplate.opsForValue().get(userId);if (user != null && !user.isExpired()) {return user;}// 从数据库中查询数据user = getUserFromDB(userId);if (user != null) {// 将数据放入缓存,并且设置一个逻辑过期时间redisTemplate.opsForValue().set(userId, user, 3600);user.setExpireTime(System.currentTimeMillis() + 300000);}}} finally {// 释放互斥锁if (lock != null && lock.isHeldByCurrentThread()) {lock.unlock();}}return user;}private User getUserFromDB(String userId) {// 从数据库中查询用户数据// ...}}public class User {private String id;private String name;private long expireTime;public User(String id, String name) {this.id = id;this.name = name;this.expireTime = System.currentTimeMillis() + 300000;}public String getId() {return id;}public String getName() {return name;}public boolean isExpired() {return System.currentTimeMillis() > expireTime;}}

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

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

相关文章

VBA高级应用30例应用2实现在列表框内及列表框间实现数据拖动

《VBA高级应用30例》&#xff08;版权10178985&#xff09;&#xff0c;是我推出的第十套教程&#xff0c;教程是专门针对高级学员在学习VBA过程中提高路途上的案例展开&#xff0c;这套教程案例与理论结合&#xff0c;紧贴“实战”&#xff0c;并做“战术总结”&#xff0c;以…

深度学习简单概述

概述 理论上来说&#xff0c;参数越多的模型复杂度越高、容量越大&#xff0c;这意味着它能完成更复杂的学习任务。但复杂模型的训练效率低&#xff0c;易陷入过拟合。随着云计算、大数据时代的到来&#xff0c;计算能力的大幅提高可以缓解训练的低效性&#xff0c;训练数据的…

大型零售企业总部到分公司数据发放,有没有更优化的方案?

大型零售企业在市场经济中扮演重要角色&#xff0c;是保证基础商品生产、流通和供给的重要一环。随着企业发展&#xff0c;很多大型零售企业都会在全国、乃至全球各地开设分公司&#xff0c;用以降低生产和运营成本&#xff0c;更好地提供本地化服务。 为了保证总部与分公司间信…

GAT1399协议分析(9)--图像上传

一、官方定义 二、wirechark实例 有前面查询的基础,这个接口相对简单很多。 请求: 文本化: POST /VIID/Images HTTP/1.1 Host: 10.0.201.56:31400 User-Agent: python-requests/2.32.3 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive content-type:…

软件游戏提示msvcp120.dll丢失的解决方法,总结多种靠谱的解决方法

在电脑使用过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“找不到msvcp120.dll”。那么&#xff0c;msvcp120.dll是什么&#xff1f;它对电脑有什么影响&#xff1f;有哪些解决方法&#xff1f;本文将从以下几个方面进行探讨。 一&#xff0c;了解msv…

【漏洞复现】Apache OFBiz 路径遍历导致RCE漏洞(CVE-2024-36104)

0x01 产品简介 Apache OFBiz是一个电子商务平台&#xff0c;用于构建大中型企业级、跨平台、跨数据库、跨应用服务器的多层、分布式电子商务类应用系统。是美国阿帕奇(Apache)基金会的一套企业资源计划(ERP)系统。该系统提供了一整套基于Java的Web应用程序组件和工具。 0x02 …

docker从入门到精通

一、Docker基本命令 1. Docker的常用命令 帮助命令 docker version # docker版本信息 docker info # 系统级别的信息&#xff0c;包括镜像和容器的数量 docker 命令 --help 帮助文档 镜像命令 docker images 查看所有本地主机上的镜像 [rootiZ2zeg4ytp0whqtmxbsqiiZ…

C++ MPI多进程并发

下载 用法 mpiexec -n 8 $PROCESS_COUNT x64\Debug\$TARGET.exe 多进程并发启动 mpiexec -f hosts.txt -n 3 $PROCESS_COUNT x64\Debug\$TARGET.exe 联机并发进程&#xff0c;其它联机电脑需在相同路径下有所有程序 //hosts.txt 192.168.86.16 192.168.86.123 192.168…

八、C语言:操作符详解

一、移位操作符 1.1左移操作 左边丢弃&#xff0c;右边补0 1.2右移操作 算数右移&#xff1a;右边丢弃&#xff0c;左边补原符号位 逻辑右移&#xff1a;右边丢弃&#xff0c;左边补0 int main() {int a -1;int b a >> 1;printf("b%d\n",b);return 0; } 原码…

医学领域科技查新点提炼方法!---附案例分析

医学领域的查新项目研究范围较广&#xff0c;涉及基础医学、临床医学、中医学、预防医学、卫生学、特种医学等众多与人类健康和疾病有关的科学。查新目的主要包括立项、成果鉴定和报奖&#xff0c;有的期刊投稿也要求作者提供查新报告。 医学领域查新项目的两极化较明显&#…

2024年CKA模拟系统制作 | step-by-step | 1、基础环境准备

目录 一、软件环境 二、虚拟网络环境准备 1、编辑虚拟网络 2、网络设置 三、新建虚拟主机 1、新建目录 2、新建虚拟主机 四、系统安装 1、装载系统镜像 2、开启虚拟机 3、选择语言 4、键盘选择 5、网络配置 6、代理设置 7、设置软件源 8、存储设置 9、名称设置 …

Edge浏览器视频画中画可拉动进度条插件Separate Window

平时看一些视频的时候&#xff0c;一般需要编辑一些其他的东西&#xff0c;于是开启画中画&#xff0c;但是画中画没有进度条&#xff0c;需要大幅度的倒退前进得回到原视频&#xff0c;很麻烦。这里推荐插件Separate Window&#xff0c;可实现画中画进度条拉动和播放sudu的调节…

Qt图标字体文件中提取字体保存为图片

本文借用别人写的一个IconHelper来做说明。 1. 加载一个字体文件 QScopedPointer<IconHelper> iconHelper(new IconHelper(":/fa-regular-400.ttf", "Font Awesome 6 Pro Regular"));构造函数 IconHelper::IconHelper(const QString &fontFile…

JS(JavaScript)的引用方式介绍与代码演示

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

手机自动化测试:4.通过appium inspector 获取相关app的信息,以某团为例,点击,搜索,获取数据等。

0.使用inspector时&#xff0c;一定要把不相关的如weditor啥的退出去&#xff0c;否则&#xff0c;净是事。 1.从0开始的数据获取 第一个位置&#xff0c;有时0.0.0.0&#xff0c;不可以的话&#xff0c;你就用这个。 第二个位置&#xff0c;抄上。 直接点击第三个启动。不要…

cocos creator3.7版本拖拽事件处理

前言&#xff1a;网上能找到的资料都太落后了&#xff0c;导致哥们用AI去写&#xff0c;全是瞎B写&#xff0c;版本都不对。贴点实际有用的。别老捣鼓你那破convertToNodeSpaceAR或者convertToNodeSpace了。 核心代码 touch.getDeltaX() touch.getDeltaY() 在cocoscreator3…

STM32-15-DMA

STM32-01-认识单片机 STM32-02-基础知识 STM32-03-HAL库 STM32-04-时钟树 STM32-05-SYSTEM文件夹 STM32-06-GPIO STM32-07-外部中断 STM32-08-串口 STM32-09-IWDG和WWDG STM32-10-定时器 STM32-11-电容触摸按键 STM32-12-OLED模块 STM32-13-MPU STM32-14-FSMC_LCD 文章目录 STM…

数据挖掘--认识数据

数据挖掘--引论 数据挖掘--认识数据 数据挖掘--数据预处理 数据挖掘--数据仓库与联机分析处理 数据挖掘--挖掘频繁模式、关联和相关性&#xff1a;基本概念和方法 数据挖掘--分类 数据挖掘--聚类分析&#xff1a;基本概念和方法 数据对象与属性类型 属性&#xff1a;是一…

csrf与xss差别 别在弄乱了 直接靶场实操pikachu的csrf题 token绕过可以吗???

我们现在来说说这2个之间的关系&#xff0c;因为昨天的我也没有弄清楚这2者的关系&#xff0c;总感觉迷迷糊糊的。 xss这个漏洞是大家并不怎么陌生&#xff0c;导致xss漏洞的产生是服务器没有对用户提交数据过滤不严格&#xff0c;导致浏览器把用户输入的当作js代码返回客户端…

Selenium时间等待_显示等待

特点&#xff1a; 针对具体元素进行时间等待 可以自定义等待时长和间隔时间 按照设定的时间&#xff0c;不断定位元素&#xff0c;定位到了直接执行下一步操作 如在设定时间内没定位到元素&#xff0c;则报错&#xff08;TimeOutException&#xff09; 显示等待概念&#x…