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

Redis 典型应用——缓存(缓存预热,穿透,雪崩,击穿)

一、缓存

缓存是计算机中一个很经典的概念,核心思路是把一些常用的数据放到访问速度更快的地方,方便随时读取;

但对于计算机硬件来说,往往访问速度越快的设备,成本越高,存储空间越小,缓存是更快,但空间上是不足的,因此大部分时候,缓存只存放一些热点数据;

二、Redis 用作缓存

在一个网站中,我们经常会使用关系型数据库来存储数据(例如 MySQL),虽然关系型数据库功能强大,但是性能不高(进行一次查询操作消耗的系统资源较多),性能不高的原因体现为:

  • 数据库把数据存储在硬盘上,硬盘的 IO 速度并不快,尤其是随机访问;
  • 如果查询没有命中索引,就需要进行表的遍历,大大增加硬盘 IO 次数;
  • 关系型数据库对于 SQL 的执行会做一系列的解析,校验,优化工作;
  • 如果是一些复杂查询,如联合查询,需要进行笛卡尔积操作,效率更是降低很多;

因此,如果访问数据库的并发量比较高,就很容易使数据库服务器宕机;服务器每处理一次请求,都要消耗一定的硬件资源的(CPU,内存,硬盘,网络带宽等),当一个服务器的硬件资源被耗尽的时候,后续的请求没有资源可用,就无法处理请求,甚至导致服务器代码出现崩溃; 

让数据库能够承担更大的并发量的措施主要有以下两个思路

  • 开源:引入更多的机器,部署更多的数据库实例,构成数据库集群;
  • 节流:引入缓存,保存经常访问的热点数据,从而降低直接访问数据库的请求数量;

Redis 就是一个用来作为数据库缓存的常见方案;

Redis 访问速度比 MySQL 快很多,或者说处理同一个访问请求,Redis 消耗的系统资源比  MySQL 少很多,因此 Redis 能支持的并发量更大,并且 Redis 数据在内存中,访问内存比硬盘快很多,Redis 只是支持简单的 key-value 存储,不涉及复杂查询的那么多限制规则; 

当客户端访问业务服务器,发起查询请求,业务服务器先查询 Redis,看要查询的数据是否在 Redis 中存在,如果在 Redis 中,则就直接返回,此时就不会访问 MySQL 了,如果在 Redis 中不存在,再去查询 MySQL;

缓存是用来加快 "读操作" 的速度的,如果是 "写操作",还是要写数据库,缓存并不能提高性能;

三、缓存的更新策略

缓存中应该存储哪些数据呢?如何知道哪些数据是热点数据呢?

1. 定期生成

每隔一定的周期(比如一天/一周/一个月),对于访问的数据频次进行统计(写程序来统计),挑选出访问频次最高的前 N% 的数据,存储在缓存中;

  • 优点:实现起来较简单,过程更可控(缓存中有什么是固定,更方便排查问题);
  • 缺点:实时性较低,对于一些突然情况应对的并不好;
    • 例如:平时很少会有人搜索 "春晚",因此这个关键词就不会在缓存中,而在除夕夜时,这个词就会成为非常高频的词,导致缓存失效;

2. 实时生成

先给缓存设定容量上限(可以通过 Redis 配置文件的 maxmemory 参数设定)然后用户每次查询

  • 如果在 Redis 中查到了,就直接返回;
  • 如果在 Redis 中不存在,就从数据库中查找,如果在数据库中查到了,则将查到的结果写入 Redis,否则,说明数据库中也不存在该数据;

当缓存满了的时候(缓存容量达到上限),就会触发缓存淘汰策略,把一些 "不太热门的数据" 淘汰掉;

常见的缓存淘汰策略

  • FIFO(First In First Out)先进先出:把缓存中存在时间最久的 key(最先存的)淘汰掉;
  • LRU(Least Recently Used)淘汰最久未使用的:记录每个 key 的最近访问时间,把最近访问时间最老的 key 淘汰掉;
  • LFU(Least Frequently Used)淘汰访问次数最少的:记录每个 key 最近一段时间的访问次数,把访问次数最少的 key 淘汰掉;
  • Random 随机淘汰:从所有的 key 中随机进行淘汰;

Redis 内置的淘汰策略

volatile-lru:当内存不足以容纳新写数据时,从设置了过期时间的 key 中使 LRU(最近最少使)算法进行淘汰  ;

