Redis——缓存
目录
·前言
一、缓存基本概念
1.概念
2.二八定律
二、使用 Redis 作为缓存
三、缓存的更新策略
1.定期生成
2.实时生成
四、Redis 内存淘汰机制
1.通用淘汰策略
(1)FIFO
(2)LRU
(3)LFU
(4)Random
2.Redis 内置的淘汰策略
(1)volatile-lru
(2)allkeys-lru
(3)volatile-lfu
(4)allkeys-lfu
(5)volatile-random
(6)allkeys-random
(7)volatile-ttl
(8)noeviction
五、缓存使用的注意事项
1.缓存预热(Cache preheating)
2.缓存穿透(Cache penetration)
3.缓存雪崩(Cache avalanche)
4.缓存击穿(Cache breakdown)
·结尾
·前言
我们都知道 Redis 的主要用途有三个方面:存储数据、作为缓存和消息队列,其中,Redis 最常用的场景就是作为缓存了,本篇文章就来和大家介绍一下缓存的基本概念,如何使用 Redis 作为缓存,缓存的更新策略有哪些,Redis 中的内存淘汰机制是怎样的,还有关于使用缓存的一些注意事项,那么就开始本篇文章的正题吧。
一、缓存基本概念
1.概念
相信大家都有过坐火车的经历,在我们坐火车时会带着一个拉杆箱,这个拉杆箱可以装很多很多的东西,如果我们把所有东西都放在了拉杆箱中,就会遇见一个问题:在我们进入火车站时,需要刷身份证进站,由于你把所有东西都放在了拉杆箱中,此时你就需要把拉杆箱放倒在地上,打开拉杆箱,翻找身份证,刷身份证进站,再把身份证放回拉杆箱,这一系列的繁琐过程结束后,才算是用身份证进入了车站,但是在后面需要刷身份证检票时、刷身份证出站时,在火车上列车员需要用身份证检验时,你都要重复上述取身份证的过程,这种方式就十分低效了,那么怎么做可以更高效呢,我想大家都是知道的,就是把身份证、手机之类经常需要使用的都放在衣服兜中,这样使用起来就会更加方便,高效。
看完上面的例子,其实我们说的缓存做的事情就类似于我们衣服兜起到的效果,缓存是计算机中的一个经典概念,其核心思路就是把一些常用的数据放到触手可及的地方,方便随时读取,在我们的计算机上,各个硬件读取速度快慢有以下的顺序:
CPU 寄存器 > 内存 > 硬盘 > 网络
速度快的设备可以作为速度慢的设备的缓存,那么我们就可以使用内存来作为硬盘的缓存,这也是 Redis 主要的用途,还可以使用硬盘来作为网络的缓存,比如浏览器中的缓存。
2.二八定律
既然缓存读取速度更快,那为什么不都用缓存来存储数据呢?这是因为缓存的内存空间往往是不足的,所以大部分情况下,缓存只是放一些热点数据(访问频繁的数据),缓存存在的意义一是因为它读取速度快,二就是因为“二八定律”。
二八定律的意思是,我们 20% 的热点数据能够应付 80% 的访问场景,所以我们只需要把这少量的热点数据放到缓存中,就可以应对大多数的场景,从而在整体上有明显的性能提升。
二、使用 Redis 作为缓存
在我们实际应用中,通常会使用 Redis 作为 Mysql 的缓存,虽然关系型数据库(Mysql)的功能强大,但是它有着一个很大的缺陷,就是性能不高,为什么性能不高,大致有以下几点原因(关系型数据库就以 MySql 为例):
- MySql 把数据存储在硬盘上,硬盘上的 IO 速度并不快,尤其是在随机访问时;
- 使用 MySql 进行查询过程中,如果查询不能命中索引,就需要进行表的遍历,这会大大的增加硬盘 IO 的次数;
- MySql 对于 SQL 在执行会做一系列的解析、校验、优化的工作;
- 如果使用 MySql 做一些复杂查询,比如:多表联合查询,需要使用笛卡尔积进行操作,效率会降低很多。
因为 MySql 等数据库有着上面的问题,所以承担的并发量就有限,一旦请求的数量多了,数据库的压力就会很大,就可能会宕机,那么如何提高 MySql 能承担的并发量呢?有以下两种方案可以做到:
- 开源:引入更多的机器,构成数据库集群;
- 节流:引入缓存,把一些频繁读取的热点数据保存到缓存中,这样后续在查询数据的时候,先在缓存中查询,如果缓存中已经存在就不再访问 MySql 了。
Redis 就是作为数据库缓存的常见方案,关于 Redis 可以作为 Mysql 缓存有以下两种原因:
- Redis 数据在内存中,访问内存速度比访问硬盘快很多;
- Redis 只是支持简单的 key-value 存储,不涉及复杂的查询的诸多限制规则。
此时当 Redis 作为 MySql 的缓存后,他们的关系,可以形象的如下图所示:
Redis 就像盾牌一样会先接收大部分的请求,少部分 Redis 上没有的数据才会请求 MySql。
注意:只有在进行读操作时,使用 Redis 作为缓存才有作用,如果进行的是写操作,那还是要对 MySql进行操作的
三、缓存的更新策略
通过上面的介绍,我们知道引入缓存的意义是用来存一些热点数据,并配合二八定律可以很好的分担 Mysql 的压力,可是什么数据是“热点数据”呢?对于存储的热点数据就有以下两种生成方式,下面来展开介绍一下这两种方式。
1.定期生成
定期生成这种策略,就是每隔一定的周期(比如一天/一周/一个月),对访问数据的频次进行统计,挑选出访问频次最高的前 N%来存储在缓存中。
使用这种策略的优缺点如下:
- 优点:定期生成的策略实现起来比较简单,过程可控,方便排查问题;
- 缺点:实时性不够,如果出现一些突发事件,有一些本来不是热词的内容突然成为了热词,新的热词就可能就数据库带来较大的压力。
关于上述缺点中的实时性有一个很好的例子,那就是在过年时搜索“春节晚会”的时候,这个词一般只会在过年期间会被人们进行搜索,并且搜索量巨大,此时由于定期生成周期还没有进行更新,就会造成这些搜索请求直接访问后面的数据库了。
2.实时生成
为了弥补上述定期生成策略的缺点,实时生成会采用动态生成热点数据的方式,我们首先需要给缓存设定容量上限(在 Redis 配置文件中的 maxmemory 参数可以设定容量上限),接下来用户的每次查询操作就会经历以下的步骤:
- 如果在 Redis 中查找到,就直接返回;
- 如果 Redis 中不存在,就从数据库中查,把查到的结果同时也写入到 Redis中。
此时,经过一段时间的“动态平衡”,Redis 中的数据就都成了热点数据了,但是同时也有一个问题,就是这样不停的往 Redis 中写数据,会导致 Redis 中的内存占用越来越多,逐渐达到内存的上限,这就出现不能继续存数据了的问题,那么针对这种问题,Redis 中有着内存淘汰这样的机制。
四、Redis 内存淘汰机制
为了解决实时生成策略引发内存满如何继续存储数据的问题,Redis 就引入了“内存淘汰”这样的机制,在介绍 Redis 的淘汰机制之前,先来介绍一些通用的淘汰策略。
1.通用淘汰策略
(1)FIFO
FIFO 的英文全称是 First In First Out 意思是先进先出,这种策略是把缓存中存在时间最久的(也就是最先来的数据)淘汰掉,然后添加新的数据。
(2)LRU
LRU 的英文全称是 Least Recently Used 意思是淘汰最近未使用的,此时,在缓存中记录每个数据最近访问的时间,把最近访问时间最老的数据淘汰掉,然后添加新的数据。
(3)LFU
LFU 的英文全称是 Least Frequently Used 意思是淘汰访问次数最少的,此时,在缓存中记录每条数据最近一段时间的访问次数,把访问次数最少的数据淘汰掉,然后添加新的数据。
(4)Random
Random 是随机淘汰的意思,这种策略会在缓存中所有的数据中随机抽取幸运儿来淘汰掉,然后再添加新的数据。
2.Redis 内置的淘汰策略
(1)volatile-lru
这种策略是当内存不足以容纳新写入的数据时,从设置了过期时间中的 key 中使用 LRU (最近最少使用)算法进行淘汰。
(2)allkeys-lru
这种策略是当内存不足以容纳新写入的数据时,从所有 key 中使用 LRU(最近最少使用)算法进行淘汰。
(3)volatile-lfu
这种策略是在 Redis 4.0 版本新增的,当内存不足以容纳新写的数据时,在过期的 key 中,使用 LFU(访问次数最少)算法进行淘汰。
(4)allkeys-lfu
这种策略是 Redis 4.0 版本新增的,当内存不足以容纳新写的数据时,从所有 key 中,使用 LFU(访问次数最少)算法进行淘汰。
(5)volatile-random
这种策略是当内存不足以容纳新写入的数据时,从设置了过期时间的 key 中,随机淘汰数据。
(6)allkeys-random
这种策略是当内存不足以容纳新写入的数据时,从所有的 key 中,随机淘汰数据。
(7)volatile-ttl
这种策略是在设置了过期时间的 key 中,根据过期时间进行淘汰,越早过期的优先被淘汰(相当于 FIFO 算法,只不过是局限于设置过期时间的 key)
(8)noeviction
这种策略是 Redis 默认策略,当内存不足以容纳新写入的数据时,新写入数据就会报错。
通过上述 Redis 中内置的淘汰策略的介绍,可以看出,Redis 默认策略不适合于实时更新缓存,以上的在 Redis 中有一个配置项,就可以设置 Redis 采取上述那种策略淘汰内存数据。至于采取哪种策略更好,就需要具体问题具体分析了。
五、缓存使用的注意事项
1.缓存预热(Cache preheating)
当我们是首次将 Redis 服务器接入整个系统来作为缓存时,Redis 服务器中是没有数据的,此时如果我们的缓存更新策略是采用定期生成的方式,就不会涉及缓存预热,但是如果我们使用的是实时生成,就会出现以下问题:
由于 Redis 服务器是首次接入,其内部没有数据,此时按照实时生成策略,客户端会先查询 Redis,如果没有查到就会再查一次 Mysql,查到之后再把数据写入到 Redis 中,在这个过程中,所有的请求就会都打给 MySql,此时的请求如果过多就会给 MySql 造成很大的压力。
缓存预热就是用来解决上述问题的,它的解决方式就是将定期生成与实时生成的两种策略进行结合,先在 Redis 服务器没有上线的时候通过统计,将热点数据找到一批,然后导入 Redis 中,此时导入的这批热点数据就可以帮 MySql 承担很大的压力,随着时间推移,Redis 中就逐渐使用新的热点数据淘汰掉旧的热点数据了。
2.缓存穿透(Cache penetration)
缓存穿透就是在查询某个 key 时,这个 key 在 Redis 中没有,MySql 中也没有,此时,由于 MySql 中也没有这个 key ,这条 key 就不会被更新到 Redis 中,但是如果出现很多这样的数据被查询,并且反复查询,请求就会全都打给 Mysql 此时就会给 MySql 带来很大的压力。出现这种问题的原因有以下几条:
- 代码设计不合理,比如缺少必要的参数校验环节,导致非法的 key 也被进行查询了;
- 在开发过程中,不小心把部分数据从数据库中误删了;
- 遭到黑客的恶意攻击。
那么如何解决缓存穿透这样的问题呢?有以下几个解决方案:
- 针对要查询的参数进行严格的合法性校验;
- 针对 Redis 和 Mysql 中都不存在的 key 仍写入到 Redis 中,将这里的 value 也设成一个非法值(比如“”);
- 引入 布隆过滤器,在每次查询 Redis/MySql 之前都先判定一下 key 是否在 布隆过滤器 上存在(把所有 key 都插入到 布隆过滤器 中)。
上述解决方法中的 布隆过滤器 是一种本质上结合了 hash 与 bitmap 的数据结构,它可以以比较小的空间开销,比较快的时间速度来实现针对 key 是否存在做出判定。
3.缓存雪崩(Cache avalanche)
缓存雪崩就是指在短时间内,Redis 上大规模的 key 失效,导致缓存命中率陡然下降,并且 MySql 的压力迅速上升,导致 MySql 直接宕机。出现这个问题的原因有主要两种:
- Redis 服务器宕机 / Redis 集群模式下大量的节点宕机;
- Redis 没有问题,但是由于之前短时间内设置的很多 key 它们的过期时间是相同的。
那么如何解决这种问题呢? 有以下几种解决方案:
- 增加并完善报警体系,争取在第一时间发现 Redis 服务器宕机;
- 部署高可用的 Redis 集群;
- 不给 key 设置过期时间 / 设置过期时间的时候添加随机的因子(避免同一时刻过期)。
4.缓存击穿(Cache breakdown)
缓存击穿可以看作缓存雪崩的特殊情况,是指热点 key 突然过期了,导致大量的请求直接访问到 MySql 中,使 MySql 服务器压力骤增甚至宕机。
解决这种问题的方式有以下几种:
- 基于统计的方式发现热点 key 并且设置永不过期;
- 进行必要的服务降级,例如访问 Mysql 的时候使用分布式锁,限制同时请求 MySql 的并发数。
·结尾
文章到此就要结束了,关于 Redis 作为缓存的意义,更新缓存中实时生成时需要用到的淘汰策略,以及在使用 Redis 作为缓存时需要注意的一些事项介绍的也差不多了,本篇文章以文字为主,希望大家可以很好的理解其中的内容,如果本篇文章对你有所帮助还是希望能得到你的三连支持咯~~如果对文章内容有什么问题,欢迎在评论区进行留言讨论,我们下一篇文章再见~~~
相关文章:

