一篇文章搞懂Redis缓存

news2024/11/28 19:00:04

目录

  • 一、什么是缓存
    • 缓存的优缺点
      • 缓存的优点
      • 缓存的缺点
  • 二、Redis缓存
  • 三、缓存的更新策略
    • 主动更新策略
  • 四、缓存穿透
    • 解决方案
  • 五、缓存雪崩
    • 解决方案
  • 六、缓存击穿
    • 解决方案

一、什么是缓存

我们都知道在计算机中内存的速度比磁盘要快非常多,如果每次都要去磁盘获取数据,是不是每次的速度都很慢。如果有一个数据是我们要经常使用的,如果每次都从磁盘获取数据,那速度是每次都是那么慢。所以就想到是不是可以把数据放到内存中,这样在第一次获取之后将数据存放在内存中,这样速度就快很多。
在这里插入图片描述
现在的计算机世界中到处都用到了缓存技术。并且缓存也不一定是要放在速度快的介质中才是缓存,应该是只要能提升速度的方法都可以称作缓存,例如一个文件非常大,每次查询一条一条遍历下去很慢,是不是可以把常用的记录单独存放在一个文件中,这样每次先查这个缓存文件就可以大大提高性能。

缓存的优缺点

缓存既然可以大大提升性能,那是不是什么都可以使用缓存?

凡事都是有优缺点的,缓存也不例外,如果他的缺点我们可以接受,那缓存就是适合的技术。

缓存的优点

  1. 降低后端负载
    例如:后端数据库可以可以接受的请求是有一定的瓶颈的,请求太多就会导致服务无法处理后续的请求,如果有些数据可以直接放在客户端,那用户就不需要请求服务器了。
  2. 提高读写效率、降低相应时间
    例如:有些数据是非常常用的数据,如果每次都要去磁盘找这些数据,那速度是一致的,非常慢。但其实可以将这些常用数据放在缓存中,每次先从缓存中找,就可以提升大多数请求的性能。

缓存的缺点

  1. 数据一致性问题
    例如:缓存往往都是将数据复制了一份放在缓存中的,用户看到的都是复制的数据,如果原数据更新了,复制的数据不能及时同步,导致原数据和缓存数据不一致
  2. 代码维护成本变高
    例如:有了缓存就要维护缓存,每次查询都要先查缓存再查磁盘,也要判断要不要维护缓存数据等各种情况
  3. 运维难度变高
    例如:使用Redis缓存,运维就要保证Redis应用不能宕机,否则就要重大事故等

二、Redis缓存

Redis应用是一个基于内存的NoSQL数据库,它具有非常高的读写性能,所以在Web应用开发中非常适合用来做缓存,去承接高并发的用户请求。
在这里插入图片描述
例如上面这样典型的业务场景,客户端的请求先请求Redis,如果查询到数据了则直接返回,如果没有查询到数据,则查询数据,然后将数据放到Redis缓存中并返回给客户端。

三、缓存的更新策略

前面分析到缓存是有数据一致性的问题的,所以使用缓存的数据要是那些更新频率不高的数据,否则维护缓存的成本将会变高,使用缓存也就没什么意义了。

就算是更新频率不高的数据也会发生变更,那应该如何更新缓存的数据呢?有什么策略呢?

内存淘汰超时剔除主动更新
说明利用Redis应用自己的内存淘汰机制,在内存不足时自动淘汰部分数据,下次查询时更新缓存给数据加过期时间,过期自动删除,下次查询更新缓存编写业务逻辑,在修改数据的同时也更新缓存
一致性一般
维护成本

看了这个表格,我们其实发现不同的更新策略各有优略,这就需要根据不同的业务场景来进行选择了。
例如有些业务数据几乎就不会发生改变,就算变化了也不会有什么较大的影响就可以选择内存淘汰策略,好处就是完全不需要维护,但是如果数据要经常发生变化,就需要使用主动更新策略,但是也有有一定难度。

主动更新策略

在实际业务场景中,基本都是在更新数据库的同时更新缓存,再加上超时剔除来作为兜底方案的更新策略。

但是会存在三个问题:

  1. 更新数据库后是删除缓存还是更新缓存?
    一般都是选择删除缓存,然后用户查询时再将数据库的数据保存到缓存中。不选更新缓存是因为每次更新数据库都更新缓存,无效写操作太多。但是也要根据实际业务场景来进行选择。

  2. 如何保证缓存与数据库操作是同时成功或者失败的?
    单体引用就将缓存操作和数据库操作放在一个事务中,这样可以保证从缓存操作失败数据库操作回滚。分布式系统使用分布式事务来解决,但是所有的都无法保证缓存回滚。

  3. 先操作缓存还是先操作数据库?
    一般都是先操作数据再操作缓存,因为缓存操作比较快。基本都是选择先操作数据库再操作缓存,详细看如下两张图。

