Redis——缓存设计与优化

讲解Redis的缓存设计与优化,以及在生产环境中遇到的Redis常见问题,例如缓存雪崩和缓存穿透,还讲解了相关问题的解决方案。

1、Redis缓存的优点和缺点

1.1、缓存优点:

  • 高速读写:Redis可以帮助解决由于数据库压力造成的延迟现象,针对很少改变的数据并且经常使用的数据,我们可以把这些数据放入内存中。这样一方面可以减小数据库压力,另一方面可以提高读写效率。
  • 降低后端负载:后端服务器通过缓存降低负载,业务端使用Redis可以降低后端数据库MySQL的负载等。

1.2、缓存缺点:

  • 数据不一致:程序的缓存层和数据层有时会不一致,这和更新数据策略有关。
  • 代码维护成本:原本只需要读写MySQL就能实现功能,但加入了Redis缓存之后就要去维护缓存中的数据,增加了代码复杂度。
  • 堆内缓存可能带来内存溢出的风险,从而影响用户进程:在Java虚拟机的EhCache、LoadingCache、Java虚拟机栈、方法区、本地方法栈、程序计数器中,堆内缓存可能会带来内存溢出的风险,从而影响用户进程。

2、缓存雪崩

2.1、什么是缓存雪崩

缓存雪崩是指数据未加载到缓存中,或者缓存在同一时间大面积失效,导致所有请求都查询数据库,从而导致数据库CPU和内存负载过高,甚至数据库宕机。

2.2、有什么解决方案来防止缓存雪崩

(1)使用互斥锁(mutex)。使用互斥锁来防止缓存雪崩,使用Redis的SETNX命令去设置一个mutex key,当操作返回成功时,再执行查询数据库操作并回设Redis缓存。否则,就重试执行缓存的GET方法。

(2)缓存预热。缓存预热就是应用上线后,将相关的缓存数据直接加载到缓存系统中。这样用户就可以直接查询事先被预热的缓存数据。

(3)双层缓存策略。Cache 1为原始缓存,Cache 2为复制缓存。Cache 1失效时,可以访问Cache 2。Cache 1缓存失效时间设置为短期,Cache 2缓存失效时间设置为长期。

(4)定时更新缓存策略。对失效性要求不高的缓存,在容器启动初始化加载时采用定时任务更新或移除缓存。

(5)设置不同的过期时间,让缓存失效的时间点尽量均匀。

3、缓存穿透

3.1、什么是缓存穿透

缓存就是数据交换的缓冲区。缓存的主要作用是提高查询效率。在企业开发的软件系统中常常使用Redis作为缓存中间件,当请求到达服务器端时,优先查询缓存中的数据,当缓存中不存在时,再查询数据库,如果在数据库中查询到数据会将数据写回缓存,使得下一次同样的请求能够在缓存中直接查询到数据。一些攻击性请求会特意查询缓存中不存在的数据,产生缓存穿透。

缓存穿透是指查询一个不存在的数据。例如,Redis在缓存中没有查询到要查询的数据,需要去数据库查询,如果查询不到数据则不写入缓存,这将导致这个不存在的数据在每次请求时都到数据库查询,进而对数据库产生流量冲击造成缓存穿透。

3.2、有什么解决方案来防止缓存穿透

(1)采用布隆过滤器。

(2)缓存空值。如果一个查询返回的数据为空值,那么不管是数据不存在,还是系统故障,程序仍然会把这个空值进行缓存处理,但它的过期时间会很短,可能不超过5min。通过设置的默认值将该数据直接存放到缓存中,这样第二次在缓存中就可以查询到值了,而不会继续访问数据库。

4、布隆过滤器

4.1、布隆过滤器简介

布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率高和查询时间短,缺点是有一定的误识别率和元素删除困难。

布隆过滤器是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合。布隆过滤器由一个很长的位数组和一系列散列函数组成,数组的每个元素都只占1 bit空间,并且每个元素只能为0或1。

布隆过滤器还拥有k个散列函数,当一个元素加入布隆过滤器时,会使用k个散列函数对其进行k次计算,得到k个散列值,并且根据得到的k个散列值,在位数组中把对应位置的值置为1。判断某个元素是否在布隆过滤器中,就对该元素进行k次散列计算,判断得到的值在位数组中对应位置的值是否都为1,如果每个元素都为1,就说明这个元素在布隆过滤器中。