allkeys-lru:当内存不足以容纳新写数据时,从所有 key 中使用 LRU(最近最少使)算法进 行淘汰;

volatile-lfu 4.0 版本新增:当内存不足以容纳新写数据时,在过期的 key 中,使用 LFU 算法进行删除 key;

allkeys-lfu 4.0 版本新增:当内存不足以容纳新写数据时,从所有 key 中使用 LFU 算法进行淘汰;

volatile-random:当内存不足以容纳新写数据时,从设置了过期时间的 key 中,随机淘汰数 据;

allkeys-random:当内存不足以容纳新写数据时,从所有 key 中随机淘汰数据;

volatile-ttl:在设置了过期时间的 key 中,根据过期时间进行淘汰,越早过期的优先被淘汰;(相当于 FIFO只不过是局限于过期的 key)   ;

noeviction:默认策略,当内存不足以容纳新写数据时,新写操作会报错;

下面内容以使用 Redis 作为 MySQL 的缓存为例

四、缓存预热(Cache preheating)

1. 解释

当 Redis 刚刚启动,或者 Redis 大批 key 失效之后,此时由于 Redis 内部相当于是空着的,没啥缓存数据,那么 MySQL 就会被直接访问到,从而使 MySQL 面临较大的压力;

2. 解决办法

因此就需要提前把热点数据准备好,直接写入到 Redis 中,使 Redis 可以尽快为 MySQL 撑起保护伞,热点数据可以基于统计生成;

这份热点数据不一定非得那么 "准确",只要能帮 MySQL 抵挡大部分请求即可,随着程序运行的推移,缓存的热点数据会逐渐自动调整,来更适应当前情况;

五、缓存穿透(Cache penetration)

1. 解释

访问的 key 在 Redis 和数据库中都不存在,此时这样的 key 不会被放到缓存上,后续如果仍然在访问该 key,依然会访问到数据库,这就会导致数据库承担的请求太多,压力很大;

2. 产生原因

  • 业务设计不合理,比如缺少必要的参数校验环节,导致非法的 key 也被进行查询了;
  • 误操作不小心把部分数据从数据库上误删了;
  • 黑客恶意攻击

3. 解决办法

  • 针对数据库上也不存在的 key,也存储到 Redis 中,比如 value 就随便设成一个 "",避免后续频繁访问数据库;
  • 使用布隆过滤器(hash + bitmap)先判定 key 是否存在,再真正查询;

六、缓存雪崩(Cache avalanche)

1. 解释

短时间大量的 key 在缓存上失效,导致数据库压力骤增,甚至宕机;比如,我们在同一时间,针大量的 key 设置了相同的过期时间,那当过期时间到来时,大量的 key 就会被删除从而失效;

2. 产生原因

  • Redis 宕机;
  • Redis 上大量的 key 同时过期;

3. 解决办法

  • 部署高可用的 Redis 集群,并且完善监控报警体系;
  • 不给 key 设置过期时间,或设置过期时间时添加随机时间因子(避免同时过期);

七、缓存击穿(Cache breakdown)

1. 解释

缓存雪崩的特殊情况,针对热点 key,突然过期了,导致大量访问该 key 的请求直接访问到数据库,引起数据库宕机;

2. 解决办法

  • 基于统计的方式发现热点 key,并设置永不过期或逻辑过期;
  • 访问数据库时,使用分布式锁,限制同时请求数据库的并发数;

相关文章:

Redis 典型应用——缓存(缓存预热,穿透,雪崩,击穿)

一、缓存 缓存是计算机中一个很经典的概念,核心思路是把一些常用的数据放到访问速度更快的地方,方便随时读取; 但对于计算机硬件来说,往往访问速度越快的设备,成本越高,存储空间越小,缓存是更…...

Sharding-JDBC分库分表的基本使用

前言 传统的小型应用通常一个项目一个数据库,单表的数据量在百万以内,对于数据库的操作不会成为系统性能的瓶颈。但是对于互联网应用,单表的数据量动辄上千万、上亿,此时通过数据库优化、索引优化等手段,对数据库操作…...

7月信用卡新规下:信用卡欠的钱不用还了?

说到信用卡,现在基本上人手一张,大家都有使用过。但你知道吗,使用信用卡不是这么简单容易的事,比如会对你的贷款有影响,透支不还逾期对生活的影响,信用卡新规对持卡人和银行那边的影响。 一、只要不逾期&am…...