Redis——缓存
目录 前言 一、缓存基本概念 1.概念 2.二八定律 二、使用 Redis 作为缓存 三、缓存的更新策略 1.定期生成 2.实时生成 四、Redis 内存淘汰机制 1.通用淘汰策略 (1)FIFO (2)LRU (3)LFU &#…...

RHCSA笔记三
第二章 linux中执行命令 命令格式 命令分为两类 内置命令:由 shell 程序自带的命令 外部命令:有独立的可执行程序文件,文件名即命令名 格式 主命令 参数 操作对象 # 注意: 下面是对于命令的语法的一些符号的说明࿱…...
【python】sorted() list.sort()
文章目录 sorted()和list.sort()sorted 函数sorted()根据键对字典排序根据字典的键排序根据字典的值排序将排序结果转换回字典 list.sort() 方法总结 keylambda student: student[age] sorted()和list.sort() 在Python中,sorted 函数和 list.sort() 方法都可以用来…...
训练集alpaca、sharegpt格式
LLaMA-Factory微调支持的格式 支持 alpaca 格式和 sharegpt 格式的数据集。 Alpaca格式 格式: [{"instruction": "人类指令(必填)","input": "人类输入(选填)","output": "模型回答(必填)","syst…...

Hive的数据存储格式
目录 一、前言 二、存储格式 2.1、文本格式(TextFile) 2.1.1、定义与特点 2.1.2、存储与压缩 2. 1.3、使用场景 2.2、行列式文件(ORCFile) 2.2.1、ORC的结构 2.2.2、ORC的数据类型 2.2.3、ORC的压缩格式 2.2.3、ORC存储…...
Linux Rsyslog 配置
1、Linux Rsyslog客户端配置 1)安装rsyslog yum install rsyslog 2)启用TCP或UDP传输 vim /etc/rsyslog.conf# Provides UDP syslog reception #若启用UDP进行传输,则取消下面两行的注释 #$ModLoad imudp #$UDPServerRun 514# Provide…...

