Redis缓存的使用

news2025/6/13 18:07:03

什么是缓存

缓存就是数据交换的缓冲区,是存储数据的临时地方,一般读写性能较高。

缓存的作用:

  • 降低后端负载
  • 提高读写效率,降低响应时间

缓存的成本:

  • 数据一致性成本
  • 代码维护成本
  • 运维成本

Redis特点

  • 键值型数据库,value支持多种不同数据结构,功能丰富
  • 单线程,每个命令具备原子性(在Redis6.0版本之后,采用多线程处理网络请求,核心部分仍是单线程)
  • 低延迟,速度快(基于内存,IO多路复用,采用C语言编写)
  • 支持数据持久化(定期将内存中的数据持久化到磁盘中)
  • 支持主从集群,分片集群
  • 支持多语言客户端

与MySQL的对比

MySQL

Redis

数据结构

结构化

非结构化

数据关联

关联的

无关联的

查询方式

SQL查询

非SQL

事务特性

ACID

BASE

存储方式

磁盘

内存

扩展性

垂直

水平

使用场景

数据结构固定,相关业务对数据安全性、一致性要求较大

数据结构不固定,对一致性,安全性要求不高,对性能有一定要求

Redis实现缓存

Redis缓存作用模型如下

缓存更新策略

内存淘汰

超时提出

主动更新

说明

不用自己维护,利用Redis的内存淘汰机制,当内存不足时自动淘汰部分数据。下次查询时更新缓存

给缓存添加TTL时间,到期后自动删除缓存,下次查询时更新缓存

编写业务逻辑,再修改数据库的同时,更新缓存

一致性

一般,取决于超时时间设置

维护成本

对于低一致性的需求我们可以采用内存淘汰

对于高一致行的需要我们需要主动更新并设置超时时间

主动更新策略

在解决一致性问题时,我们需要注意以下三个问题

1、在更新缓存时应该删除缓存还是直接更新缓存?

直接更新缓存:每次更新数据库时都会进行修改,当写多读少时,无效写操作过多。

删除缓存:更新数据库时,让缓存失效,查询时再更新缓存。

经过两种对比下,大多数场景都选择之间删除缓存。

2、如何保证缓存与数据库的操作同时成功或失败?

也就是说,如何保证更新缓存的原子性。

在单体系统中,将缓存与数据库操作放在同一个事物下。

在分布式系统中,利用TCC等分布式事务方案。

3、先操作数据库还是先操作缓存?

这涉及到多线程并发问题,接下来查看先删除缓存再操作数据库可能会出现的情况。正常情况下如下所示

但是如果在线程1更新数据时有其他线程开始执行查询操作,就会变成如下情况,这样会导致Redis中保存的数据仍然是旧数据,从而产生数据不一致问题。

那么,接下来查看先更新数据库再删除缓存可能会出现的情况。正常情况下如下图所示

但也可能存在如下一种情况,假设线程1先查询缓存,但是由于缓存已经失效,比如说过期或是Redis中不存在,但是就在从数据库写入缓存前线程2开始执行,从而导致写入缓存的仍然是旧数据。

即使这两种情况都会产生数据不一致的问题,但是总体来说先操作数据库后删除缓存出现数据不一致的概率要低于先删除缓存再更新数据库。因为如果先删除缓存的话,是一个微秒级别的操作,而更新数据库相对来说耗时比较久。在此之间可能会存在其他线程开始查询缓存并查询数据库写入缓存的问题。

但如果先更新数据库,期间即使有其他线程查询数据库并更新缓存执行,最后也会被更新数据库后的删除缓存操作将旧数据删除。其次,查询数据库操作耗时短,其他线程恰好开始更新数据库的概率低。

因此,更新缓存的最佳方案如下:

  1. 低一致性需求:使用Redis自带的内存淘汰机制
  2. 高一致性需求:主动更新,并以超时剔除作为兜底方案

读操作:

  • 缓存命中则直接返回
  • 缓存未命中则查询数据库,并写入缓存,设定超时时间

写操作:

  • 先写数据库,然后再删除缓存
  • 要确保数据库与缓存操作的原子性

缓存穿透

指查询一个数据库一定不存在的数据,最终导致所有请求打在数据库上,导致数据库压力变大。模型图如下

缓存空对象

模型图如下

即使查不到数据,也返回一个key为提交的数据,value为null的数据给缓存,并设置一个存活时间。