坑——python的redis库的decode_responses设置

python的redis库查询返回的值默认是返回字节串,可以在redis.Redis()方法中通过设置decode_responses参数,让返回值直接是字符串; 查询返回字节串是因为Redis()方法中decode_responses默认值是False: 设置decode_responses为True就…...

从项目中学习Bus-Off的快慢恢复

0 前言 说到Bus-Off,大家应该都不陌生,使用VH6501干扰仪进行测试的文章在网上数不胜数,但是一般大家都是教怎么去干扰,但是说如何去看快慢恢复以及对快慢恢复做出解释比较少,因此本文以实践的视角来讲解Bus-Off的快慢恢…...

视频参考帧和重构帧复用

1、 视频编码中的参考帧和重构帧 从下图的编码框架可以看出,每编码一帧需要先使用当前帧CU(n)减去当前帧的参考帧CU(n)得到残差。同时,需要将当前帧的重构帧CU*(n)输出,然后再读取重构帧进行预测…...

js修改scss变量

style.scss $color : var(--color,#ccc); // 默认值 #ccc .color{background: $color; } 定义了一个scss变量($color),用普通的css变量(--color)给他赋值,这里需要一个默认值,此时css变量(--co…...

【中霖教育怎么样】报考注册会计师有年龄限制吗?

【中霖教育怎么样】报考注册会计师有年龄限制吗? 申请参加注册会计师考试有没有年龄约束? 对于注册会计师的考试,不存在具体的年龄上限。而且该考试的入学门栏相对低,主要对考生的年龄下限规定。 在专业阶段,注册会计师考试要求考生具备…...

PHP验证日本手机电话号码

首先,您需要了解手机号码的规格。 根据 ,手机和PHS(个人手持电话系统)可以理解为以“070”、“080”和“090”开头的11位数字。 此外,以“050”开头的11位特定IP电话号码也将包含在该目标中。 关于以“060”开头的F…...

Qt 配置ASan

Qt 配置ASan 文章目录 Qt 配置ASan摘要关于ASan(AddressSanitizer)在Qt中配置 ASan1. 安装必要的工具2. 修改项目的 .pro 文件3. 重新构建项目4. 运行应用程序5. 分析错误报告示例注意事项 关键字: Qt、 ASan、 AddressSanitizer 、 GCC …...

MySQL常用操作命令大全

文章目录 一、连接与断开数据库1.1 连接数据库1.2 选择数据库1.3 断开数据库 二、数据库操作2.1 创建数据库2.2 查看数据库列表2.3 删除数据库 三、表操作3.1 创建表3.2 查看表结构3.3 修改表结构3.3.1 添加列3.3.2 删除列3.3.3 修改列数据类型 3.4 删除表 四、数据操作4.1 插入…...

有人物联的串口服务器USR-TCP232-410S基本测试通信和使用方案(485串口和232串口)

1.将 410S(USR-TCP232-410S,简称 410S 下同)的串口通过串口线(或USB 转串口线)与计算机相连接,通过网线将 410S 的网口 PC 的网口相连接,检测硬件连接无错误后,接入我们配送的电源适配器,给 410S 供电。观察指示灯状态…...

二维码登录的原理

二维码登录的原理: 二维码登录是一种基于移动设备和网络技术的便捷登录方式。其原理主要依赖于以下几个关键要素: 随机生成:服务器端随机生成一个具有唯一性和时效性的二维码。编码信息:这个二维码包含了特定的登录信息,例如用户标识、会话标识、时间戳等。扫描识别:用户…...

归并排序详解(递归与非递归)

归并排序是建立在归并操作上的一种有效算法。该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列间断有序。若将两个有序表合并成一个有序表,成为二路归并。 一…...

计算机系统基础(二)

1.数值数据的表示 为什么采用二进制? 二进制只有两种基本状态,两个物理器件就可以表示0和1二进制的编码、技术、运算规则都很简单0和1与逻辑命题的真假对应,方便通过逻辑门电路实现算术运算 数值数据表示的三要素 进位记数制(十…...

vue根据文字长短展示跑马灯效果

介绍 为大家介绍一个我编写的vue组件 auto-marquee ,他可以根据要展示文本是否超出展示区域,来判断是否使用跑马灯效果,效果图如下所示 假设要展示区域的宽度为500px,当要展示文本的长度小于500px时,只会展示文本&…...

leetcode-21-回溯-全排列及其去重

一、[46]全排列 给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例: 输入: [1,2,3]输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] 其中,不需要使用startIndex used数组,其实就是记录此时path里都有哪些元素…...

如何根据两个关键字查询报错日志的位置

1、查找两个关键字(无顺序要求) 如果你不关心这两个关键字出现的顺序,你可以使用egrep(等同于grep -E)或grep的-E选项来启用扩展正则表达式,并使用管道(|)来组合两个搜索模式。 gr…...

短视频预算表:成都柏煜文化传媒有限公司

短视频预算表:精打细算,打造高质量视觉盛宴 在数字时代,短视频以其独特的魅力迅速占领了互联网内容的半壁江山,成为品牌宣传、文化传播乃至个人表达的重要载体。然而,每一个成功的短视频背后,都离不开一份…...

【Llama 2的使用方法】

Llama 2是Meta AI(Facebook的母公司Meta的AI部门)开发并开源的大型语言模型系列之一。Llama 2是在其前身Llama模型的基础上进行改进和扩展的,旨在提供更强大的自然语言处理能力和更广泛的应用场景。 以下是Llama 2的一些关键特性和更新点&am…...

mysql-sql-第十三周

学习目标: sql 学习内容: 37.查询各科成绩最高分、最低分和平均分: 以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率 及格为>60,中等为:70-80,优良为:80-90,优秀…...

【Android】ViewPage2嵌套Fragment+SeekBar横向滑动冲突

问题描述 ViewPage2嵌套FragmentSeekBar,拖动SeekBar的进度条时,触发ViewPage2的滑动。 解决方案: 方案一:通过事件总线ViewPage2的isUserInputEnabled属性 子Fragment: class SeekBarFragment : Fragment() {priv…...

【408考点之数据结构】图的遍历

图的遍历 图的遍历是指从图中的某个顶点出发,按照一定的规则访问图中所有顶点,并使每个顶点仅被访问一次。图的遍历包括两种主要方法:深度优先搜索(DFS)和广度优先搜索(BFS)。这两种遍历方法在…...

自动驾驶---Motion Planning之多段五次多项式

1 前言 在之前的博客系列文章中和读者朋友们聊过Apollo的 Motion Planning方案: 《自动驾驶---Motion Planning之LaneChange》 《自动驾驶---Motion Planning之Path Boundary》 《自动驾驶---Motion Planning之Speed Boundary》 《自动驾驶---Motion Planning之轨迹Path优化》…...

Linux基础IO操作详解

C文件IO相关接口 fopen函数 pathname: 要打开的文件名字符串mode: 访问文件的模式 模式描述含义“r”读文件不存在失败返回null“r”读写文件不存在打开失败返回null,文件存在则从头开始覆盖现有的数据(不会清空数据)“w”写文件不存在创建…...

轻松掌握:Hubstudio指纹浏览器如何接入IPXProxy代理IP

​代理IP对于保护个人和企业网络安全起到了至关重要的作用,然而在需要多个工作的时候,就需要搭配指纹浏览器来使用。其中Hubstudio指纹浏览器就可以模拟多个浏览器环境,然而有些用户不知道如何将Hubstudio和代理IP一起使用,下面以…...

React小记(五)_Hooks入门到进阶

React 16.8 版本 类组件 和 函数组件 两种组件共存,到目前 React 18 版本,官方已经不在推荐使用类组件,在函数组件中 hooks 是必不可少的,它允许我们函数组件像类组件一样可以使用组件的状态,并模拟组件的生命周期等一…...

使用工业自动化的功能块实现大语言模型应用

大语言模型无所不能? 以chatGPT为代表的大语言模型横空出世,在世界范围内掀起了一场AI革命。给人的感觉似乎大模型语言无所不能。它不仅能够生成文章,图片和视频,能够翻译文章,分析科学和医疗数据,甚至可以…...

PPT文件中,母版视图与修改权限的区别

在PPT(PowerPoint)制作过程中,母版视图和修改权限是两个重要的概念,它们各自在演示文稿的编辑、管理和分发中扮演着不同的角色。本文将从定义、功能、使用场景及区别等方面详细探讨PPT母版视图与修改权限的异同。 PPT母版视图 定…...

php简单的单例模式

本文由 ChatMoney团队出品 单例模式是一种常用的设计模式,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。在 PHP 中实现单例模式通常有三种形式:饿汉式(Eager)、懒汉式(Lazy&…...