python实现放烟花效果庆祝元旦
马上就要2025年元旦啦,提前祝大家新年快乐 完整代码下载地址:https://download.csdn.net/download/ture_mydream/89926458...

模型训练识别手写数字(二)
模型训练识别手写数字(一)使用手写数字图像进行模型测试 一、生成手写数字图像 1. 导入所需库 import cv2 import numpy as np import oscv2用于计算机视觉操作。 numpy用于处理数组和图像数据。 os用于文件和目录操作。 2. 初始化画布 canvas np.z…...

深入Vue2
frontend Vue2 学习内容参考 /在线运行 Element 学习内容参考 /视频教学 vue2 1. vue 实例 当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中 但是当使用Object.freeze(),会阻止修改现有的 property&#x…...
opencv-rust 系列3: Create_mask
前言: 这里只是opencv-rust自带示例的中文注解. 略微增加了一些代码也是我在调试时用到的. 调试方法可参见前文. 一. 这个程序还是有点难度的, 关键点在于: 创建了遮罩. 直接调用一个函数, 还是很简单的.窗口事件处理. 注册窗口回调函数, 用以处理鼠标事件进程同步和互斥锁. 为…...
Go语言初识
一、Go语言概述 Go语言是为了取代C和java的地位,既要保留C的简洁,也追求java的规模化开发 并行及分布式的支持,使得开发多核及多机器集群程序如同单机一样简单 Go语言从语言级别支持协程(goroutine, 轻量级线程),Go语言…...