优点是实现简单,维护方便。

缺点是额外的内存消耗,可能造成短期的不一致,如果无法忍受数据不一致情况,可以在更新数据库时主动将数据更新到缓存当中。

布隆过滤器

模型图如下

查询时先通过布隆过滤器判断数据是否存在,如果不存在直接拒接,存在的话才会访问Redis或数据库,布隆过滤器实际上是一个算法,将数据库中存在的数据通过哈希算法得到哈希值然后转化为二进制位保存在布隆过滤器当作,当客户端请求发起时,通过判断请求的数据在布隆过滤器对应的位置是0还是1。

优点是内存占用少,没有多余的key。

缺点是实现复杂,存在误判。判断没有的数据一定没有,判断存在但不一定真的存在,还是存在一定穿透的问题。

以上是被动解决方案,我们也可以主动选择防止被穿透的方案。

设置id格式,然后进行基础格式校验,格式不对不进行查询。给用户进行权限设置。

缓存雪崩

指在一个时间段,缓存集中过期失效,在失效的时间段中,所有的访问查询都由数据库来操作,产生周期性的压力波峰。模型图如下

设置不同TTL:将缓存的数据设置不同的失效时间,避免在同一时间集中失效,对于热门的数据,存活时间长一点甚至可以设置永不过期。

设置Redis集群:为了防止Redis宕机造成的雪崩,要建立Redis集群,从而提高Redis的高可用性。

添加降级处理:当发现Redis出现故障时,应该进行快速失败,而不应该交给服务器处理。

添加多级缓存:在浏览器、Nginx或是JVM内部进行缓存,而不是单单只在Redis中进行缓存

缓存击穿

也叫热点key问题。是指一个key非常热点,在不停扛着大并发,大并发集中对于一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求到数据库上。模型图如下

互斥锁

模型图如下

同一时刻只需要一个线程对数据库访问就可以了,其他线程获取不到锁就休眠一会再去Redis进行查询。

缺点:线程需要等待,会影响性能。当一个线程需要获取多个锁时可能存在死锁风险。

优点:没有额外的内存消耗,保证了一致性,实现简单。

逻辑过期

模型图如下

不设置TTL的过期时间,而是存储再Value中,如果逻辑时间过期了,那么由一个线程拿到互斥锁后开辟一个新线程去进行数据库查询,重建缓存。其余线程仍然使用逻辑上的旧数据。

缺点:不保证一致性,有额外的内存消耗,实现复杂。

优点:性能上比较好。

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

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

相关文章

使用JSP+Servlet+MySQL实现登录注册功能

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Java从入门到精通 ✨特色专栏&#xf…

java使用poi读写excel(处理上下标和科学计数法)

Background 要读写如下图所示的excel,符号和单位中包含上下标,在读写时需要特殊处理;取值列中是科学计数法,读写时需要特殊处理;excel中包含多个sheet,读的时候把所有sheet的数据读出来,写的时候…

Azure Machine Learning - 使用.NET创建和管理AI搜索功能

本文介绍了如何在 Azure SDK for .NET 中使用 C# 和 Azure.Search.Documents客户端库来创建和管理搜索对象。 关注TechLead,分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之linux存储管理(2)》(18)

《Linux操作系统原理分析之linux存储管理(1)》(17) 6 Linux存储管理6.2 选段符与段描述符6.2.1 选段符6.2.2 段描述符6.2.3 分段机制的存储保护 6.3 80x86 的分页机制6.3.180x86 的分页机制6.3.2 分页机制的地址转换6.3.3 页表目录…

uni-app 微信小程序 电子签名及签名图片翻转显示功能

文章目录 1. 需求背景2. 开始撸2.1 点击 重写 进入签名页面(上图一)2.2 书写签名,点击确认返回,及图片翻转显示(上图二,三) 3. 图片进行翻转,返回翻转后的图片 1. 需求背景 接的一个…

结构体||联合体

1.结构体 1.1实际生活中一些东西往往有多个元素组成。如一名学生有身高、体重、名字、学号等。这时候就需要用到结构体。 结构体是一些值的结合,这些值被称为成员变量。结构体的每个成员可以是不同类型的变量,如:标量、数组、指针、甚至是其…

锐捷EWEB网管系统 RCE漏洞复现