在这里插入图片描述
在这里插入图片描述
对比这两张图,我们可以发现如果先操作缓存再操作数据库,缓存里的值有可能是过时的数据。先操作数据库再操作缓存,可以保证缓存的值是最新的值。
并且如果先操作数据库,如果执行失败回滚了,对缓存完全无影响,但是如果先操作缓存,则会导致很多缓存失效。

其实缓存更新还有一种策略,就是先操作缓存,然后再开启一个异步线程将缓存的值更新到数据库中

四、缓存穿透

缓存穿透是指客户端请求的数据在缓存和数据库中都不存在(大量请求访问一个不存在的值),这样缓存永远都不会生效,请求全部都会打到数据库。如果请求量过大,很容易造成数据库服务宕机。如下图:
在这里插入图片描述

解决方案

1、缓存空对象
缓存空对象就是将不存在的值保存一个空值在缓存中,这样后续的请求查询缓存就会返回一个空值给客户端。
在这里插入图片描述
但是这样虽然可以防止缓存穿透的问题,但是还会带来其他问题:

  • 额外的内存消耗
  • 可能造成短期的不一致

2、布隆过滤器
将数据库中所有的查询条件,放入布隆过滤器中,当一个查询请求过来时,先经过布隆过滤器进行查,如果判断请求查询值存在,则继续查;如果判断请求查询不存在,直接丢弃。

还有一些主动解决缓存穿透的方案:
1、增强id的复杂度,避免被猜测到id的规律
2、做好数据基础格式的校验
3、加强用户权限管理
4、做好热点数据库限流

五、缓存雪崩

缓存雪崩是指在同一个时间段大量的可缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。
在这里插入图片描述

解决方案

如果是因为同一时间段大量缓存key过期导致的

  • 给不同的key设置随机均匀的过期时间

如果是因为Redis宕机

  • 利用Redis集群提高服务可用性
  • 给缓存业务添加降级限流策略
  • 给业务添加多级缓存

六、缓存击穿

缓存击穿问题也叫热点key问题,也就是一个高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会瞬间给数据库带来巨大的冲击。
在这里插入图片描述

解决方案

1、利用互斥锁
就是在缓存重建时只有一个线程去重建,其他线程都阻塞等待。
在这里插入图片描述

2、利用逻辑过期
就是缓存key是永不过期的,key的value值会保存业务数据和一个逻辑过期时间,请求访问数据主动判断数据是否过期,如果过期了则返回过期值并创建一个异步线程来更新缓存。

在这里插入图片描述

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

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

相关文章

《Python魔法大冒险》004第一个魔法程序

在图书馆的一个安静的角落,魔法师和小鱼坐在一张巨大的桌子前。桌子上摆放着那台神秘的笔记本电脑。 魔法师: 小鱼,你已经学会了如何安装魔法解释器和代码编辑器。是时候开始编写你的第一个Python魔法程序了! 小鱼:(兴奋地两眼放光)我准备好了! 魔法师: 不用担心,…

Lesson6---案例:人脸案例

学习目标 了解opencv进行人脸检测的流程了解Haar特征分类器的内容 1 基础 我们使用机器学习的方法完成人脸检测,首先需要大量的正样本图像(面部图像)和负样本图像(不含面部的图像)来训练分类器。我们需要从其中提取特…

解决Debian系统通过cifs挂载smb后,中文目录乱码问题

解决Debian系统通过cifs挂载smb后,中文目录乱码问题 //$smb_server/share /mnt/nas_share cifs credentials/root/.smbcredentials,iocharsetutf8 0 0默认通过以上命令挂载smb,但是在查看文件目录时,中文乱码 解决问题方式: de…

BLDC无感方波控制

BLDC无感控制 反电动势过零检测反电动势检测方法比较器模式采样过零信号闭环的建立 BLDC 方波启动技术转子预定位电机的外同步加速电机运行状态的转换 程序部分 反电动势过零检测 它的主要核心就是通过检测定子绕组的反电动势过零点来判断转子当前的位置。 三相六状态 120通电…

JavaScript -【第二周】

文章来源于网上收集和自己原创,若侵害到您的权利,请您及时联系并删除~~~ 理解什么是流程控制,知道条件控制的种类并掌握其对应的语法规则,具备利用循环编写简易ATM取款机程序能力 运算符语句综合案例 1. 运算符 算术运算符赋值运…

【python爬虫】批量识别pdf中的英文,自动翻译成中文上