将数据库中需要查询的数据放入系统缓存中的布隆过滤器中,当请求向后台系统查询数据时,先去系统缓存中的布隆过滤器中进行查找,如果查询的数据在布隆过滤器中不存在,就不用查询数据库了,直接给请求返回一个未查询到数据的结果,从而避免了对数据库的频繁查询。

布隆过滤器是一个判断元素是否属于集合的快速的概率算法。布隆过滤器有可能会出现错误判断,但不会漏掉判断。也就是说,如果布隆过滤器判断元素不在集合中,那么肯定不在;如果判断元素在集合中,那么会有一定的概率判断错误。因此,布隆过滤器不适合那些零错误的应用场景。而在能容忍低错误率的应用场景中,布隆过滤器比其他常见的算法(如散列函数、折半查找)极大节省了空间,如下图所示:
在这里插入图片描述
布隆过滤器很常用的一个功能是去重,比如在爬虫中有一个常见的需求:目标网站的URL可以有成千上万个,怎么判断某个URL是否被爬虫爬取过呢?一个简单的方法是,可以把爬虫爬取过的每个URL存入数据库中,每次一个新的URL过来就到数据库查询是否爬取过。例如,SELECT*FROM spider WHERE url=‘http://www.163.com’。

但是随着爬虫爬取过的URL越来越多,每次请求查询时都要访问数据库一次,判断某个URL是否访问过使用SQL查询效率并不高。除了数据库之外,还可以使用Redis的Set数据类型满足这个需求,并且其性能优于数据库。但是Redis也存在一个问题,它会耗费过多的内存,这时候就可以使用布隆过滤器来解决去重问题。相比于数据库和Redis,使用布隆过滤器可以很好地避免性能和内存占用的问题。

我们通常使用Redis作为数据缓存,当收到请求时先通过key去Redis缓存中查询,如果查询的数据在Redis缓存中不存在,就会去查询数据库中的数据。如果这种请求量很大,会给数据库造成很大的查询压力,从而影响系统的性能,这时就需要用到布隆过滤器来解决缓存穿透问题了。

解决缓存穿透的方法:

方法一:当数据库和Redis中都不存在key,查询数据库会返回null。需要在Redis中使用SETEX key null expireTime设置一个过期时间expireTime,这样当再次请求key时Redis将直接返回null,而不用再次查询数据库。

方法二:使用Redis提供的布隆过滤器模块RedisBloom,同样是将存在的key放入布隆过滤器中。当收到请求时先在布隆过滤器中查询key是否存在,如果key不存在直接返回null,不必再次查询数据库。

布隆过滤器的用途是判断过滤器中是否存在该数据,从而减少没有必要的数据库请求。

4.2、Redis加载布隆过滤器模块

Redis官方提供的布隆过滤器在Redis 4.0发布以后才正式推出。布隆过滤器可作为一个插件加载到Redis服务器中,给Redis提供强大的布隆去重功能。在本小节中,我们将学习如何在Redis服务器上加载布隆过滤器模块。

在GitHub搜索RedisBloom下载最新发布的源代码,单击页面的“Clone or download”按钮后选择“Download ZIP”,下载RedisBloom-master.zip到本地硬盘,如下图所示:
在这里插入图片描述
上传RedisBloom-master.zip到Linux服务器,在Linux服务器上进行解压缩和编译:

$ unzip RedisBloom-master.zip 
$ cd RedisBloom-master/ 
$ make

4.3、在项目中使用布隆过滤器

pom.xml文件中引入以下类库:

<dependencies> 
     <dependency> 
        <groupId>com.redislabs</groupId> 
        <artifactId>jrebloom</artifactId> 
        <version>1.0.1</version> 
     </dependency> 
 
     <dependency> 
        <groupId>redis.clients</groupId> 
        <artifactId>jedis</artifactId> 
        <version>3.1.0</version> 
     </dependency> 
   </dependencies>

新建测试类RedisbloomDemo。本实例使用“RedisbloomDemo.java”,内容如下:

 
import io.rebloom.client.Client; 
 
