Java面试篇:Redis使用场景问题(缓存穿透,缓存击穿,缓存雪崩,双写一致性,Redis持久化,数据过期策略,数据淘汰策略)

目录

  • 1.缓存穿透
    • 解决方案一:缓存空数据
    • 解决方案二:布隆过滤器
  • 2.缓存击穿
    • 解决方案一:互斥锁
    • 解决方案二:设置当前key逻辑过期
  • 3.缓存雪崩
    • 1.给不同的Key的TTL添加随机值
    • 2.利用Redis集群提高服务的可用性
    • 3.给缓存业务添加降级限流策略
    • 4.给业务添加多级缓存
  • 4.双写一致性
    • 1.问题:redis做为缓存,mysql的数据如何与redis进行同步呢?
    • 2.异步通知保证数据的最终一致性
  • 5.Redis持久化的方式
    • 1.RDB
      • RDB的执行原理
    • 2.AOF
    • 3.RDB与AOF对比
  • 6.Redis数据过期策略
    • 1.惰性删除
    • 2.定期删除
  • 7.数据淘汰策略
    • 使用建议:

1.缓存穿透

①缓存穿透是指在使用缓存系统时,频繁请求一个不存在于缓存中的数据,导致缓存系统无法起到预期的加速作用,而直接请求数据库或其他底层存储系统。

②缓存系统一般通过将数据存储在内存中,以提高读取速度。当一个请求到达时,缓存系统会先检查是否有缓存数据,如果有则直接返回,如果没有则从底层存储系统中读取数据,并将其缓存起来以备后续使用。

③然而,如果频繁请求一个不存在于缓存中的数据,每次请求都会直接访问底层存储系统,无法从缓存中获取数据,导致缓存系统无法发挥作用。这种情况下,即使缓存系统存在,仍然会对底层存储系统产生很大的负载,甚至可能导致底层存储系统崩溃。

④缓存穿透可能会发生的原因包括恶意攻击、大量的并发请求和数据更新等。为了解决缓存穿透的问题,可以采取一些修复措施,例如使用布隆过滤器来过滤掉不存在的数据请求、设置缓存的过期时间对缓存进行预热等。

在这里插入图片描述

查询一个不存在的数据,mysql查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库

解决方案一:缓存空数据

缓存空数据,查询返回的数据为空,仍把这个空结果进行缓存。
优点:简单
缺点:消耗内存,可能会发生不一致的问题

在这里插入图片描述

解决方案二:布隆过滤器

布隆过滤器(Bloom Filter)是一种用于判断某个元素是否存在于集合中的数据结构,它的特点是高效地判断一个元素是否存在于集合中,并且占用的内存空间相对较小。

布隆过滤器的核心是一个位数组(bit array)和一组哈希函数。当一个元素被加入布隆过滤器时,通过哈希函数将其映射为多个位数组的索引位置,并将这些位置的值设置为1。当判断一个元素是否存在于布隆过滤器时,同样通过哈希函数将其映射为多个位数组的索引位置,并检查这些位置的值是否都为1。如果有任何一个位置的值为0,则可以确定该元素不存在于集合中;如果所有位置的值都为1,则表示该元素可能存在于集合中,但不能确定是否真的存在,可能会存在误判的情况。

布隆过滤器的优点是占用的内存空间相对较小,且判断的速度非常快。但它也有一些缺点,其中最主要的就是可能存在误判的情况。由于布隆过滤器使用了多个哈希函数,所以在判断元素是否存在时可能会产生哈希冲突,导致误判。另外,布隆过滤器无法删除已经加入的元素,因为删除一个元素可能会影响到其他元素的判断结果。

布隆过滤器在实际应用中常用于缓存、数据库查询等领域,可以有效地提高查询效率和减轻底层存储系统的负载
在这里插入图片描述
布隆过滤器作用:布隆过滤器可以用于检索一个元素是否在一个集合中。

