redis10 应用问题(穿透、击穿、雪崩、分布式锁)

思维草图

缓存穿透

查询不存在的数据,穿透redis缓存,请求直接攻击后端db。

问题

当系统中引入redis缓存后,一个请求进来后,会先从redis缓存中查询,缓存有就直接返回(相当于一道隔离闸,保护db),缓存中没有就去db中查询,db中如果有就会将其丢到缓存中。

但是有些key对应数据在db中并不存在,每次针对此次key的请求从缓存中取不到,请求都会压到db,从而可能压垮db。 比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用大量此类攻击可能压垮数据库。

解决方案

1.对空值缓存

如果一个查询返回的数据为空(不管数据库是否存在),我们仍然把这个结果(null)进行缓存,给其设置一个很短的过期时间,最长不超过五分钟。

2.设置可访问的名单(白名单)

使用redis中的bitmaps类型定义一个可以访问的名单,名单id作为bitmaps的偏移量,每次范文和 bitmap里面的id进行比较,如果访问的id不在bitmaps里面,则进行拦截,不允许访问。

3.采用布隆过滤器

布隆过滤器(Bloom Filter)是1970年有布隆提出的,它实际上是一个很长的二进制向量(位图)和一 系列随机映射函数(哈希函数)。 布隆过滤器可以用于检测一个元素是否在一个集合中,它的优点是空间效率和查询的世界都远远超过一 般的算法,缺点是有一定的误识别率和删除困难。 将所有可能存在的数据哈希到一个足够大的bitmaps中,一个一定不存在的数据会被这个bitmaps拦截掉,从而避免了对底层存储系统的查询压力。

4.进行实时监控

当发现redis的命中率开始急速降低,需要排查访问对象和访问的数据,和运维人员配合,可以设置黑名单限制对其提供服务(比如:IP黑名单)。

缓存击穿

当一个热点key突然失效,或者一个数据突然变成热点数据(key还没放进缓存),请求先查询redis,发现没有,所有的请求瞬间打到后端的db上,把db打穿。

问题

redis中某个热点key(访问量很高的key)过期,此时大量请求同时过来,发现缓存中没有命中,这些请求都打到db上了,导致db压力瞬时大增,可能会打垮db,这种情况成为缓存击穿。

key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据,这个时候,要考虑一个问题,缓存被“击穿”的问题

这种情况下redis正常运行,压力全都瞬间给到了db。

解决方案

1.预先设置热门数据,适时调整过期时间

在redis高峰之前,把一些热门数据提前存入到redis里面,对缓存中的这些热门数据进行监控,实时调 整过期时间。

2.使用锁

缓存中拿不到数据的时候,此时不是立即去db中查询,而是去获取分布式锁(比如redis中的setnx), 拿到锁再去db中load数据;没有拿到锁的线程休眠一段时间再重试整个获取数据的方法。

缓存雪崩

同一时间redis种大量的key同时失效,导致请求全部请求后端db,底层服务崩溃。

问题

key对应的数据存在,但是极短时间内有大量的key集中过期,此时若有大量的并发请求过来,发现缓存没有数据,大量的请求就会落到db上去加载数据,会将db击垮,导致服务奔溃。

缓存雪崩与缓存击穿的区别在于:前者是大量的key集中过期,而后者是某个热点key过期或者某个数据突然变成热点数据。

解决方案

1.构建多级缓存

nginx缓存+redis缓存+其他缓存(ehcache等)

2.使用锁或队列

用加锁或者队列的方式来保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上,不适用高并发情况。

3.监控缓存过期,提前更新

监控缓存,发下缓存快过期了,提前对缓存进行更新。

4.将缓存失效时间分散开(常用)

比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样缓存的过期时间重复率就会降低,就很难引发集体失效的事件。

(就是不要让所有的key同一时间失效)

分布式锁

问题

随着业务发展的需要,原单体单机部署的系统被演化成分布式集群系统后,由于分布式系统多线程、多进程且分布在不同机器上,这将使原单机部署情况下的并发控制锁策略失效,单纯的Java API并不能提供分布式锁的能力,为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题。