public class RedisbloomDemo { 
    public static void main(String[] args) { 
       // 创建客户端,Jedis实例 
       Client client = new Client("192.168.11.15", 6379); 
 
       String urlsBloomKey = "urls"; 
 
       // 创建一个有初始值和出错率的布隆过滤器 
       client.createFilter(urlsBloomKey,1000,0.01); 
       // 在布隆过滤器新增一个key-value键值对 
       boolean url1 = client.add(urlsBloomKey,"http://www.163.com"); 
       System.out.println("url1 add :" + url1); 
 
       boolean url2 = client.add(urlsBloomKey,"http://www.cnblogs.com"); 
       System.out.println("url2 add :" + url1); 
 
       // 某个value是否在布隆过滤器中存在 
       boolean exists = client.exists(urlsBloomKey, "http://www.163.com"); 
       System.out.println("http://www.163.com 是否存在: " + exists); 
    } 
}

该程序输出如下:

url1 add :true 
url2 add :true 
http://www.163.com 是否存在: true

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

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

相关文章

Blender教程(基础)-顶点的移动、滑移-16

一、顶点的移动与缩放 ShiftA新建柱体、切换到编辑模式 点模式下&#xff0c;选择一个顶点、选择移动&#xff08;GZ&#xff09;&#xff0c;发现顶点严Z轴移动&#xff0c;如下图所示 GY 按数字键盘7切换视图&#xff0c;选择这个面的所有顶点 按S把面缩放大 Ctrl…

第九个知识点:内部对象

Date对象: <script>var date new Date();date.getFullYear();//年date.getMonth();//月date.getDate();//日date.getDay();//星期几date.getHours();//时date.getMinutes();//分date.getSeconds();//秒date.getTime();//获取时间戳&#xff0c;时间戳时全球统一&#x…

一键放置柱子护角,你get了吗?

今天写个番外篇&#xff0c;给柱子添加护角。 记得几年前刚开始做BIM的时候&#xff0c;有次做车库导视方案模型&#xff0c;记得好像是鼎伦设计的车库一体化方案&#xff0c;当时柱子护角就给了两种方案&#xff0c;而且基本上每颗柱子上都要放护角&#xff0c;然后甲方竟然要…

容斥原理基础

文章目录 容斥原理的引入从集合的角度考虑推广例子不被2、3、5整除的数错排问题求不定方程的解Devu和鲜花 容斥原理的引入 从一个小学奥数问题引入&#xff1a; 一个班级有50人 喜欢语文的人有20人 喜欢数学的人有30人 同时喜欢语文数学的人有10人。 问题&#xff1a; 两门都不…

10个简单有效的编辑PDF文件工具分享

10个编辑PDF文件工具作为作家、编辑或专业人士&#xff0c;您可能经常发现自己在处理 PDF 文件。无论您是审阅文档、创建报告还是与他人共享工作&#xff0c;拥有一个可靠的 PDF 编辑器供您使用都非常重要。 10个简单适用的编辑PDF文件工具 在本文中&#xff0c;我们将介绍当今…

详细分析python中的 async 和 await(附Demo)

目录 前言1. 基本知识2. Demo2.1 Demo1&#xff08;同步&#xff09;2.2 Demo2&#xff08;错误&#xff09;2.3 Demo3&#xff08;不正确的异步&#xff09;2.4 Demo4&#xff08;正确异步&#xff09; 3. 完整版4. 拓展4.1 asyncio.create_task(coroutine)4.2 asyncio.gather…

FXTM富拓监管变更!2024开年连续3家交易商注销牌照

交易商的监管信息是经常发生变更的&#xff0c;即使第一次投资时查询平台监管牌照&#xff0c;投资者仍需持续关注其监管动态。千万不要以为第一步审核好后就万事大吉了&#xff01; 2024年开年&#xff0c;就有3家交易商的重要信息发生变更&#xff0c;注销其金融监管牌照&…

Java 将TXT文本文件转换为PDF文件

与TXT文本文件&#xff0c;PDF文件更加专业也更适合传输&#xff0c;常用于正式报告、简历、合同等场合。项目中如果有使用Java将TXT文本文件转为PDF文件的需求&#xff0c;可以查看本文中介绍的免费实现方法。 免费Java PDF库 本文介绍的方法需要用到Free Spire.PDF for Java…

编程实例分享,宠物诊所电子处方怎么开,兽医电子处方模板电子版操作教程