bitmap(位图)︰相当于是一个以(bit)位为单位的数组,数组中每个单元只能存储二进制数0或1

在这里插入图片描述

误判率:数组越小误判率就越大,数组越大误判率就越小,但是同时带来了更多的内存消耗。
在这里插入图片描述

优点:内存占用较少,没有多余key
缺点:实现复杂,存在误判

2.缓存击穿

缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮.

在这里插入图片描述

解决方案一:互斥锁

  • 强一致
  • 性能差

当缓存失效时,不立即去load db,先使用如Redis的setnx去设置一个互斥锁,当操作成功返回时再进行load db的操作并回设缓存,否则重试get缓存的方法

在这里插入图片描述

解决方案二:设置当前key逻辑过期

  • 高可用,性能优
  • 不能保证数据绝对一致

①在设置key的时候,设置一个过期时间字段一块存入缓存中,不给当前key设置过期时间
②当查询的时候,从redis取出数据后判断时间是否过期
③如果过期则开通另外一个线程进行数据同步,当前线程正常返回数据,这个数据不是最新

在这里插入图片描述

3.缓存雪崩

缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。

在这里插入图片描述

1.给不同的Key的TTL添加随机值

合理设置缓存失效时间:根据业务场景和数据特点设置合理的缓存失效时间,避免大量数据在同一时间失效。可以根据数据的访问频率和重要性来设置不同的失效时间

解决方案主要是可以将缓存失效时间分散开,比如可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件

2.利用Redis集群提高服务的可用性

哨兵模式、集群模式

  1. 数据分片:Redis 集群可以将数据按照一定的规则分片存储在不同的节点上,以提高数据处理能力和并发访问能力。

  2. 主从复制:通过配置 Redis 主从复制,可以将主节点的数据同步到多个从节点,实现数据的备份和故障恢复。当主节点发生故障时,从节点可以自动切换为主节点,保证服务的可用性。

  3. Sentinel 哨兵机制:Redis Sentinel 是 Redis 自带的高可用性解决方案,可以监控主节点和从节点的状态,并在主节点故障时自动选举新的主节点。哨兵还可以监控和修复其他节点的故障。

  4. 高可用性架构:搭建 Redis 集群时可以采用一主多从的高可用性架构,通过增加主节点和从节点来提高服务的可用性和并发处理能力。

  5. 集群模式:Redis 3.0 版本引入了 Cluster 集群模式,可以实现数据分片和自动故障转移。利用 Redis Cluster 可以搭建分布式的 Redis 集群,提高数据存储和处理的能力。

  6. 客户端链接失败重试:在客户端访问 Redis 集群时,可以设置失败重试机制,当某个节点连接失败时,自动尝试连接其他可用节点,提高服务的可用性。

3.给缓存业务添加降级限流策略

ngxin或spring cloud gateway

降级可做为系统的保底策略,适用于穿透、击穿、雪崩
限流降级:在高并发情况下,适当地对请求进行限流或降级,保护后端服务器的稳定性。

4.给业务添加多级缓存

Guava或Caffeine
使用多级缓存:将缓存分为多个层级,比如本地缓存和分布式缓存。
本地缓存可以使用内存,而分布式缓存可以使用 Redis。
这样即使 Redis 出现问题,本地缓存仍然可以提供部分服务。

4.双写一致性

1.问题:redis做为缓存,mysql的数据如何与redis进行同步呢?