解决方案

1. 基于数据库实现分布式锁

2. 基于缓存(redis等)

3. 基于zookeeper

每一种分布式锁解决方案都有各自的优缺点,根据实际的业务场景进行选择

1. 性能:redis最高

2. 可靠性:zookeeper最高 

使用redis实现分布式锁

set key value NX PX 有效期(毫秒)

# 执行命令,返回ok表示执行成功,则获取锁成功,多个客户端并发执行此命令的时候,redis可确保只有一个可以执行成功。

总结

概括

  • 缓存穿透是指缓存中无法找到所需数据,导致每次请求都需要访问数据库,从而增加了数据库的负载。这种情况通常发生在恶意攻击或者查询不存在的数据时。
  • 缓存击穿是指一个缓存中的热点数据非常频繁地被大量并发请求访问,当该热点数据失效的瞬间,持续的大并发请求无法通过缓存获取到数据,而直接访问数据库。
  • 缓存雪崩是指在同一时间段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库给数据库带来巨大压力,可能导致数据库崩溃。

差异点

  • 缓存穿透是查询不存在的数据,而缓存击穿缓存雪崩是查询存在的数据。
  • 缓存击穿是一个热点key失效,而缓存雪崩是大量key同时失效。

记忆方法

  • 穿透:想象一个盗贼穿透了缓存直接攻击数据库,即查询不存在的数据。
  • 击穿:想象一个热门景点(热点key)被大量游客(并发请求)同时访问,但景点突然关闭(数据失效),游客只能转而访问其他景点(数据库)。
  • 雪崩:想象一场大雪压垮了多个景点(大量key同时失效),导致大量游客无处可去,只能涌向剩余的景点(数据库),给景点带来巨大压力。

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

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

相关文章

【打工日常】使用docker部署轻量的运维监控工具

一、Uptime-Kuma介绍 Uptime-Kuma是一个轻量级的自动化运维监控工具,最为引人注目的特点是其出色的监控Dashboard面板。部署简单,工具轻量又强大。而且,Uptime-Kuma是开源免费的,并支持基于Docker的部署方式。它支持网站、容器、数…

【李沐论文精读】Resnet精读

论文地址:Deep Residual Learning for Image Recognition 参考:撑起计算机视觉半边天的ResNet【论文精读】、ResNet论文逐段精读【论文精读】、【李沐论文精读系列】 一、导论 深度神经网络的优点:可以加很多层把网络变得特别深,然…

Java进阶-测试方法

来学习一下软件测试相关的方法,了解一下黑盒测试和白盒测试,以及后面要用到的JUnit单元测试。JUnit单元测试也属于白盒测试,这次内容较少且相对简单。 一、软件测试方法 1、黑盒测试 不需要写代码,给输入值,看程序…

打家劫舍(java版)

📑前言 本文主要是【动态规划】——打家劫舍(java版)的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是听风与他🥇 ☁️博客首页:CSDN主页听风与他 🌄每日一…

RT-DETR改进最新LSKNet结构:顶会ICCV2023|原创改进遥感旋转目标检测SOTA!大选择性卷积核的领域首次探索

💡本篇内容:RT-DETR改进最新LSKNet结构:顶会ICCV2023|原创改进遥感旋转目标检测SOTA!大选择性卷积核的领域首次探索 💡🚀🚀🚀本博客 RT-DETR 遥感旋转目标检测SOTA&…

GIS之深度学习10:运行Faster RCNN算法

(未完成,待补充) 获取Faster RCNN源码(开源的很多) 替换自己的数据集(图片标签文件) 打开终端,进入gpupytorch环境 运行voc_annotation.py文件生成与训练文件 E:\DeepLearningMode…

万物皆可模块化分解

引言 为何要模块化,这里的主体是人,客体是事物。当事物很小时,人可以很轻松的解决;但是当事物远大于人能处理的范围时,我们就可以考虑对它进行模块化分解。模块化是一种解决复杂问题的方式,放之四海而皆可…