编程实例分享&#xff0c;宠物诊所电子处方怎么开&#xff0c;兽医电子处方模板电子版操作教程 一、前言 以下操作教程以 佳易王兽医电子处方软件V16.0为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、在系统 设置里可以设置打印参数&#x…

《动手学深度学习(PyTorch版)》笔记7.2

注&#xff1a;书中对代码的讲解并不详细&#xff0c;本文对很多细节做了详细注释。另外&#xff0c;书上的源代码是在Jupyter Notebook上运行的&#xff0c;较为分散&#xff0c;本文将代码集中起来&#xff0c;并加以完善&#xff0c;全部用vscode在python 3.9.18下测试通过&…

单片机学习笔记---LED点阵屏的工作原理

目录 LED点阵屏分类 LED点阵屏显示原理 74HC595的介绍 一片74HC595的工作原理 多片级联工作原理 总结 LED点阵屏由若干个独立的LED组成&#xff0c;LED以矩阵的形式排列&#xff0c;以灯珠亮灭来显示文字、图片、视频等。LED点阵屏广泛应用于各种公共场合&#xff0c;如汽…

go语言进阶篇——面向对象(一)

什么是面向对象 在我们设计代码时&#xff0c;比如写一个算法题或者写一个问题结局办法时&#xff0c;我们常常会使用面向过程的方式来书写代码&#xff0c;面向过程主要指的是以解决问题为中心&#xff0c;按照一步步具体的步骤来编写代码或者调用函数&#xff0c;他在问题规…

后端创建订单

package com.java1234.entity;import io.jsonwebtoken.Claims;/*** jwt验证信息* author java1234_小锋* site www.java1234.com* company Java知识分享网* create 2019-08-13 上午 10:00*/ public class CheckResult {private int errCode;private boolean success;private Cl…

Linux下的多线程

前面学习了进程、文件等概念&#xff0c;接下里为大家引入线程的概念 多线程 线程是什么&#xff1f;为什么要有线程&#xff1f;线程的优缺点Linux线程操作线程创建线程等待线程终止线程分离 线程间的私有和共享数据理解线程库和线程id深刻理解Linux多线程&#xff08;重点&a…

2023年全国职业院校技能大赛软件测试赛题第3套

2023年全国职业院校技能大赛 软件测试赛题第3套 赛项名称&#xff1a; 软件测试 英文名称&#xff1a; Software Testing 赛项编号&#xff1a; GZ034 归属产业&#xff1a; 电子与信息大类 …

软件价值10-数字时钟

这是一个数字时钟程序&#xff1a; # importing whole module from tkinter import * from tkinter.ttk import *# importing strftime function to # retrieve systems time from time import strftime# creating tkinter window root Tk() root.title(Clock)# This functio…

Docker Compose实例

目录 一、前提说明 二、简单的Docker容器部署案例 1. Dockerfile 配置 2. docker-compose.yml 配置 3. application.properties 配置 4. pom.xml 配置 5. 上传文件 6. 创建基础Docker镜像 7. docker-compose.yml编排 8. 停止并删除容器编排 一、前提说明 在配置好Do…

【博云2023】乘龙一跃腾云海,侧目抬手摘星河

癸卯渐远&#xff0c;甲辰渐至&#xff0c;预示着被汗水浇灌的种子&#xff0c;必将顶开冻土&#xff0c;迎接阳光。 每逢春节&#xff0c;当亲友彼此问候&#xff0c;博云人总能自豪地说&#xff0c;我们认真地、努力地奋斗&#xff0c;让我们能自信地踏上新的征程。 我们的…

使用Python进行数据的描述性分析,用少量的描述性指标来概括大量的原始数据

在进行数据分析时&#xff0c;当研究者得到的数据量很小时&#xff0c;可以通过直接观察原始数据来获得所有的信息。但是&#xff0c;当得到的数据量很大时&#xff0c;就必须借助各种描述性指标来完成对数据的描述工作。用少量的描述性指标来概括大量的原始数据&#xff0c;对…

用户和文件权限管理

一、用户管理 1、创建用户 [rootmaster ~]# useradd maple [rootmaster ~]# ll /home total 0 drwx------ 2 maple maple 62 Feb 7 20:47 maple drwx------ 2 www www 62 Jan 17 21:05 www [rootmaster ~]# passwd maple Changing password for user maple. New passwor…