[Redis] Redis缓存机制

🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:
🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm=1001.2014.3001.5482
🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀线程与网络(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
🍃 Spring(97平均质量分)https://blog.csdn.net/2301_80050796/category_12724152.html?spm=1001.2014.3001.5482
🎃Redis(97平均质量分)https://blog.csdn.net/2301_80050796/category_12777129.html?spm=1001.2014.3001.5482
🐰RabbitMQ(97平均质量分) https://blog.csdn.net/2301_80050796/category_12792900.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
在这里插入图片描述

目录

  • 1. 为何要使用Redis作为缓存
  • 2. 缓存的更新策略
  • 3. 缓存预热,缓存穿透,缓存雪崩,缓存击穿(常考面试题)
    • 3.1 缓存预热
    • 3.2 缓存穿透
    • 3.3 缓存雪崩
    • 3.4 缓存击穿

1. 为何要使用Redis作为缓存

我们知道,Redis最主要的用途主要有三个方面,首先就是存储数据,也就是把它当做一种内存数据库,其次是缓存,这是Redis最常用的一种场景,然后就是消息队列,不过我们一般不使用Redis作为消息队列,市面上有很多现成的消息队列中间件,比Redis好用的多.
我们为什么要使用Redis作为缓存呢?
首先我们需要知道在计算机中,访问数据的速度CPU寄存器>内存>硬盘>网络,速度快的设备可以作为速度慢的设备的缓存.我们最常见的就是内存作为硬盘的缓存(这也是Redis的定位).当然我们前面也曾经谈到过,硬盘也可以作为网络的缓存.当访问到某个网站上的数据的时候,浏览器就会从服务器上获取数据并进行展示,如果某些数据的体积较大,变化频率又不是很高的时候,就可以通过网络直接存储数据到本地硬盘,当下一次打开页面的时候,就不必从通过网络从服务器上再次获取数据了.
缓存中存储的数据,一般都是我们经常需要访问的数据,这些数据虽然不多,但是却可以满足绝大部分的查询情况,满足的是二八定律,20%的数据可以应对80%的请求.
我们通常使用Redis作为数据库的缓存(MySQL),但是我们知道,数据库的性能并不是很高:
- 首先数据库是把数据存储在硬盘上的,硬盘的读写速度并不快,尤其是随机访问.
- 其次如果查询不能命中索引的话,就需要对表进行遍历,这就会大大增加硬盘读写的次数.
- 如果是一些复杂的查询,比如联合查询,就需要对表进行笛卡尔积的操作,效率更低.

就是因为MySQL这种关系型数据库效率比较低,所以可以承担的并发量比较有限,一旦请求多了,数据库的压力就会很大,甚至发生宕机.如果想要解决MySQL并发量的问题,我们有两种解决的策略,一种是开源,就是引入更多的机器,构成数据库集群,另一种就是节流,即引入缓存,这就是典型的方案,把一些频繁读取的热点数据,保存到缓存上,后续在查询数据的时候,如果缓存中已经存在了,就可以不再访问MySQL了.Redis也就相当于一个护盾一样,把MySQL给罩住了.
在这里插入图片描述

2. 缓存的更新策略

如何知道Redis中存储的是哪些数据呢,换句话说,如何知道哪些数据是热点数据呢?这就涉及到了缓存的更新策略.缓存的更新策略有如下两种:

  1. 定期生成
    顾名思义,就是每隔一定的周期就会挑选出热点数据(比如一天/一周/一个月),Redis会把访问的数据,使用日志的形式来记录下来.此处的热点数据,就可以根据当前这里的统计维度(日志),来定期进行更新.

比如搜索引擎: 在搜索引擎中,所搜索的查询词就是要访问的数据,这时候,系统就会统计搜索的查询词,把这些查询词统计到日志之中.之后就可以对这些日志进行统计了.统计这一天/一周/一个月每个词出现的频率,在根据频率降序排列,取出比如前20%的词作为热点数据,接下来就可以把这些热点词涉及到的搜索结果,提前拎出来,就可以放到类似于Redis这样的缓存中了.

缓存数据总体的流程大体如下:

  • 完成统计热词的过程
  • 根据热词,找到搜索结果的数据
  • 把得到的数据同步到部署缓存中间件的服务器上
  • 控制这些缓存服务器自动重启

以上定期缓存策略的优点就是实现起来比较简单,过程更加可控,方便排查问题.
缺点也很明显,就是实时性不够,如果出现一些突发性事件,有一些本来不是热词的内容就会突然成为热词,这些数据就会都打到数据库上,新的热词可能会给数据库带来较大的压力.

  1. 实时生成
    用户在每次查询的时候,系统集群就会经历以下的过程:
  • 首先在Redis中查询要查询的数据,如果数据在Redis中存在的话,会直接返回结果.
  • 如果Redis中不存在的话,就会从数据库中查询,之后把查询到的结果同时也写入Redis中.
    在这种模式之下,经过一段时间的动态平衡,Redis中的key就会逐渐都成为了热点数据.但是如果这样一直不停地写Redis的话,就会达到内存上限(这里的上限不一定是服务器的内存上限,也可能是Redis中的配置项参数,最多可以使用多少内存空间,我们可以在conf文件中通过maxmemory配置项来配置).
  • 为了解决上述的问题,Redis就引入了==“内存淘汰策略[常见面试题]”==.Redis中的内存淘汰策略主要有以下的几种:
    • FIFO(first in first out) 先进先出
      把缓存中存在时间最久的(先进来的数据)数据淘汰掉.
    • LRU(least recently used) 淘汰最近未使用的
      记录每个key的最近访问时间,把最近访问的时间最早的key淘汰掉.
    • LFU(least frequently used) 淘汰访问次数最少的
      记录每个key最近一段时间的访问次数,把访问次数最少的淘汰掉.
    • Random 随机淘汰
      随机抽取一名幸运儿淘汰掉

举例说明:甄嬛传
在这里插入图片描述
我们需要把Redis想想成一个皇帝.把数据想象成后宫佳丽.
FIFO:皇后肯定是最先受宠的,但是现在已经年老色衰了,皇后失宠
LRU:统计最近宠幸的时间,宠幸时间最早的佳丽失宠
LFU:统计最近宠幸的次数,宠幸次数最少的佳丽失宠
Random:随机挑选一个佳丽失宠

上面的策略,具体要采用哪种,就要具体场景具体分析了.在Redis的配置文件中,我们有一个配置项,就可以配置内存淘汰策略.这里的淘汰策略,我们可以自己实现,当然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 默认策略,当内存不足以容纳新写入数据时,新写入操作会报错.

3. 缓存预热,缓存穿透,缓存雪崩,缓存击穿(常考面试题)

3.1 缓存预热

我们上面提到,缓存中更新数据有两种策略,一种是定期生成,一种是实时生成.定期生成不涉及"预热",但是实时生成会涉及到.
Redis服务器在首次接入之后,服务器里是没有任何数据的,此时,所有的请求就都会答到数据库上,如果请求以下子太多,很容易导致数据库服务器宕机.缓存预热就是用来解决上述的问题的,首先通过离线的方式,通过一些统计途径,先把热点数据找到一批,导入到Redis中,此时导入的这批热点数据,就可以帮mysql承担很大的压力了.随着时间的推移,逐渐就会使用新的热点数据淘汰掉旧的热点数据.

3.2 缓存穿透

我们在Redis中查询某个key,在Redis中没有,在mysql中也没有,这个key肯定也不会被更新到Redis中.这次查询没有,下次查还没有,如果像这样的数据存在很多,并且还反复查询,一样会给mysql带来很大的压力.
为什么会有上面的这种情况呢?有以下的几种情况:

  • 业务涉及不合理,比如缺少相关参数的校验,导致非法的key也被查询了.
  • 开发/运维人员误删数据库上的数据.
  • 黑客恶意攻击

那么如何解决上述内存穿透的问题呢?

  • 首先针对第一种场景,我们需要改进业务逻辑,加强监控报警机制,但是这也是一种亡羊补牢的一种方式.更加靠谱的方案,如果发现这个key在Redis中和mysql中都不存在,我们仍然把这个值写入到Redis中,value设置为一个非法的值(比如""),后续在访问非法数据的时候,就会返回设置好的非法的数据.当然我们还可以进入布隆过滤器.每次查询Redis/mysql之前,都判定一下key是否在布隆过滤器上存在.
  • 之后就是第二种场景,我们就需要开发/运维人员介入,尽快回复数据.
  • 第三种场景,需要安全团队的介入.

3.3 缓存雪崩

由于在短时间内,Redis上大规模的key失效,导致了缓存命中率陡然下降,让数据库的压力陡然上升,甚至发生宕机.
造成上述这种问题的一般有两种情况:

  1. Redis服务器宕机,或者是Redis的集群大量服务器宕机
  2. 短时间之内,设置了很多过期时间相同的key.过期的时候也正好是同一时间过期.

解决上述问题的主要方式是:

  1. 加强监控报警,保证Redis集群的可用性.
  2. 我们可以选择不给Redis的数据设置过期时间或者是设置过期时间的时候,加入一些随机的因子(避免同一时间过期).

3.4 缓存击穿

缓存击穿相当于缓存雪崩的一种特殊情况,雪崩是大量的key发生了过期,但是穿透与雪崩的区别就是==只是热点数据突然发生了过期,==这就会使得大量的请求打在了数据库上,导致数据库发生宕机.相比雪崩,击穿过期的是热点数据,访问频率更高,影响更大.

解决方案有以下几种:

  1. 基于统计的方式发现热点key,并设置为永不过期.但是这种往往需要服务器的结构做出较大的调整
  2. 进行必要的服务降级,例如使用分布式锁,限制同时请求数据库的并发数.我们接下来介绍

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

绘制3D图

一个 3D 函数的表面图,其中包含向量场。 Python 代码示例,使用 matplotlib 和 numpy 库来绘制类似的图。 python 复制代码 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D# 生成网格 x np.linspace(-…

【开源免费】基于SpringBoot+Vue.JS课程答疑系统(JAVA毕业设计)

博主说明:本文项目编号 T 070 ,文末自助获取源码 \color{red}{T070,文末自助获取源码} T070,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…

C#开发流程

注:检查数据库链接 设置搜索 1.新建模块文件夹 对应应用 右键-添加-新建文件夹 2.新建类 在新建模块下右键 新建-类,修改类名称 修改internal为public 新建所需字段,注意类型声明及必填设置 [SugarColumn(IsNullable false)]public strin…

【Transformer】模型输出模块处理

目录 输出处理模块步骤1. 交叉注意力后的输出向量2. 线性变换(投影)3. Softmax 操作4. 选择最大概率的单词5. 输出词并进入下一轮预测总结: 线性变换详解1. 交叉注意力后的输出向量2. 线性层的参数3. 线性变换的计算4. Softmax 转换为概率示例…

对话流式数据加载

需求:根据接口返回的数据进行类似打字机渲染的效果 使用的fetch 流式处理 fetch(BASE_URL/api/apps/ this.app_Id /chat-messages, {signal: this.controller.signal,method: POST,headers: {Authorization: Bearer localStorage.getItem(token),Content-Type: …

关于git使用的图文教程(包括基本使用,处理冲突问题等等)超详细

目录 用户签名,初始化git git提交流程图 提交到本地库 版本穿梭 分支操作 分支合并冲突 团队协作 github的使用 推送代码 克隆 拉取代码 团队协作冲突 团队协作之分支管理 推送分支到分支: 拉去远程库分支到本地库: 本地删除远程分支&am…

6、If、While、For、Switch

6、If、While、For、Switch 一、If 1、if-else if (boolean) {代码块 } else if (boolean) {代码块 } else if (boolean) {代码块 } else { // 默认情况代码块 }关于IDEA单元测试控制台不能输入数据的问题: https://blog.csdn.net/m0_72900498/article/details/…

【智谱开放平台-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…

贪心算法day05(k次取反后最大数组和 田径赛马)

目录 1.k次取反后最大化的数组和 2.按身高排序 3.优势洗牌 1.k次取反后最大化的数组和 题目链接:. - 力扣(LeetCode) 思路: 代码: class Solution {public int largestSumAfterKNegations(int[] nums, int k) {//如…

简简单单的UDP

前言 上一篇了解了TCP的三次握手过程,目的、以及如何保证可靠性、序列号与ACK的作用,最后离开的时候四次挥手的内容,这还只是TCP内容中的冰山一角,是不是觉得TCP这个协议非常复杂,这一篇我们来了解下传输层另外一个协…

安科瑞工业绝缘监测装置:保障煤矿井下6kV供电系统安全运行的关键应用——安科瑞 丁佳雯

在现代煤矿开采中,供电系统的稳定性和安全性是至关重要的。特别是在煤矿井下,由于环境复杂、湿度大、易腐蚀等因素,供电系统面临着严峻的挑战。为了确保供电系统的正常运行和矿工的生命安全,采用先进的绝缘监测装置显得尤为重要。…

OKG Research:用户意图驱动的Web3应用变革

出品| OKG Research 作者|Samuel QIN 当前加密市场的快速演变中,用户增长成为行业可持续发展的基石。目前主流观点在推动行业前进的路上,从单纯的技术探索在向更注重应用价值的方向转变。尽管近年来Web3生态系统发展迅速&#xf…

人工智能:重塑医疗、企业与生活的未来知识管理——以HelpLook为例

一、医疗行业:AI引领的医疗革新 随着人工智能(AI)技术的持续飞跃,我们正身处一场跨行业的深刻变革之中。在医疗健康的广阔舞台上,人工智能技术正扮演着日益重要的角色。它不仅能够辅助医生进行病例的精准诊断&#xf…

Ubuntu 20.04安装CUDA 11.0、cuDNN 8.0.5

不知道咋弄的ubuntu20.04电脑的cuda驱动丢了,无奈需装PyTorch环境,只有CUDA11.0以上版本才支持Ubuntu20.04,所以安装了CUDA11.0、cuDNN8.0.5 为防止频繁在浏览器检索对应的贴子,今天记录一下。 一. 驱动安装 为防止驱动安装后没…

Vue Element-UI 选择隐藏表格中的局部字段信息

一、功能需求分析 为什么需要这个功能? (1)简化信息,减少混乱: 就像整理抽屉,只留下常用的东西,这样找起来更快,看起来也更整洁。在表格中,只展示需要的字段&#xff…

STL学习-排序算法

1.sort 使用快速排序,平均性能好O(nlogn),但最差情况可能很差O(n^2)。不稳定。 sort(v.begin(),v.end());//对v容器进行排序,默认升序 sort(v.begin(),v.end(),greater<int>());//降序排序 2.partial_sort 使用堆排序,平均性能和最差都是O(nlogn),但实际情况比sort慢…

WSL 2 中 FastReport 与 FastCube 的设置方法与优化策略

软件开发人员长期以来一直在思考这个问题&#xff1a;“我们如何才能直接在 Windows 中运行 Linux 应用程序&#xff0c;而无需使用单独的虚拟机&#xff1f;” WSL 技术为这个问题提供了一个可能的答案。WSL 的历史始于 2016 年。当时&#xff0c;其实现涉及使用 Windows 内核…

JVM的组成、字节码文件的组成

目录 java虚拟机的组成 字节码文件的组成 基础信息 常量池 字段 方法 属性 字节码相关的常用工具&#xff1a; 总结&#xff1a; 1、如何查看字节码文件&#xff1f; 2、字节码文件的核心组成有哪些&#xff1f; java虚拟机的组成 类加载器 ClassLoader运行时数据区…

李佳琦回到巅峰背后,双11成直播电商分水岭

时间倏忽而过&#xff0c;又一年的双11即将宣告结束。 从双11正式开始前的《新所有女生的offer》&#xff0c;到被作为“比价”标杆被其他平台直播间蹭、被与其他渠道品牌比较&#xff0c;再到直播间运营一时手快多发了红包……整个双11周期下来&#xff0c;李佳琦直播间在刷新…

使用iviewui组件库的坑

背景 使用view-design组件库的Input组件的时候&#xff0c;按照产品的要求&#xff0c;输入框中只能键入正整数。 使用效果 如果直接使用组件的type属性&#xff0c;设置类型为number时&#xff0c;乍一看没啥问题&#xff0c;但是当我们键入 小数点(.) 或者 e/E 后面没有跟任…