Redis缓存问题

news/2024/10/18 8:22:43/

目录

1、缓存穿透

2、缓存击穿

3、缓存雪崩

​​​​​​​4、Redis的并发竞争key问题


​​​​​​​1、缓存穿透

        大量请求缓存中和数据库不存在的数据。

        大量用户请求缓存中和数据库中不存在的数据,导致所有请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。

解决方案:

  • 布隆过滤器(增加一个原理图)

        

        布隆过滤器的底层是一个位数组,数组的每个元素只能是0和1。

        添加数据时,将数据通过多个hash算法,映射到位数组中的不同位置,并将该位置为1。

        查询数据时,通过多个hash算法,找出查询数据在位数组中占据的位置,若所占位置全部为1,则说明该数据存在。

        优点:不存储完整的数据,所以占用内存小,查询速度快;

        缺点:hash算法映射的地址可能会重复,只能判断数据一定不存在,无法判断数据一定存在,有一定的误判率。且只支持新增和查询,不支持删除操作。

  • 缓存空对象

        当持久层不命中时,即使返回的空对象也存储在缓存中,并设置一个过期时间,之后再访问这个空数据就不用再去请求数据库。(防止用户反复用同一个id进行暴力攻击)

        会存储很多无用的空键,占用缓存空间。

​​​​​​​2、缓存击穿

        大量请求缓存中同一个失效的热点key数据。

        大量用户并发对缓存中的同一个热点key进行请求,当该热点key失效的时候,持续的大并发请求就击穿缓存,直接请求数据库,导致数据库短时间承受大量请求而崩溃。

解决方案:

  • 设置热点key永不过期
  • 互斥锁

        多个线程同时请求同一个数据时,为第一个请求数据库的线程操作加锁,其他请求等待;等到第一个请求完成后,刷新缓存,其他请求就可以直接通过缓存获取数据。

​​​​​​​3、缓存雪崩

        大量请求缓存中大面积失效的缓存数据。

        缓存同一时间大面积失效(缓存过期,缓存服务宕机),大量用户并发访问缓存时,会将请求落到数据库上,导致数据库短时间承受大量请求而崩溃。

解决方案:

  • 缓存数据设置随机的过期时间,防止同一时间大量数据集合失效
  • 集群,将数据分布在不同的缓存数据库中
  • 限流,通过加锁或队列来控制读数据库写缓存的线程数量

​​​​​​​4、Redis的并发竞争key问题

        多个Redis的客户端同时set key引起的并发问题。

        比如客户端1和客户端2需要对Redis中key为price的值+10,并发执行顺序如下:

  1. 客户端1读取price1 = 0;
  2. 客户端2读取price2 = 0;
  3. 客户端1写入price = price1+10 = 10;
  4. 客户端2写入price = price2+10 = 10。
  5. 最终Redis结果为10,而不是预期的20。

解决方案:

  • 分布式锁

        在redis的服务端用一个状态值表示锁,对锁的占用和释放通过状态值来标识

  • 消息队列

         把redis.set操作放在队列中,串行化处理。

  • 乐观锁

        假设不会冲突,使用redis命令watch进行构造。

        watch:监控一个或多个键,一旦其中有一个键被修改/删除,之后的事务就不会执行。

        multi:标记事务块的开始。Redis会将后续的命令逐个放入队列中。

        exec:在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态。

watch price
get price $price
$price = $price + 10
multi
set price $price
exec

以上内容为个人学习理解,如有问题,欢迎在评论区指出。

部分内容截取自网络,如有侵权,联系作者删除。


http://www.ppmy.cn/news/748.html

相关文章

Ambari-yarn-timeline 内置 HBase数据表清理

HDP 集群 timeline 内置的 HBase 数据表持续增大,我们将默认TTL30改 为7 天。 ambari界面YARN 服务中 的 timeline v2.0 timeline 内置 HBase数据HDFS路径 : 表在HDFS上的大小 使用如下命令进入 Hbase shell [hdfswinner-backup-hdp root]$ hbase -…

【C++】vector的认识+模拟实现

目录1️⃣vector的概念2️⃣STL中vector的使用2.1 vector的定义2.2 iterator的使用2.3 vector的空间问题2.4 vector的增删查改2.5 迭代器失效问题2.5.1 什么是迭代器?2.5.2 迭代器失效3️⃣vector的模拟实现3.1 迭代器3.2 构造函数🔎memcpy的拷贝异常问题…

论文笔记 A Comprehensive Survey on Graph Neural Networks(GNN综述)

前言 近年来,深度学习促进了很多机器学习任务的发展,这些任务很多都表示在规则的欧几里得空间中表示。但是图作为具有复杂关系和对象之间相互依赖,其数据是从非欧几里得域生成的,最近也有很多关于图数据深度学习方法的研究。 在…

6.终于了解volatile的原理和使用方法了

1.volatile能保证可见性 先说个案例: 有两个线程A和B,有一个公共的 boolean flag 标记位,最开始赋值为 true;B线程循环,根据这个flag来进行执行或者退出;这时线程A把flag改成false这个时候希望线程B看到变…

Android Profiler入门与实践

1、内存分析 点击MEMORY,可以看到正在运行进程的各种内存使用情况 Tips:点击右上角的垃圾桶图标会触发强制gc 1.1、查看Java堆内存和Java实例 执行以下代码: 说明:list为MainActivity的全局变量,所以list的只有在M…

Oracle面试题整理

目录 Oracle面试题整理 1.MySQL和Oracle的区别: 2.Oracle中function和procedure的区别? 3. 比较truncate和delete命令 ? 4.oralce中 rowid, rownum的定义 5. 事务的特性(ACID)是指什么 6. 列举几种表连接方式…

微机----------LED显示接口

目录 LED显示器的工作原理采用专用芯片进行LED段译码软件译码法静态显示与动态显示LED显示器的工作原理 LED显示器的主要部分是七段发光管,这七段发光段分别称为a、b、c、d、e、f、g有的产品还附带有一个小数点DP。通过7个发光段的组合,可以显示0 ~ 9 和 A ~ F共16个字母数字…

使用azure-data factory

data-fatory介绍 Azure Data Factory(简写 ADF)是Azure的云ETL服务,简单的说,就是云上的SSIS。ADF是基于云的ETL,用于数据集成和数据转换,不需要代码,直接通过UI(code-free UI&…