高级java每日一道面试题-2024年10月8日-数据库篇[Redis篇]-谈—谈缓存穿透、缓存击穿和缓存雪崩,以及解决办法?

如果有遗漏,评论区告诉我进行补充

面试官: 谈—谈缓存穿透、缓存击穿和缓存雪崩,以及解决办法?

我回答:

在分布式系统和高并发场景中,缓存是提高系统性能和响应速度的重要手段。然而,如果缓存使用不当,可能会遇到一些问题,如缓存穿透、缓存击穿和缓存雪崩。下面我将详细解释这些问题以及相应的解决办法。

一、缓存穿透

定义

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。如果有恶意攻击者不断请求系统中不存在的数据,会导致短时间大量请求落在数据库上,造成数据库压力过大,甚至导致数据库承受不住而崩溃。

解决办法

  1. 接口校验:在接口层增加校验,如用户鉴权校验,对id做基础校验,id小于等于0的直接拦截。也可以在缓存层和数据库层都添加一些校验措施,例如检查请求的IP地址、User-Agent等信息,如果发现异常,则可以拒绝请求,防止缓存穿透。
  2. 使用布隆过滤器:布隆过滤器是一种概率型数据结构,可以用来判断一个元素是否在一个集合中。它类似于一个哈希算法,能够减少查询的次数,降低数据库的压力。
  3. 设置空值缓存:对于不存在的数据,可以设置一个默认值,如当查询不存在的数据时,返回这个默认值,而不是直接穿透缓存。也可以将key-value对写为key-null,并设置一个较短的过期时间(如30秒)。这样可以防止攻击用户反复用同一个id暴力攻击。
  4. 增加缓存更新频率:对于一些不常用的数据,可以增加其缓存更新频率,使得这些数据更快地过期,减少缓存穿透的可能性。
  5. IP限流:对频繁访问不存在数据的IP进行限流,防止恶意攻击。

二、缓存击穿

定义

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,导致数据库压力瞬间增大。

解决办法

  1. 设置热点数据不过期:对于经常被访问的热点数据,可以设置其缓存永不过期,从而避免缓存击穿的问题。
  2. 使用互斥锁:当缓存中不存在数据时,可以使用锁机制(如对key加锁),一次只允许一个线程去访问数据库,获取到数据后,马上更新缓存。这样可以避免大量并发请求同时冲击数据库。
  3. 设置逻辑过期时间:给缓存数据设置一个逻辑过期时间,而不是完全依赖于实际的缓存过期策略。当数据被访问时,先检查数据是否已经逻辑过期,如果是,则异步或在当前线程中更新缓存,同时返回旧数据给客户端。
  4. 延时更新:在缓存数据过期后,设置一个较短的过期时间,并在这个时间段内不断刷新缓存,直到数据从数据库中重新加载到缓存中。

三、缓存雪崩

定义

缓存雪崩是指缓存中大批量数据同时过期,而查询量又大,导致这些请求都落在数据库上,使得数据库层压力巨大,甚至宕机。

解决办法

  1. 分散过期时间:尽量让缓存中的数据过期时间分散一些,避免大量数据同时过期。
  2. 使用互斥锁或队列:在缓存失效时,可以设置一个短暂的锁定时间或队列,只允许一个请求查询数据库并刷新缓存,其他请求等待锁释放或队列处理后再读取缓存。
  3. 搭建缓存集群:为了防止单个缓存节点宕机导致雪崩,可以搭建缓存集群,提高缓存的容灾性。如 Redis Sentinel 或者 Redis Cluster,当某个缓存节点宕机时,其他节点可以继续提供服务,从而避免因为单个缓存服务器宕机导致的缓存雪崩问题。
  4. 设置热点数据不过期:类似于缓存击穿的处理方法,对于热点数据可以设置其永不过期。
  5. 实现本地缓存:在应用服务器本地维护一个小容量、高速缓存,作为远程缓存的补充,减少对外部缓存和数据库的依赖。
  6. 多级缓存:使用多级缓存策略,例如本地缓存 + 分布式缓存。即使分布式缓存失效,本地缓存也可以起到缓冲作用。如在本地缓存(如 Guava Cache 等)和分布式缓存(如 Redis)之间建立多级缓存。
  7. 限流与降级:通过限流技术控制到达数据库的请求数量,或者对某些非核心服务进行降级处理,优先保障系统的稳定性。
  8. 服务熔断:当检测到数据库负载过高时,触发服务熔断机制,暂时停止某些非核心服务的请求,以保护核心服务的正常运行。
  9. 异步更新:对于大规模更新操作,可以采用异步方式进行,避免短时间内大量数据失效。

