【Redis】缓存(上)

news2024/11/13 10:57:48

为什么要使用缓存?

在日常开发中,通常使用Redis来做MySQL的缓存。究其原因,首先,根据二八定律,20%的数据可以应对80%的请求;其次,对于MySQL这样的关系型数据库来说,性能普遍都不是很高。一旦承载的并发量过高,那么就很容易造成宕机,这对生产环境造成的影响是巨大的。但是,对于缓存来说,响应速度是比较迅速的,因而就想到了使用缓存来代替数据库。

首先,想要使用缓存,那么就一定要将缓存放入到Redis中,这就涉及到了缓存的更新策略;其次,Redis的内存并不是无限的,因此就涉及到了缓存的淘汰策略;并且,热点数据可能是暂时的,因此我们在设置缓存时,还给予了一个淘汰时间,从而就涉及到了缓存的超时剔除策略。在把这些八股了解完之后,又出现了缓存预热、缓存穿透、缓存击穿、缓存雪崩四个重要的概念。最后,由于我们学习Redis并不只是为了八股,因此我们还要掌握代码的书写。

更新策略

在日常开发中,一般使用MySQL作为持久层来存储数据,Redis则作为缓冲层来减少对于MySQL的访问,从而防止MySQL因请求过多而宕机的危险。所以,对于Redis中的所有数据,都是来源于MySQL的,这就导致Redis可以存在不同的更新策略,例如定期更新或者实时更新。

定期生成

对于用户访问的数据,以日志的形式进行记录。对日志进行统计(统计时间不定,看具体的业务场景,统计任务可以使用定时任务的方式实现),把出现的数据进行排序,再取出前20%的数据,就认为这些数据是热点数据。再把这些数据同步到缓存服务器上,控制缓存服务器进行重启即可。

至于如何进行统计?在数据量较小的情况下,可以自制一个简单程序进行统计;在数据量较大的情况下,就需要使用大数据的一套技术栈来做。

优点是实现比较简单,缺点就是实时性差一点。

实时生成

当客户端发送请求之后,先在Redis中进行查询。如果存在数据,那么就直接返回;如果没查到,那么就去MySQL中进行查询。当查询到之后,就返回客户端,并写入到Redis中;如果没有查到,那么就属于是缓存穿透了,可以根据实际情况来做出处理。

在实际工作中,对于实时生成的更新策略一般有三种解决方案:

1. 由缓存的调用者,在修改数据库的同时,更新缓存。

2. 缓存与数据库整合成一个服务,由服务来维护一致性。调用者调用该服务,无需考虑缓存一致性问题。

3. 调用者只调用缓存,由其他线程异步的将缓存数据持久化到数据库,保持最终一致,

在三种解决方案中,一致性是由弱到强,维护成本也是由弱到强。

淘汰策略

Redis是一款内存型数据库,但是内存并不和硬盘一样,其价格是比较高昂的。因此我们在使用Redis的过程中,就要考虑当内存占满之后,如何进行淘汰才是最优的解决方案,即我们要找到对程序的性能影响是最小的方案。

通用策略

1. FIFO(first in first out):先进先出

2. LRU(least recently used):淘汰最久未使用的。记录每个key的最近访问时间,把最近访问时间最老的数据给淘汰掉。

3. LFU(least frequently used):淘汰访问次数最少的。记录每个key最近一段时间的访问次数,把访问次数最少的给淘汰掉。

4. Random:随机淘汰。从数据中随机选取数据进行淘汰。

Redis配置项

1. volatile-lru:当内存不足以容纳新写入数据时,从设置了过期时间的key中使用LRU算法进行淘汰。

2. allkeys-lru:当内存不足以容纳写入新数据时,从所有key中使用LRU算法进行淘汰。

3. volatile-lfu:4.0版本新增,当内存不足以容纳新写入数据时,在过期的key中,使⽤LFU算法进⾏删除key。

4. allkeys-lfu:4.0版本新增,当内存不足以容纳新写入数据时,从所有key中使⽤LFU算法进⾏淘汰。

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

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

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

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

总的来说,Redis提供的过期策略和上述介绍的通用策略是基本一致的。只不过Redis会基于有过期时间key和全部key做分别处理。

过期策略

在Redis中,是可以给key设置过期时间的。因此我们就要考虑当key到达到期时间之后,如何对其进行删除。而Redis中,采用了定期删除+惰性删除的方式。

定期删除

定期删除并不是把所有的key都遍历一次,然后将过期的删除。而是每次抽取一小部分,进行验证是否过期(所谓的小部分,就是要保证检查过期的时间足够短)。

这里对于定期删除的时间,是有明确的要求。因为Redis是单线程的程序,如果扫描过期key消耗的时间太长。那么就会导致其他正常的请求被阻塞,从而造成其他的影响。