Android Activity SingleTop启动模式使用场景
通知栏 当用户点击通知栏中的通知时,可以使用单顶启动模式来打开对应的活动,并确保只有一个实例存在。 简单集成极光推送 创建应用 获取appkey参数 切换到极光工作台 极光sdk集成 Project 根目录的主 gradle 配置 Module 的 gradle 配置 Jpush依赖配置 配置推送必须…...
PHP 代码执行相关函数
函数 说明 示例代码 ${} 用于复杂的变量解析,通常在字符串内用来解析变量或表达式。可以配合 eval 或其他动态执行代码的功能,用于间接执行代码。 eval(${flag}); eval() 用于执行一个字符串作为 PHP 代码。可以执行任何有效的 PHP 代码片段。没有…...

五周年,继续破浪前行
五周年,TapData 再一次带着自己的“乘风破浪”大队,在一个阳光明媚的日子里,把生日过在了海上。 头顶日升日落,这条属于全体 Tap-pers 的航船,再次校准航向,在船长的带领下,驶向下一个晴好的明…...
【操作系统】Linux之进程管理一
第1关:获取进程常见属性 ret.pidgetpid(); ret.ppidgetppid(); 第2关:进程创建操作-fork pid_t pid fork(); if(pid-1) printf("创建进程失败!"); else if(pid0) printf("Children"); else printf("Parent"); …...