可以通过以下几种方式将MySQL的数据同步到Redis缓存中:

  1. 手动同步:当MySQL中的数据发生变化时,手动编写代码将这些变化同步到Redis中。这可以通过使用MySQL的触发器或在代码中监听数据变化事件来实现。在触发器或事件中,将相应的数据插入、更新或删除到Redis中。

  2. 定时同步:定时将MySQL中的数据同步到Redis中。可以使用定时任务工具(例如Cron)来实现。设置一个定时任务,定期查询MySQL中的数据,然后将查询结果同步到Redis中。

  3. 增量同步:记录MySQL中数据的变化,只将发生变化的数据同步到Redis中。可以通过使用MySQL的二进制日志(binlog)来捕获MySQL中所有的修改操作,然后解析binlog,将修改的数据同步到Redis中。

  4. 使用消息队列:将MySQL中的数据变化通过消息队列传递给Redis,然后Redis消费这些消息来同步数据。可以使用消息队列工具(如RabbitMQ或Kafka)来实现。当MySQL中的数据发生变化时,将变化的数据作为消息发布到消息队列中,然后Redis作为消费者从消息队列中获取消息并将数据同步到Redis中。

无论使用哪种方式进行同步,都需要注意数据的一致性和并发性。在同步过程中,需要考虑数据的读写锁、事务处理和冲突解决等问题,以确保数据在MySQL和Redis之间的一致性。

双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致

在这里插入图片描述

  • 读操作:缓存命中,直接返回;缓存未命中查询数据库,写入缓存,设定超时时间
  • 写操作:延迟双删
    在这里插入图片描述

共享锁:读锁readLock,加锁之后,其他线程可以共享读操作
排他锁:也叫独占锁writeLock,加锁之后,阻塞其他线程读写操作

在这里插入图片描述

2.异步通知保证数据的最终一致性

使用MQ中间中间件,更新数据之后,通知缓存删除

在这里插入图片描述
利用canal中间件,不需要修改业务代码,伪装为mysql的一个从节点,canal通过读取binlog数据更新缓存
在这里插入图片描述

二进制日志(BINLOG)记录了所有的DDL(数据定义语言)语句和DML (数据操纵语言)语句
但不包括数据查询(SELECT、SHOW)语句。

5.Redis持久化的方式

1.RDB