惰性删除

假设某个key已经到达了过期时间,但是由于定时删除还没有扫描到该key,因此仍然存在于Redis中。此时恰好要使用这个key,这次使用就会让Redis触发删除key的操作,同时再返回一个nil。

定期删除 + 惰性删除两种策略结合,仍然会有一大部分过期key被残留,没有及时删除。

定时器删除

首先,Redis并没有采用定时器来实现过期key删除。但是,如果使用定时器的方式来实现key过期删除也是一个不错的策略。所谓定时器,就是在某个时间到达之后,执行指定的任务。

对于定时器的实现,可以使用优先级队列或者时间轮的方式来实现较高效的定时器。对于Redis中没有使用定时器,可能是因为遵从了Redis单线程的基调。一旦使用定时器,那势必要引入多线程,这就可能打破设计者的初衷。

优先级队列

在Redis中,可以利用key过期时间越早,优先级就越高的方式来进行设置。将队列设置好之后,使用一个线程来扫描队首元素。只要队首没过期,那么后续的key也一定没过期。因此这个扫描线程只需要盯着队首即可。如果扫描线程发现队首key距离过期时间还很长,那么扫描线程就可以进入休眠状态,等到快过期时,再唤醒进行删除即可。如果在休眠过程中来了新的key,也需要唤醒扫描线程,再次检查队首元素是否发生了变化。

时间轮

 时间轮就是把时间划分成一小段一小段,至于划分区间的大小,就具体看实际需求的多少。对于每一段时间来说,上面都是一个链表,而链表上面就挂着许许多多的key。在时间轮中,存在一个指针,这个指针首先对所在区间进行尝试,看看有没有过期的key,然后等待一定时间间隔之后,就会走到下一个区间去探测,一直循环往复。

值得注意的是,假设规定某一个为1区间,时间间隔为100ms,有10个区间,那么过期时间是1100ms的话,那也是存在于1区间。因此,指针走到某个区间并不是全部过期,而是进行测试哪个过期,哪个还在运行中。并且区间大小,区间多少等也是根据实际需求来的,并不是说规定。

缓存更新策略最佳实践方案

1. 低一致性需求:使用Redis自带的内存淘汰策略。

2. 高一致性需求:主动更新,并以超时剔除作为兜底方案。对于读操作,缓存命中则直接返回;缓存未命中则查询数据库,并写入缓存,设定超时时间。对于写操作,先写数据库,再删除缓存;并且要确保数据库与缓存操作的原子性。

数据库和缓存操作的前后性

 由图看出,先操作数据库,再操作缓存。反之,如果先删除缓存,那么就有可能导致缓存和数据库数据的不一致。

在本篇文章中,介绍了内存更新策略、内存淘汰策略以及内存过期策略。在此文章的续篇中,主要来介绍缓存的应用以及缓存预热、缓存穿透、缓存雪崩、缓存击穿的概念及其代码中的解决方案。

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

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

相关文章

复习:存储类别内存分配动态分配内存

目录 存储类别说明符 自动变量(auto) 寄存器变变量(register) 块作用域的静态变量(static) 外部链接的静态变量(external) 内存分配 概念回顾 动态分配内存 malloc函数 free函数 回…

若依框架(前后端分离)增加手机号验证码登录

这篇文章主要介绍了如何在若依架(前后端分离)版本中集成短信验证码登录功能。文章内容包括了前后端的详细实现步骤,并通过代码示例展示了如何生成验证码、验证验证码、验证码登录、自定义的认证处理等功能的实现。 前端部分: 登录界面改造:在现有的登录界面上增加短信验证…

Spring Boot集成google Authenticator实现mfa

1.什么时候mfa? 多重身份验证(MFA)是多步骤的账户登录过程,它要求用户输入更多信息,而不仅仅是输入密码。例如,除了密码之外,用户可能需要输入发送到其电子邮件的代码,回答一个秘密…

GoodSync - 本地云端备份同步工具

最近几年各种加密勒索软件层出不穷,个人数据受到威胁。如何让风险降到最低?养成好的备份习惯就很重要。 GoodSync 就是你值得信赖的同步备份工具,能够实现多合一管理网盘、文件安全备份或同步。 文件同步、备份好助手 要在多种设备中同步文…

9.1centos安装postgres

目录 一、安装并启动postgres 二、设置允许远程连接 三、重置密码 四、开放防火墙端口 五、重启服务后进入命令行模式 六、远程连接 一、安装并启动postgres # Install the repository RPM: sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpm…

用Python实现时间序列模型实战——Day 7: ARIMA 模型的诊断与调整

一、学习内容 1. 残差分析与模型诊断 残差分析: 在 ARIMA 模型拟合之后,我们需要检查模型残差是否满足白噪声的假设。如果模型残差表现为零均值、方差恒定且无自相关性,这说明模型已经捕捉了时间序列中的主要结构,剩下的残差是…