不管是上学还是上班,有时不可避免需要看英文文章,特别是在写毕业论文的时候。比较头疼的是把专业性很强的英文pdf文章翻译成中文。我记得我上学的时候,是一段一段复制,或者碰到不认识的单词就百度翻译一下,非常耗费时间。本文提供批量识别pdf中英文的方法,后续文章实现自…

简明易懂:Python中的分支与循环

文章目录 前言分支结构if 语句:单一条件判断else语句:提供备选方案elif 语句:多条件判断嵌套的分支结构:复杂条件逻辑 循环结构for循环:遍历序列range()函数与for循环while循环:条件重复循环控制&#xff1…

C++------vector【STL】

文章目录 vector的介绍及使用vector的介绍vector的使用 vector的模拟实现 vector的介绍及使用 vector的介绍 1、vector是表示可变大小数组的序列容器。 2、就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问和数…

【rust/egui】(八)使用panels给你的应用划分功能区块

说在前面 rust新手,egui没啥找到啥教程,这里自己记录下学习过程环境:windows11 22H2rust版本:rustc 1.71.1egui版本:0.22.0eframe版本:0.22.0上一篇:这里 panel是啥 panel是ui上的一块区域&…

【数据库】通过实例讲清楚,Mongodb的增删查改,分组查询,聚合查询aggregate

目录 一.基础概念 二.数据库的管理 1.创建数据库 2.删除数据库 二.集合的管理 1.显示所有集合 2.创建集合 3.删除当前集合 4.向集合中插入元素 三.文档的管理 1.文档插入 2.文档的更新 3.文档的删除 4.文档查询 (1)查询基本语法&#xff1…

不同路径 II【动态规划】

不同路径 II 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。 现在考虑网格中有障碍物。那么从左上…

JavaScript设计模式(四)——策略模式、代理模式、观察者模式

个人简介 👀个人主页: 前端杂货铺 🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…

手撕 视觉slam14讲 ch7 / pose_estimation_3d2d.cpp (1)

首先理清我们需要实现什么功能,怎么实现,提供一份整体逻辑:包括主函数和功能函数 主函数逻辑: 1. 读图,两张rgb(cv::imread) 2. 找到两张rgb图中的特征点匹配对 2.1定义所需要的参数:keypoints…

githubPage部署Vue项目

github中新建项目 my-web (编写vue项目代码) myWebOnline(存放Vue打包后的dist包里面的文件) 发布流程 (假设my-web项目已经编写完成)Vue-cli my-web vue.config.js文件中 const { defineConfig } require(vue/cli-service)…

Spark【RDD编程(二)RDD编程基础】

前言 接上午的那一篇,下午我们学习剩下的RDD编程,RDD操作中的剩下的转换操作和行动操作,最好把剩下的RDD编程都学完。 Spark【RDD编程(一)RDD编程基础】 RDD 转换操作 6、distinct 对 RDD 集合内部的元素进行去重…

Windows Update Blocker,windows系统关闭自动更新工具

今天打开电脑发现系统又自动更新了 这一天天更新真的太烦了 然后我从网上找到一个工具 可以自由开启和关闭系统自动更新 这里分享一下网址:https://www.filehorse.com/download-windows-update-blocker/ 若网址失效,蓝奏云盘链接 https://wwgw.lanzouc.c…

mapboxGL3新特性介绍

概述 8月7日,mapboxGL发布了3版本的更新,本文带大家一起来看看mapboxGL3有哪些新的特性。 新特新 如上图所示,是mapboxGL官网关于新版的介绍,大致翻译如下: 增强了web渲染的质量、便捷程度以及开发人员体验&#xff…

一篇文章教会你如何编写一个简单的Shell脚本

文章目录 简单Shell脚本编写1. 简单脚本编写2. Shell脚本参数2.1 Shell脚本参数判断2.1.1 文件测试语句2.1.2 逻辑测试语句2.1.3 整数值测试语句2.1.4 字符串比较语句 3. Shell流程控制语句3.1 if 条件测试语句3.1.1 if...3.1.2 if...else...3.1.3 if...elif...else 4. Shell脚…

目标检测模型推理实验记录

在进行目标检测算法的学习过程中,需要进行对比实验,这里可以直接使用MMDetection框架来完成,该框架集成了许多现有的目标检测算法,方便我们进行对比实验。 环境配置 首先是环境配置,先前博主曾经有过相关方面的配置&…

【数据结构Java版】 初识泛型和包装类

目录 1.包装类 1.1基本数据类型以及它们所对应的包装类 1.2装箱和拆箱 1.3自动装箱和自动拆箱 2.什么是泛型 3.引出泛型 4.泛型类的使用 4.1语法 4.2示例 4.3类型推导 5.泛型是如何编译的 5.1擦除机制 5.2正确的写法 6.泛型的上届 6.1语法 6.2示例 …