C语言_数据在内存中的存储
1. 整数在内存中的存储 计算机中的整数有三种2进制表示方法 :原码、反码、补码。 三种表示方式均有符号位和数值位两个部分,最高一位的是符号位,剩下的都是数值位。符号位用“0”表示“正”,用“1”表示“负”。 正数的原、反、…...

华为原生鸿蒙操作系统:我国移动操作系统的新篇章
华为原生鸿蒙操作系统:我国移动操作系统的新篇章 引言 在移动操作系统领域,苹果iOS和安卓系统一直占据主导地位。然而,随着华为原生鸿蒙操作系统的正式发布,这一格局正在发生深刻变化。作为继苹果iOS和安卓系统后的全球第三大移动…...
队列的基本操作(数据结构)
1.实验内容: 编写一个程序sqqueue.cpp,实现环形队列(假设栈中元素类型ElemType 为 char)的各种基本运算,并在此基础上设计一个程序exp4_1.cpp,完成如下功能: 2.实验步骤: (1)初始化队列q (2)判断队列q是否非空 (3…...

linux开机自启动三种方式
方式一、 1:rc.local 文件 1、执行命令:编辑 “/etc/rc.local” vi /ect/rc.local 2、然后在文件最后一行添加要执行程序的全路径。 例如,每次开机时要执行一个 hello.sh,这个脚本放在 / usr 下面,那就可以在 “/et…...

AI创作者与人类创作者的协作模式
公主请阅 1. AI创作者的崛起1.1 AI创作者的工作原理1.2 AI创作者的优势 2. 人类创作者的独特价值2.1 创造性与情感2.2 伦理与价值观2.3 文化与背景 3. AI与人类的协作模式3.1 协同创作3.2 内容编辑3.3 数据驱动的创作3.4 跨媒体协作 4. AI与人类协作的挑战4.1 技术局限性4.2 版…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...