jarbas 靶机渗透(cms 渗透)

靶机信息 vulnhub 靶机 主机发现 (base) ┌──(root㉿kali)-[/home/kali/testJarbas] └─# sudo nmap -sn 192.168.50.0/24 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-28 15:45 CST Nmap scan report for 192.168.50.1 Host is up (0.00023s latency). MAC …

职场真相:在草台班子中寻找自我价值

在踏入社会的那一刻起,我们每个人都怀揣着对未来的无限憧憬与梦想,渴望在职场这个广阔的舞台上绽放光彩。然而,现实往往比理想骨感得多,尤其是在初入职场的几年里,那些曾经以为的“精英团队”、“完美计划”逐渐被现实…

如何选到好的宠物空气净化器,用哪款宠物空气净化器比较好?

在当今社会,养宠物已成为许多家庭不可或缺的一部分,猫猫狗狗以其独特的魅力,悄然融入了我们的生活,成为了家中的一员,它们不仅带来了无尽的欢笑与陪伴,更在无形中丰富了我们的情感世界,让家充满…

【Python】如何使用pip,安装第三方库和生成二维码、操作Excel

文章目录 第三方库使用 pip安装第三方库 生成二维码1. 确定使用哪个库2. 查看对应文档3. 开始操作 操作 Excel1. 安装 xlrd2. 编写代码 第三方库 第三方库就是别人已经实现好了的库,我们可以拿过来直接使用 虽然标准库已经很强大了,但是终究是有限的&am…

QT线程同步

#线程同步 在前面理解了QThread两种使用方法,和线程机制以及退出过程后,需要了解线程同步的内容了,今天开启学习线程同步知识。 还是从大佬的文章开始。 从下面这篇文章开始学习 线程同步 线程同步有: QMutex(互斥&…

【PID系列】一文理解PID原理

【PID系列目录】 [1、一文理解PID原理] 2、PID代码设计 本文目录 1、引出2、 PID概念2.1 首先,什么是偏差呢?2.2 其次,什么是PID比例项?2.3 积分————解决稳态误差的利器2.4  微分————改善动态响应…

while (r > b[i].r) del(a[r--]); while (r < b[i].r)

论 分治 cdq | [SDOI2011] 拦截导弹 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度、并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高于前一发的高度…

利用深度学习实现验证码识别-2-使用Python导出ONNX模型并在Java中调用实现验证码识别

1. Python部分:导出ONNX模型 首先,我们需要在Python中定义并导出一个已经训练好的验证码识别模型。以下是完整的Python代码: import string import torch import torch.nn as nn import torch.nn.functional as FCHAR_SET string.digits# …

静态库和共享库

文章目录 库的概念函数库库函数静态库的创建与使用静态库的概念静态库的创建代码示例--静态库的创建和使用 共享库的创建和是使用共享库的概念共享库的创建共享库的使用 总结 库的概念 当进行编辑C代码的时候常常会用到printf函数,这个函数被声明在stdio.h头文件中…

企业内部通信软件:打造高效协同办公的IM即时通讯工具

在现代企业中,高效的内部通信和协同办公是保持竞争优势的重要因素。为了实现团队间的快速沟通和协作,许多企业采用了企业内部通信软件,其中包括IM即时通讯工具。本文将探讨企业内部通信软件的重要性以及如何利用IM即时通讯工具打造高效协同办…

Clickhouse 为什么这么快

Clickhouse 的缘起 Clickhouse 最初是为 Yandex.Metrica 这个世界上第二大的Web分析平台开发的,并且一直是这个系统的核心组件。ClickHouse在Yandex.Metrica中的主要任务是使用非聚合数据在在线模式下构建报告,使用374台服务器组成的集群,在…

服务器间进行文件传输-SFTPSCP一篇搞定

1.简单介绍一下 在一些特殊场景,两台服务器之间需要进行文件传输的时候,或许我们会想到FTP,这也是我们常见的实现方式,但是如果我们不能操作远程服务器,无法判断远程服务器是否安装了FTP呢,众所周知&#…

学习周报-2024.8.31

目录 摘要 Abstract 创新点总结 模型数学原理 实验设置 一、验证实验 二、对比实验 摘要 这周重新梳理出论文的三个创新点,对所提出方法进行数学原理验证,证明其可行性。重新设置了实验部分,分为验证实验和对比实验,一共四…

使用 Eigen 库中的 Kronecker 积运算

前言 在数值计算和线性代数的众多应用中,Kronecker 积(Kronecker Product)是一种常用的矩阵运算。Eigen 是一个高性能的 C 数值计算库,广泛用于科学计算和工程应用中。在 Eigen 库中,Kronecker 积运算属于不常用的扩展…