RDB全称Redis Database Backup file (Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据

Redis内部有触发RDB的机制,可以在redis.conf文件中找到.

RDB的执行原理

bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据
完成fork后读取内存数据并写入RDB文件。

fork采用的是copy-on-write技术:

  • 当主进程执行读操作时,访问共享内存;
  • 当主进程执行写操作时,则会拷贝一份数据,执行写操作。

在这里插入图片描述

2.AOF

AOF全称为Append Only File(追加文件)。
Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件

AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF。

AOF的命令记录的频率也可以通过redis.conf文件来配:

在这里插入图片描述

因为是记录命令,AOF文件会比RDB文件大的多
而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意义。
通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同效果。

Redis也会在触发阈值时自动去重写AOF文件。阈值也可以在redis.conf中配置

在这里插入图片描述

3.RDB与AOF对比

RDB和AOF各有自己的优缺点,如果对数据安全性要求较高,在实际开发中往往会结合两者来使用。

在这里插入图片描述

6.Redis数据过期策略

Redis对数据设置数据的有效时间,数据过期以后,就需要将数据从内存中删除掉。可以按照不同的规则进行删除,这种删除规则就被称之为数据的删除策略(数据过期策略)。

1.惰性删除

设置该key过期时间后,我们不去管它,当需要该key时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key.

  • 优点∶对CPU友好,只会在使用该key时才会进行过期检查,对于很多用不到的key不用浪费时间进行过期检查
  • 缺点∶对内存不友好,如果一个key已经过期,但是一直没有使用,那么该key就会一直存在内存中,内存永远不会释放

2.定期删除

每隔一段时间,我们就对一些key进行检查,删除里面过期的key(从一定数量的数据库中取出一定数量的随机key进行检查,并删除其中的过期key)。

定期清理有两种模式:

  • SLOW模式是定时任务,执行频率默认为10hz,每次不超过25ms,以通过修改配置文件redis.conf的hz选项来调整这个次数
  • FAST模式执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms

优点:可以通过限制删除操作执行的时长和频率来减少删除操作对CPU的影响。另外定期删除,也能有效释放过期键占用的内存。
缺点:难以确定删除操作执行的时长和频率。

Redis的过期删除策略:惰性删除+定期删除两种策略进行配合使用

7.数据淘汰策略

当Redis中的内存不够用时,此时在向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略

①LRU (Least Recently Used)最近最少使用。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。
②LFU (Least Frequently Used)最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高。

Redis支持8种不同策略来选择要删除的key:

  • noeviction:不淘汰任何key,但是内存满时不允许写入新数据,默认就是这种策略
  • volatile-ttl:对设置了TTL的key,比较key的剩余TTL值,TTL越小越先被淘汰
  • allkeys-random: 对全体key,随机进行淘汰
  • volatile-random:对设置了TTL的key,随机进行淘汰
  • allkeys-Iru:对全体key,基于LRU算法进行淘汰
  • volatile-lru:对设置了TTL的key,基于LRU算法进行淘汰
  • allkeys-lfu: 对全体key,基于LFU算法进行淘汰
  • volatile-lfu:对设置了TTL的key,基于LFU算法进行淘汰

使用建议:

1.优先使用 alkeys-lru 策略。充分利用LRU算法的优势,把最近最常访问的数据留在缓存中。如果业务有明显的冷热数据区分,建议使用。
2.如果业务中数据访问频率差别不大,没有明显冷热数据区分,建议使用allkeys-random,随机选择淘汰。
3.如果业务中有置顶的需求,可以使用volatile-lru策略,同时置顶数据不设置过期时间,这些数据就一直不被删除,会淘汰其他设置过期时间的数据。
4.如果业务中有短时高频访问的数据,可以使用allkeys-lfu或 volatile-lfu策略

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

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

相关文章

2015年认证杯SPSSPRO杯数学建模C题(第一阶段)荒漠区动植物关系的研究全过程文档及程序

2015年认证杯SPSSPRO杯数学建模 C题 荒漠区动植物关系的研究 原题再现: 环境与发展是当今世界所普遍关注的重大问题, 随着全球与区域经济的迅猛发展, 人类也正以前所未有的规模和强度影响着环境、改变着环境, 使全球的生命支持系统受到了严重创伤, 出现了全球变暖…

C++动态内存管理:new/delete与malloc/free的对比

在C中,动态内存管理是一个至关重要的概念。它允许我们在程序运行时根据需要动态地分配和释放内存,为对象创建和销毁提供了灵活性。在C中,我们通常会用到两对工具:new/delete 和 malloc/free。虽然它们都能够完成类似的任务&#x…

Windows如何搭建 ElasticSearch 集群

单机 & 集群 单台 Elasticsearch 服务器提供服务,往往都有最大的负载能力,超过这个阈值,服务器 性能就会大大降低甚至不可用,所以生产环境中,一般都是运行在指定服务器集群中。 除了负载能力,单点服务器…

map china not exists. the geojson of the map must be provided.

map china not exists. the geojson of the map must be provided. 场景:引入echarts地图报错map china not exists. the geojson of the map must be provided. 原因: echarts版本过高,ECharts 之前提供下载的矢量地图数据来自第三方&…

[LeetCode]LCR 081. 组合总和

题目 思路 先找出数组中最小元素,与目标数比较: 若目标数小,则无组合可能; 若相等,则输出该最小元素; 若目标数大,则寻找一元素的组合可能,寻找二元素的组合可能 以candidates [2,3…

Future机制实际应用

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 常见的两种创建线程…

vue-office/docx插件实现docx文件预览

1.下包 //预览docx文件 npm install vue-office/docx vue-demi//如果是vue2.6版本或以下还需要额外安装 vue/composition-api2.引入 <template><div>//在src填入文档地址<VueOfficeDocx srchttp://...../xx.docx style"width:80%" rendered"re…

C++ 3.25作业

1、定义自己的命名空间&#xff0c;其中有string类型的变量&#xff0c;再定义两个函数&#xff0c;一个函数完成字符串的输入&#xff0c;一个函数完成求字符串长度&#xff0c;再定义一个全局函数完成对该字符串的反转 #include <iostream>using namespace std;namesp…

如何从外网访问内网服务器?

在网络通信中&#xff0c;内网服务器指的是位于私有网络内部的服务器&#xff0c;它们可以提供各种服务&#xff0c;如网站、应用程序等。由于安全性的考虑&#xff0c;内网服务器通常无法直接从外部网络访问。本文将介绍如何通过使用【天联】组网来实现从外网访问内网服务器的…

基于Spring Boot+Vue的美食推荐商城系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与环…

Element-Plus下拉菜单边框去除教程

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

2016年认证杯SPSSPRO杯数学建模C题(第二阶段)如何有效的抑制校园霸凌事件的发生全过程文档及程序

2016年认证杯SPSSPRO杯数学建模 C题 如何有效的抑制校园霸凌事件的发生 原题再现&#xff1a; 近年来&#xff0c;我国发生的多起校园霸凌事件在媒体的报道下引发了许多国人的关注。霸凌事件对学生身体和精神上的影响是极为严重而长远的&#xff0c;因此对于这些情况我们应该…

【Unity】调整Player Settings的Resolution设置无效

【背景】 Build时修改了Player Settings下的Resolution设置&#xff0c;但是再次Building时仍然不生效。 【分析】 明显是沿用了之前的分辨率设定&#xff0c;所以盲猜解决办法是Build相关的缓存文件&#xff0c;或者修改打包名称。 【解决】 实测修改版本号无效&#xf…

Windows服务器性能监控

Windows服务器操作系统设计用于运行在客户端-服务器架构内的服务器上&#xff0c;这些服务器通常设计用于处理繁重的工作负载&#xff0c;并作为企业中涉及的大多数软件操作的骨干。因此&#xff0c;为了防止由于性能问题而导致的任何服务损失并保持操作的无缝流&#xff0c;Wi…

Linux-进程控制(进程创建、进程终止、进程等待)

一、进程创建 1.1 fork函数介绍 在命令行下我们可以通过 ./ exe文件 来创建一个进程&#xff0c;通过fork函数&#xff0c;我们可以通过代码的形式从一个进程中创建一个进程&#xff0c;新进程为子进程&#xff0c;原进程为父进程&#xff0c;子进程在创建时&#xff0c;会与…

教育建筑智慧能源管理平台解决方案【新型电力系统下的绿色校园能源管理平台】

一、行业特点 1.建筑类型多&#xff1a;集教学、科研、生活于一体&#xff0c;占地面积大&#xff0c;建筑类型多&#xff0c;功能划分复杂。 2.供电可靠性要求高&#xff1a;教育建筑中的高层建筑、图书馆、实验楼等特级和一级负荷比较多&#xff0c;一旦发生故障会危及生命…

STM32 ESP8266模块的曲折探索

这是本文的配套资料&#xff0c;最终工程请参考 新_ESP8266资料\stm32f103成功移植的项目 【免费】stm32f103c8t6esp8266资料资源-CSDN文库 一、等到了ready 产品参数 我使用的是ai-thinker的esp8266-01s&#xff0c;以下为产品规格书 引脚定义&#xff1a; 依据引脚定义&…

android studio忽略文件

右键文件&#xff0c;然后忽略&#xff0c;就不会出现在commit里面了 然后提交忽略文件即可

如何在VS Code上搭建 C/C++开发环境

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、什么是VScode VScode&#xff08;Visual Studio Code&#xff09;是一款由微软开发的免费开源的轻量级代码编辑器。它…

如何成功将自己开发的APP上架到应用商店

随着移动应用市场的蓬勃发展&#xff0c;开发一款优秀的APP已成为许多企业和个人的首要选择。然而&#xff0c;成功上架并有效推广APP至关重要。本文将逐步介绍完整的上架流程&#xff0c;包括准备所需材料、注册开发者账户、进行APP备案、提交审核以及上架成功后的推广和维护。…