SPI总线知识总结

1 SPI的时钟极性CPOL和时钟相位CPHA的设置 1.1 SPI数据传输位数 SPI传输数据过程中总是先发送或接收高字节数据,每个时钟周期接收器或发送器左移一位数据。对于小于16位的数据,在发送前必须左对齐,如果接收的数据小于16位,则采用软…

C++基于多设计模式下的同步异步日志系统day7(终)

C基于多设计模式下的同步&异步日志系统day7(终) 📟作者主页:慢热的陕西人 🌴专栏链接:C基于多设计模式下的同步&异步日志系统 📣欢迎各位大佬👍点赞🔥关注&#…

CAN总线位时序的介绍

CAN控制器根据两根线上的电位差来判断总线电平。总线电平分为显性电平和隐性电平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。 显性电平对应逻辑 0,CAN_H 和 CAN_L 之差为 2.5V 左右。而隐性电平对应逻辑 1&#xff0c…

深入理解现代JavaScript:从语言特性到应用实践

💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 JavaScript作为一门动态、解释性脚本语言&…

前端面试题 ===> 【JavaScript - 高级】

公众号:需要以下pdf,关注下方 2023已经过完了,让我们来把今年的面试题统计号,来备战今年的金三银四!所以,不管你是社招还是校招,下面这份前端面试工程师高频面试题,请收好。 JavaScr…

步进电机驱动器接法

实物 参数 共阳极: 使能给高电平有效 共阴极: 使能给低电平有效 整体接线 参考内容 B站UP范辉

基于Java SSM springboot+VUE+redis实现的前后端分类版网上商城项目

基于Java SSM springbootVUEredis实现的前后端分类版网上商城项目 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐…

深入理解Lambda表达式:基础概念与实战演练【第114篇—python:Lambda表达式】

深入理解Lambda表达式:基础概念与实战演练 在现代编程语言中,Lambda表达式作为一种轻量级的匿名函数形式,越来越受到程序员的青睐。特别是在函数式编程兴起的今天,Lambda表达式在简化代码、提高可读性方面发挥着重要作用。本文将…

【Web】浅浅地聊JDBC java.sql.Driver的SPI后门

目录 SPI定义 SPI核心方法和类 最简单的SPIdemo演示 回顾JCBC基本流程 为什么JDBC要有SPI JDBC java.sql.Driver后门利用与验证 SPI定义 SPI: Service Provider Interface 官方定义: 直译过来是服务提供者接口,学名为服务发现机制 它通…

加油站“变身”快充站,探讨充电新模式

摘要:新能源汽车规模化发展的同时,充电不便利的痛点愈发明显。在未来的新能源汽车行业发展当中,充电的矛盾要远远大于造车的矛盾,解决好充电的问题成为电动汽车行业发展的一个突出问题。解决充电补能问题,重要的方式之…

【牛客】VL60 使用握手信号实现跨时钟域数据传输

题目描述 分别编写一个数据发送模块和一个数据接收模块,模块的时钟信号分别为clk_a,clk_b。两个时钟的频率不相同。数据发送模块循环发送0-7,在每个数据传输完成之后,间隔5个时钟,发送下一个数据。请在两个模块之间添加…

(vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)

(vue)el-checkbox 实现展示区分 label 和 value&#xff08;展示值与选中获取值需不同&#xff09; 后端数据 解决方法 在 el-checkbox 标签中间传入要展示的文本即可&#xff0c;代码如下&#xff1a; <el-checkbox-groupv-model"formInline.processFieldList"…

【C语言】指针超级无敌金刚霹雳进阶(但不难,还是基础)

点击这里访问我的博客主页~~ 对指针概念还不太清楚的点击这里访问上一篇指针初阶2.0 上上篇指针初阶1.0 谢谢各位大佬的支持咯 今天我们一起来学习指针进阶内容 指针进阶 一、指针变量1、字符指针变量2、数组指针变量①数组指针变量的定义②数组指针变量的初始化 3、函数指…