0x01 产品简介 锐捷网管系统是由北京锐捷数据时代科技有限公司开发的新一代基于云的网络管理软件,以“数据时代创新网管与信息安全”为口号,定位于终端安全、IT运营及企业服务化管理统一解决方案。 0x02 漏洞概述 Ruijie-EWEB 网管系统 flwo.control.ph…

MATLAB实战 | S函数的设计与应用

S函数用于开发新的Simulink通用功能模块,是一种对模块库进行扩展的工具。S函数可以采用MATLAB语言、C、C、FORTRAN、Ada等语言编写。在S函数中使用文本方式输入公式、方程,非常适合复杂动态系统的数学描述,并且在仿真过程中可以对仿真进行更精…

【代码】多种调度模式下的光储电站经济性最优 储能容量配置分析matlab/yalmip

程序名称:多种调度模式下的光储电站经济性最优储能容量配置分析 实现平台:matlab-yalmip-cplex/gurobi 代码简介:代码主要做的是一个光储电站经济最优储能容量配置的问题,对光储电站中储能的容量进行优化,以实现经济…

仿京东淘宝商品列表筛选组件:实现一个高效的侧边栏弹框筛选功能

仿京东淘宝商品列表筛选组件:实现一个高效的侧边栏弹框筛选功能 一、引言 随着电子商务的快速发展,用户体验成为了竞争的关键因素。在众多的电商网站中,如京东和淘宝,商品列表筛选功能为用户提供了便捷的途径来找到心仪的商品。本…

策略模式与简单工厂模式:终结if-else混乱,让代码更清爽

阅读建议 嗨,伙计!刷到这篇文章咱们就是有缘人,在阅读这篇文章前我有一些建议: 本篇文章大概4500多字,预计阅读时间长需要5分钟。本篇文章的实战性、理论性较强,是一篇质量分数较高的技术干货文章&#x…

STM32-GPIO

一、GPIO简介 GPIO(General Purpose Input Output)通用输入输出口 可配置8种输入输出模式 引脚电平:0V~3.3V,部分引脚可容忍5V 输出模式下:可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输…

Windows11系统下MemoryCompression导致内存占用率过高

. # 📑前言 本文主要是win11系统下CPU占用率过高如何下降的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是青衿🥇 ☁️博客首页:CSDN主页放风讲故事 🌄每日…

java学习part30callabel和线程池方式

140-多线程-线程的创建方式3、4:实现Callable与线程池_哔哩哔哩_bilibili 1.Callable 实现类 使用方式 返回值 2.线程池

[英语学习][5][Word Power Made Easy]的精读与翻译优化

[序言] 今日完成第18页的阅读, 发现大量的翻译错误以及不准确. 需要分两篇文章进行讲解. [英文学习的目标] 提升自身的英语水平, 对日后编程技能的提升有很大帮助. 希望大家这次能学到东西, 同时加入我的社区讨论与交流英语相关的内容. [原著英文与翻译版对照][第18页] Wh…

Lattice-Based Blind Signatures: Short, Efficient, and Round-Optimal

目录 摘要引言 Lattice-Based Blind Signatures: Short, Efficient, and Round-Optimal CCS 2023 摘要 我们提出了一种基于随机预言机启发式和标准格问题(环/模块SIS/LWE和NTRU)的2轮盲签名协议,签名大小为22KB。该协议是全面优化的&#xf…

Elasticsearch 的使用

一、简介 1.Shard(分片) 数据分散集群的架构模式,Elasticsearch 将一个 Index(索引)中的数据切为多个 Shard(分片),分布在不同服务器节点上。 默认每个索引会分配5个主分片和1个副本…

HarmonyOS开发工具安装

目录 下载与安装DevEco Studio DevEco Studio下载官网,点击下载 下载完成后,双击下载的“deveco-studio-xxxx.exe” 进入DevEco Studio安装向导 选择安装路径 如下安装选项界面勾选DevEco Studio后,单击“Next” 点击Install 安装完…

【云备份】业务处理

文章目录 1. 业务处理作用功能 2. 代码框架编写构造函数UpLoad ——文件上传请求ListShow —— 展示页面请求处理实现Download —— 下载请求的处理实现断点续传实现 1. 业务处理 作用 业务处理模块是对客户端的业务请求进行处理 功能 1.文件上传请求:备份客户端…

A--Z与a--z的ASCII码的差异

从z到A还有一些字符 应该改为str[i]>A&&str[i]<Z||str[i]>a&&str[i]<z;