Redis缓存的使用

什么是缓存

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

缓存的作用:

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

缓存的成本:

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

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.mzph.cn/news/192426.shtml

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

相关文章

C语言之结构体

一.前言引入. 我们知道在C语言中有内置类型,如:整型,浮点型等。但是只有这些内置类 型还是不够的,假设我想描述学⽣,描述⼀本书,这时单⼀的内置类型是不⾏的。描述⼀个学⽣需要名字、年龄、学号、⾝⾼、体…

Spark经典案例分享

Spark经典案例 链接操作案例二次排序案例 链接操作案例 案例需求 数据介绍 代码如下: package base.charpter7import org.apache.hadoop.conf.Configuration import org.apache.hadoop.fs.{FileSystem, Path} import org.apache.spark.SparkContext import org.a…

四、Zookeeper节点类型

目录 1、临时节点 2、永久节点 Znode有两种,分别为临时节点和永久节点。 节点的类型在创建时即被确定,并且不能改变。 1、临时节点 临时节点的生命周期依赖于创建它们的会话。一旦会话结束,临时节点将被自动删除,

OpenCV-Python:计算机视觉介绍

目录 1.背景 2.计算机视觉发展历史 3.计算机视觉主要任务 4.计算机视觉应用场景 5.知识笔记 1.背景 OpenCV是计算机视觉的一个框架,想要学习OpenCV,需要对计算机视觉有一个大致的了解。计算机视觉是指通过计算机技术和算法来模拟人类视觉系统的能力…

Redis高效缓存:加速应用性能的利器

目录 引言 1. Redis概述 1.1 什么是Redis? 1.2 Redis的特点 2. Redis在缓存中的应用 2.1 缓存的重要性 2.2 Redis作为缓存的优势 2.3 缓存使用场景 3. Redis在实时应用中的应用 3.1 实时数据处理的挑战 3.2 Redis的实时数据处理优势 3.3 实时应用中的Red…

mediapipe+opencv实现保存图像中的人脸,抹去其他信息

mediapipeopencv MediaPipe本身不提供图像处理功能,它主要用于检测和跟踪人脸、手势、姿势等。如果您想要从图像中仅提取人脸主要信息并去除其他信息. # codingutf-8 """project: teatAuthor:念卿 刘file: test.pydate&…

Kubernetes学习笔记-Part.09 K8s集群构建

目录 Part.01 Kubernets与docker Part.02 Docker版本 Part.03 Kubernetes原理 Part.04 资源规划 Part.05 基础环境准备 Part.06 Docker安装 Part.07 Harbor搭建 Part.08 K8s环境安装 Part.09 K8s集群构建 Part.10 容器回退 第九章 K8s集群构建 9.1.集群初始化 集群初始化是首…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《余电上网/制氢方式下微电网系统全生命周期经济性评估》

该标题涉及到对微电网系统的全生命周期经济性进行评估,其重点关注两种运营方式:余电上网和制氢。以下是对标题的解读: 微电网系统: 微电网是指一种小规模的电力系统,通常包括分布式能源资源(如太阳能、风能…

ES通过抽样agg聚合性能提升3-5倍

一直以来,es的agg聚合分析性能都比较差(对应sql的 group by)。特别是在超多数据中做聚合,在搜索的条件命中特别多结果的情况下,聚合分析会非常非常的慢。 一个聚合条件:聚合分析请求的时间 search time a…

部署springboot项目到GKE(Google Kubernetes Engine)

GKE是 Google Cloud Platform 提供的托管 Kubernetes 服务,允许用户在 Google 的基础设施上部署、管理和扩展容器。本文介绍如何部署一个简单的springboot项目到GKE. 本文使用podman. 如果你用的是docker, 只需要把本文中所有命令中的podman替换成docker即可 非H…

java+springboot物资连锁仓库经营商业管理系统+jsp

主要任务:通过网络搜集与本课题相关的素材资料,认真分析连锁经营商业管理系统的可行性和要实现的功能,做好需求分析,确定该系统的主要功能模块,依据数据库设计的原则对数据库进行设计。最后通过编码实现本系统功能并测…

Linux周期任务

我自己博客网站里的文章 Linux周期任务:at和crontab 每个人或多或少都有一些约会或者是工作,有的工作是长期周期性的, 例如: 每个月一次的工作报告每周一次的午餐会报每天需要的打卡…… 有的工作则是一次性临时的&#xff0…

Prometheus+Grafana搭建日志采集

介绍 一、什么是日志数据采集 日志数据采集是指通过各种手段获取应用程序运行时产生的各类日志信息,并将这些信息存储到特定的地方,以便后续分析和使用。通常情况下,这些日志信息包括系统运行状态、错误信息、用户操作记录等等。通过对这些…

牛客算法题 【HJ97 记负均正】 golang实现

题目 HJ97 记负均正 描述 首先输入要输入的整数个数n,然后输入n个整数。输出为n个整数中负数的个数,和所有正整数的平均值,结果保留一位小数。 0即不是正整数,也不是负数,不计入计算。如果没有正数,则平均…

大文件分片上传、分片进度以及整体进度、断点续传(一)

大文件分片上传 效果展示 前端 思路 前端的思路&#xff1a;将大文件切分成多个小文件&#xff0c;然后并发给后端。 页面构建 先在页面上写几个组件用来获取文件。 <body><input type"file" id"file" /><button id"uploadButton…

动态规划学习——回文串

目录 一&#xff0c;回文子串 1.题目 2.题目接口 3&#xff0c;解题代码及其思路 解题代码&#xff1a; 二&#xff0c; 分割回文串II 1&#xff0c;题目 2&#xff0c;题目接口 3&#xff0c;解题思路及其代码 一&#xff0c;回文子串 1.题目 给你一个字符串 s &…

模板初阶(2):函数模板的匹配原则,类模板的实例化

一、函数模板的匹配原则 int Add(const int& x, const int& y) {return x y; }template <class T> T Add(const T& x, const T& y) {return x y; }int main() {int a1 1, a2 2;Add(a1, a2);double d1 1.1, d2 2.2;Add(d1, d2);return 0; }一个非模…

【搭建网站】搭建一个自己的网站

【搭建网站】搭建一个自己的网站 传送门&#xff1a;搭建一个自己的网站&#xff1f;看这个就够了&#xff01; P1&#xff0c;建站准备 P2&#xff0c;创建站点

ZooKeeper 如何保证数据一致性?

在分布式场景中&#xff0c;ZooKeeper 的应用非常广泛&#xff0c;比如数据发布和订阅、命名服务、配置中心、注册中心、分布式锁等。 ZooKeeper 提供了一个类似于 Linux 文件系统的数据模型&#xff0c;和基于 Watcher 机制的分布式事件通知&#xff0c;这些特性都依赖 ZooKee…