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.mfbz.cn/a/488622.html

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

相关文章

✮✮✮宁波CE认证,CE认证,CE产品检测✮✮✮

✮✮✮🌈宁波CE认证,🌈CE认证,🌈CE产品检测🌈✮✮✮ ❀热点:😘CE认证什么意思 ❀优势:😜CE认证的目的 ✎🍒CE认证定义和目的 ✎🍐CE认…

李宏毅深度强化学习导论——演员-评论员

引言 本文主要介绍演员-评论员(Actor-Critic)算法。 Critic 给定Actor θ \theta θ,Critic评估当观测到 s s s(或进一步地采取行动 a a a)的好坏。 价值函数(Value function),记为 V θ ( s ) V^\theta(s) Vθ(s),就是一种Critic。 它的…

蓝桥杯刷题(十四)

1.小平方 代码 n int(input()) count0 def f(x)->bool: # 判断条件return True if x**2%n<n/2 else False for i in range(1,n): # 遍历[1,n-1]&#xff0c;符合题意计数加一if f(i):count1 print(count)2.3的倍数 代码 a int(input()) b int(input()) c int(input…

【python】flask各种版本的项目,终端命令运行方式的实现

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Java:ArrayList与顺序表

一、线性表 线性表是n个具有相同特征的数据元素的有限序列&#xff0c;它是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表有&#xff1a;顺序表、链表、栈、队列...... 如图&#xff1a;顺序表与链表的区别看了标题的伙伴就应该知道&#xff0c;我们这次要讲解的主…

【浏览器渲染-输入Url到页面渲染全流程】

概述 在面试题中有一道经典面试题就是浏览器输入url之后发送了什么&#xff0c;看了下网上的大多数文章都感觉不太全&#xff0c;所以这里梳理了比较全的流程&#xff0c;如果有误&#xff0c;欢迎评论指正。本文大致是从以下内容概览入手&#xff0c;有需要的可以跳转到感兴趣…

初识C++(三)构造函数和析构函数

目录 一、构造函数&#xff1a; 1.构造函数的概念&#xff1a; 2.构造函数的特性&#xff1a; 3.构造函数的形式&#xff1a; 4.为什么要引出构造函数这一概念 5.默认构造函数包括&#xff1a; 6.对默认生成的构造函数不处理内置类型的成员这事的解决办法&#xff1a; …

docker可视化界面 - portainer安装

目录 一、官方安装说明 二、安装portainer 2.1拉取镜像 2.2运行portainer容器 2.3登录和使用portainer 一、官方安装说明&#xff1a; Install PortainerChoose to install Portainer Business Edition or Portainer Community Edition.https://www.portainer.io/install…

stm32待机模式被意外唤醒之原因分析

1. 故障现象 客户在项目中使用 STM32G0B1, 由产品内置电池供电. 客户在程序中有使用到 standby 模式, 通过 WKUP2(PC13), WKUP6 引脚唤醒. 除此之外并没有其它唤醒源. 代码中有使用到 RTC,但只是用来记录日期和时间, 并没有参与 standby 的唤醒. 有两种故障现象 : 第一种 : …

Typora结合PicGo + Github搭建个人图床

目录 一 、GitHub仓库设置 1、新建仓库 2、创建Token 并复制保存 二、PicGo客户端配置 1、下载 & 安装 2、配置图床 三、Typora配置 一 、GitHub仓库设置 1、新建仓库 点击主页右上角的 号创建 New repository 填写仓库信息 2、创建Token 并复制保存 点击右上角…

【Unity人机交互】人工智能之爬虫开章

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

如何在内网访问其他电脑?

网络的发展使得人与人之间的通信变得更加便捷&#xff0c;而在公司或者家庭中&#xff0c;也经常遇到需要内网访问其他电脑的需求。内网访问其他电脑可以实现在局域网内部进行数据共享、文件传输、远程控制等操作&#xff0c;提高工作效率和便利性。本文将介绍内网访问其他电脑…

(已解决)vue运行时出现Moudle Bulid error: this.getoptios is not a function at........

1.首先查看你的less-loader版本 点击package.json 即可查看less-loader版本&#xff0c;我之前的版本是12.0&#xff0c;太高了&#xff0c;出现了不兼容的问题 2、卸载less-loader ctrlshift~ 打开项目终端 &#xff0c;输入&#xff1a; npm uninstall less-loader 3.重…

浙江省某市监局 API 敏感数据保护与全链路数据安全管控实践

背景 随着政务服务数字化转型的加速&#xff0c;政府信息化建设、大数据分析应用以及智慧监管建设等现代化、智能化转型持续推进&#xff0c;新的数据安全风险也暗藏其中。为加强公共数据安全体系建设&#xff0c;提升数据安全主动防御能力、监测预警能力、应急处置能力、协同…

【C++】vector介绍

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 前言2. vector的介绍3. Member functions3.1 (constructor)3.2 (destructor) 4. Capacity4.1 resize4.2 reserve4.3 shrink_to_fit 5. vector 增删查改5.1 push_back5.2 insert5.3 pop_back5.4 find5.5 erase 1. 前…

Windows Docker 部署 MongoDB 数据库

部署 MongoDB 打开 Docker Desktop&#xff0c;切换到 Linux 容器。然后在 PowerShell 执行下面命令&#xff0c;即可启动一个 MongoDB 服务。这里安装的是 7.0.7 Tag版本&#xff0c;如果需要安装其他或者最新版本&#xff0c;可以到 Docker Hub 进行查找。 docker run -d -…

基于 Amazon Bedrock 的 Claude 3 体验:ChatGPT 已经 OUT 了吗?Claude 3 数据实测

文章目录 前言一、Claude 3 系列大模型开发团队二、基于 Amazon Bedrock 的 Claude 3 体验三、Claude 3 数据实测3.1、申请模型访问权限3.2、Claude 3 回答的严谨性3.3、验证 Claude 3 较于 ChatGPT-4 数据集更新时间3.4、“二分法”判断 Claude 3 训练数据截止时间3.5、综合二…

瑞吉外卖实战学习--登录过滤器和判断是否登录过

完善登录功能 1、创建自定义过滤器LoginCheckFiler1.1通过WebFilter创建过滤器1.2 验证是否可以拦截请求1.3 代码 2、在启动类加入注解ServletComponentScan 用来扫描过滤器触发所有的过滤器ServletComponentScan 3、完善过滤器的处理逻辑3.1判断是否需要是要放行的请求3.2判断…

斌之曲科技集团迎接绵阳科技城新区领导考察,共探数字新能源

2024年3月22日上午&#xff0c;一场旨在促进科技与经济发展深度融合的考察活动在上海斌之曲科技集团总部隆重举行。绵阳科技城新区经济合作局局长陈桂全一行到访&#xff0c;集团董事长田斌先生、总裁廖彬曲女士热情接待&#xff0c;双方就科技创新、市场布局等议题进行了深入探…

js逆向入门之简概实例--MD5

目录 js逆向入门之简概&实例--MD5 爬虫: 爬虫流程&#xff1a; 逆向js原因: 网站反爬: 什么是MD5? js加密特征: 练习开始 正常请求 加post请求 伪装加U-Sign参数 伪装加Content-Type参数 请求参数变字符串 代码实现: 真逆开始 补充知识点: 代码 免责声明…
最新文章