总结

  • 缓存穿透:使用布隆过滤器或缓存空对象来减少无效请求对数据库的影响。
  • 缓存击穿:通过互斥锁、设置随机过期时间或永不过期来防止热点数据的集中访问。
  • 缓存雪崩:通过设置随机过期时间、多级缓存、限流与降级和服务熔断来分散失效时间和减轻数据库压力。

这些策略可以帮助你在高并发场景下更好地管理缓存,确保系统的稳定性和性能。

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

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

相关文章

Windows下MYSQL8.0如何恢复root权限

误操作把root权限清掉导致数据库无法登录(确实很难受),在网上找了很多方法,发现没有很行之有效的方法,在多方尝试终于找到了适合敏感宝宝体质的方法。 C:\Users\Administrator>mysql -u root -P3307 ERROR 1045 (2…

数据结构——遍历二叉树

目录 什么是遍历二叉树 根据遍历序列确定二叉树 例题(根据先序中序以及后序中序求二叉树) 遍历的算法实现 先序遍历 中序遍历 后序遍历 遍历算法的分析 二叉树的层次遍历 二叉树遍历算法的应用 二叉树的建立 复制二叉树 计算二叉树深度 计算二…

Redis 高可用方案

Redis 高可用性(High Availability)是指在 Redis 系统中实现持续的可用性,即使在发生硬件故障或其他意外情况下,系统仍能保持运行。 1 常用方案 为了实现 Redis 的高可用性,以下是几种常用方案: 1.1 使用…

常见校验算法介绍

文章目录 一、奇偶校验二、 校验和三、 BCC(Block Check Character,块校验字符)校验四、CRC(循环冗余校验)五、海明码校验六、MD5(消息摘要算法第五版)和 SHA(安全哈希算法&#xff…

1688商品评论接口技术深度解析与实战代码实现

引言 在电商领域,商品评论是消费者购物决策的重要依据。1688作为国内领先的B2B电商平台,提供了丰富的商品评论接口,供商家和开发者获取、管理并展示商品评论数据。本文将详细介绍如何调用1688商品评论接口,并提供Python实战代码示…

系统架构设计师教程 第16章 16.1 嵌入式系统概述 笔记

16.1 嵌入式系统概述 嵌入式系统 (Embedded System) 是为了特定应用专门构建的计算机系统,其架构是随着嵌入式系统的逐步应用而发展形成。 16.1.1 嵌入式系统发展历程 五个阶段: 一:单片微型计算机 (SCM) 阶段,即单片机时代。…

小猿口算自动PK脚本

大家好,我是小黄。 近期,众多大学生炸鱼小猿口算APP,把一众小学生都快虐哭了,小黄听闻后,也跃跃欲试。对此小黄也参考网上的资料写了一个自动Pk的脚步。 首先大家需要安装一个pytorch环境过程中,如果小伙伴对此不熟悉的…

C语言-输入输出

实验一:编写一个输出两行自定义字符的 C 程序 一、实验目的 熟悉 C 语言的基本结构和语法。掌握 printf() 函数的使用方法。了解在 Code::Blocks 中编写、编译和运行程序的过程。 二、实验内容 编写一个 C 程序,要求输出两行字符,内容自定…

软考《信息系统运行管理员》- 4.3 信息系统软件运维的过程

4.3 信息系统软件运维的过程 文章目录 4.3 信息系统软件运维的过程日常运维日常运维的内容日常运行例行测试维护例行测试流程的关键点例行维护流程的关键点 定期测试维护 缺陷诊断与修复信息系统软件缺陷的概念信息系统软件缺陷的分类信息系统软件缺陷诊断与修复流程缺陷诊断与…

springboot kafka多数据源,通过配置动态加载发送者和消费者

前言 最近做项目,需要支持kafka多数据源,实际上我们也可以通过代码固定写死多套kafka集群逻辑,但是如果需要不修改代码扩展呢,因为kafka本身不处理额外逻辑,只是起到削峰,和数据的传递,那么就需…

Koa学习

Koa 安装与配置 1. 初始化项目 在终端中执行以下命令: # 创建项目文件夹 mkdir koa cd koa# 初始化并安装依赖 npm init -y npm install koa npm install nodemon --save-dev2. 修改 package.json 在 package.json 文件中进行如下修改: {"type…

llava论文阅读

论文名称是 Visual Instruction Tuning 视觉指令微调 摘要 我们首次尝试仅使用语言模型GPT-4来生成多模态的语言-图像指令跟随数据。 通过在生成的数据上进行指令微调,我们引入了LLaVA(Large Language and Vision Assistant):一…

c++基础知识复习(1)

前期知识准备 1 构造函数 (1)默认构造函数:没有参数传入,也没有在类里面声明 (2)手动定义默认构造函数:没有参数传入,但是在类里面进行了声明 可以在类外实现或者类内实现 以下案…

【Windows】 C++实现 Socket 通讯

【Windows】 C实现 Socket 通讯 一&#xff1a;头文件与套接字实例 &#xff08;1&#xff09;Windows 系统下所需头文件 &#xff1a; #include<WinSock2.h>  &#xff08;2&#xff09;我们使用 SOCKET 来作为套接字的实例&#xff1a;通过查看源码得知其是一个无符号…

计算机网络803-(4)网络层

目录 1.虚电路服务 虚电路是逻辑连接 2.数据报服务 3.虚电路服务与数据报服务的对比 二.虚拟互连网络-IP网 1.网络通信问题 2.中间设备 3.网络互连使用路由器 三.分类的 IP 地址 1. IP 地址及其表示方法 2.IP 地址的编址方法 3.分类 IP 地址 &#xff08;1&#x…

LabVIEW中的非阻塞定时器

在LabVIEW编程中&#xff0c;通常需要在某些任务执行过程中进行非阻塞的延时操作。例如&#xff0c;显示某条信息一段时间&#xff0c;同时继续执行其他任务&#xff0c;并在延时时间结束后停止显示该信息。这类需求通常用于处理优先级不同的信息显示&#xff0c;如错误信息需要…

【Arduino IDE安装】Arduino IDE的简介和安装详情

目录 &#x1f31e;1. Arduino IDE概述 &#x1f31e;2. Arduino IDE安装详情 &#x1f30d;2.1 获取安装包 &#x1f30d;2.2 安装详情 &#x1f30d;2.3 配置中文 &#x1f30d;2.4 其他配置 &#x1f31e;1. Arduino IDE概述 Arduino IDE&#xff08;Integrated Deve…

Jupyter的使用分享

文章目录 碎碎念安装方法1.安装Anaconda方法2.通过库的安装方式 启动使用教程1.指定目录打开2.启动后的简单使用 小结 碎碎念 前情提示 之前与许多小伙伴交流的时候&#xff0c;发现大家对于pycharm更容易上手&#xff08;可能是比较好设置中文的原因&#xff09;&#xff0c;在…

算法: 前缀和题目练习

文章目录 前缀和题目练习前缀和二维前缀和寻找数组的中心下标除自身以外数组的乘积和为 K 的子数组和可被 K 整除的子数组连续数组矩阵区域和 前缀和题目练习 前缀和 自己写出来了~ 坑: 数据太大,要用long. import java.util.Scanner;public class Main {public static voi…

vue中用echarts做一个躺着的柱状图

在 Vue 中集成 ECharts 并绘制一个躺着的柱状图&#xff08;即横向的柱状图&#xff09;&#xff0c;你可以通过设置 ECharts 的 bar 类型&#xff0c;并配置 xAxis 和 yAxis 来实现。下面是一个完整的 Vue 示例代码。 示例代码&#xff1a; <template><div id"…