redis基础6——缓存穿透、缓存击穿、缓存雪崩

news2024/9/24 3:24:48

文章目录

  • 一、缓存穿透(双库为空)
    • 1.1 基础概念
    • 1.2 解决办法
      • 1.2.1 业务层校验
      • 1.2.2 设置key过期时间
      • 1.2.3 布隆过滤器
        • 1.2.3.1 原理
          • 1.2.3.1.1 哈希函数使用
          • 1.2.3.1.2 布隆过滤器数据结构
            • 1.2.3.1.2.1 映射函数执行过程
            • 1.2.3.1.2.2 布隆过滤器的误判率
        • 1.2.3.2 特性
        • 1.2.3.3 操作元素流程
        • 1.2.3.4 优缺点(缺点导致布谷鸟过滤器出现)
        • 1.2.3.5 安装启动
          • 1.2.3.5.1 二进制安装启动
            • 1.2.3.5.1.1 参数启动
            • 1.2.3.5.1.2 配置文件启动
          • 1.2.3.5.2 docker 安装
        • 1.2.3.6 布隆命令
          • 1.2.3.6.1 添加元素到布隆
          • 1.2.3.6.2 判断元素是否存在布隆
          • 1.2.3.6.3 查看布隆过滤器信息
          • 1.2.3.6.3 布隆命令其他参数
  • 二、缓存击穿(定点爆破)
    • 2.1 基础概念
    • 2.2 解决方案
      • 2.2.1 热key永不过期
      • 2.2.2 定时更新热key
      • 2.2.3 采用互斥锁
  • 三、缓存雪崩(没有一片雪花是无辜的!)
    • 3.1 基础概念
    • 3.2 解决方案
      • 3.2.1 设置有效期均匀分布(一视同仁)
      • 3.2.2 缓存限流(层层关卡)
      • 3.2.3 搭建集群(安全加固)
      • 3.2.4 数据预热(未卜先知)
      • 3.2.5 缓存降级(弃驹保帅)
      • 3.2.6 高压熔断(实时监控)
      • 3.2.7 及时隔离(画地为牢)

一、缓存穿透(双库为空)

1.1 基础概念

redis做缓存来用可用大大提高工作效率,先去访问redis内存里的数据,若没有再去访问数据库里的。

  • 概念: 当缓存和数据库中都没有客户端请求的的数据时,客户端还源源不断地发起请求,那么每次请求都会到数据库,从而压垮数据库服务器。

在这里插入图片描述

1.2 解决办法

1.2.1 业务层校验

用户发过来的请求,根据请求参数进行校验,对于明显错误的参数,直接拦截返回。

  • 使用情景:
    • 请求参数为主键自增id,那么对于请求小于0的id参数,明显不符合,可以直接返回错误请求。

1.2.2 设置key过期时间

对于不存在数据设置短过期时间。

  • 使用场景:
    • 当请求的key不存在时,返回的空结果设置过期时间,让redis暂时缓存一段时间,过期时间长短要根据实际业务来定。这种方法具有很大的局限性。

1.2.3 布隆过滤器

布隆过滤器(BloomFilter)是由一个固定大小的二进制向量或者位图(bitmap)和一系列映射函数组成的,可以判断一个元素是否在一个集合中。利用极小的内存,可以判断大量的数据“一定不存在或者可能存在”。

  • 使用场景:
    • 当客户端请求到来时,会把所有可能查询的参数哈希到一个足够大的布隆过滤器中存储,并在控制层进行校验,一定不存在的数据就直接拦截返回了,从而避免下一步对数据库的压力。

在这里插入图片描述

1.2.3.1 原理

布隆过滤器使用到哈希函数原理,我们可以先来了解一下哈希函数。

1.2.3.1.1 哈希函数使用

哈希函数的概念: 将任意大小的输入数据转换成特定大小的输出数据的函数,转换后的数据称为哈希值或哈希编码,也叫散列值。

  • 图示效果:

在这里插入图片描述

  • 散列函数基本特性:

    • 如果两个散列值是不相同的(根据同一函数),那么这两个散列值的原始输入也是不相同的。这个特性是散列函数具有确定性的结果,具有这种性质的散列函数称为单向散列函数
    • 散列函数的输入和输出不是唯一对应关系的,如果两个散列值相同,两个输入值很可能是相同的,但也可能不同,这种情况称为“散列碰撞(collision)”。

    当用hash表存储大数据量时,空间效率还是很低。因为当只有一个 hash 函数时,还很容易发生哈希碰撞。

1.2.3.1.2 布隆过滤器数据结构

BloomFilter 是由一个固定大小的二进制向量或者位图(bitmap)和一系列映射函数组成的。

1.2.3.1.2.1 映射函数执行过程

1、在初始状态时,位数组上的位都是0,如图所示。

在这里插入图片描述
2、当接收到客户端请求时,其变量就会被加入集合,通过多个映射函数将这个变量映射成位图中的多个点,并把这些位变为 1。比如下图中有两个变量都通过3个映射函数,那么会有6个映射函数处理位上的值,这6个函数中可能存在多个函数对同一个位产生变化,如图所示。
在这里插入图片描述

从映射函数执行过程中,我们可以得出结论:
查询某个变量的时候我们只要看看这些点是不是都是 1 就可以大概率知道集合中有没有它了。

  • 如果这些点有任何一个 0,则被查询变量一定不在;
  • 如果都是 1,则被查询变量很可能存在。
1.2.3.1.2.2 布隆过滤器的误判率

概念: 指多个输入变量经过哈希之后在相同的bit位置1了,这样就无法判断究竟是哪个输入变量产生的,根源在于同一个bit 位被多次映射且置 1。
这种情况也造成了布隆过滤器的删除问题,因为布隆过滤器的每一个 bit 并不是独占的,可能有多个元素共享了某一位。如果直接删除这一位会影响其他的元素。(比如上图中的第 6、11位)

1.2.3.2 特性

  1. 当一个元素判断结果为存在时,该元素不一定存在;当判断结果为不存在时,则该元素一定不存在。
  2. 布隆过滤器可以添加元素,但是不能删除元素。因为删掉元素会导致误判率增加。

1.2.3.3 操作元素流程

  • 添加元素
  1. 将要添加的元素给设定的哈希函数。
  2. 设定的多个哈希函数会把元素映射到多个位上,从而得到对应于位数组上的bit的位置。
  3. 将这bit位置设为 1。
  • 查询元素
  1. 将要查询的元素给设定的哈希函数。
  2. 设定的多个哈希函数会把元素映射到多个位上,从而得到对应于位数组上的bit的位置。
  3. 判断bit位的值;
    • 如果k个位置有一个为 0,则肯定不在集合中。
    • 如果k个位置全部为 1,则可能在集合中。

1.2.3.4 优缺点(缺点导致布谷鸟过滤器出现)

  • 优点
  1. 占用内存小。布隆过滤器存储空间和插入/查询时间都是常数 O ( K ) O(K) O(K)
  2. 影响服务器性能小。布隆过滤器运用了散列函数,其相互之间没有关系,方便由硬件并行实现。
  3. 一定场景下具备保密性。布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。
  4. 布隆过滤器可以表示全集,链表、树、散列表等数据结构都不能。
  • 缺点
  1. 存在误算率。存入元素数量越多,误算率多高。但是如果元素数量太少,可以使用散列列表不需要使用位图。
  2. 不能随意删除布隆过滤器中的元素。

1.2.3.5 安装启动

1.2.3.5.1 二进制安装启动
1.2.3.5.1.1 参数启动

1、下载安装包

wget https://github.com/RedisLabsModules/rebloom/archive/v2.2.6.tar.gz

2、解压编译

[root@localhost git-2.38.1]# tar -zxvf v2.2.6.tar.gz
[root@localhost git-2.38.1]# cd RedisBloom-2.2.6/
[root@localhost RedisBloom-2.2.6]# make

3、编译完成后,当前目录会生成一个redisbloom.so文件,服务端启动时需要指定该文件。

在这里插入图片描述
4、服务端启动成功后,就可以开始玩布隆过滤器基本指令了。

在这里插入图片描述

1.2.3.5.1.2 配置文件启动

可以在redis.conf配置文件里指定redisbloom.so文件位置,这样每次启动时不需要再指定参数启动,省事。

1、配置文件指定文件位置
在这里插入图片描述
2、服务直接启动就可以使用布隆过滤器了。
在这里插入图片描述

1.2.3.5.2 docker 安装

docker方式安装没有测试,大家可以尝试下。

docker pull redislabs/rebloom:latest # 拉取镜像
docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest #运行容器
docker exec -it redis-redisbloom bash
redis-cli    

1.2.3.6 布隆命令

1.2.3.6.1 添加元素到布隆
  • 单个元素
127.0.0.1:6381> bf.add baidu 888
(integer) 1

在这里插入图片描述

  • 多个元素
127.0.0.1:6381> bf.madd wuhan 111 222 333 
1) (integer) 1
2) (integer) 1
3) (integer) 1

在这里插入图片描述

1.2.3.6.2 判断元素是否存在布隆
  • 单个元素
127.0.0.1:6381> bf.add key1 111
(integer) 1
127.0.0.1:6381> bf.exists key1 111
(integer) 1
127.0.0.1:6381> bf.exists key1 999
(integer) 0

在这里插入图片描述

  • 多个元素
127.0.0.1:6381> bf.madd wuhan 111 222 333 
1) (integer) 1
2) (integer) 1
3) (integer) 1
127.0.0.1:6381> bf.mexists wuhan 111 222 999
1) (integer) 1
2) (integer) 1
3) (integer) 0

在这里插入图片描述

1.2.3.6.3 查看布隆过滤器信息

命令:bf.info [key名称]

  • Capacity:预设容量;
  • Size:实际占用情况,但如何计算待进一步确认;
  • Number of filters:过滤器层数;
  • Number of items inserted:已经实际插入的元素数量;
  • Expansion rate:子过滤器扩容系数(默认 2);

在这里插入图片描述

1.2.3.6.3 布隆命令其他参数

BF.RESERVE {key} {error_rate} {capacity} [EXPANSION {expansion}] [NONSCALING]

  • key:布隆的名字;
  • error_rate:期望的错误率,默认 0.1,值越低,需要的空间越大;
  • capacity:初始容量,默认 100,当实际元素的数量超过这个初始化容量时,误判率上升。
  • EXPANSION:可选参数,当添加到布隆过滤器中的数据达到初始容量后,布隆过滤器会自动创建一个子过滤器,子过滤器的大小是上一个过滤器大小乘以 expansion;expansion 的默认值是 2,也就是说布隆过滤器扩容默认是 2 倍扩容;
  • NONSCALING:可选参数,设置此项后,当添加到布隆过滤器中的数据达到初始容量后,不会扩容过滤器,并且会抛出异常((error) ERR non scaling filter is full) 说明:BloomFilter 的扩容是通过增加 BloomFilter 的层数来完成的。每增加一层,在查询的时候就可能会遍历多层 BloomFilter 来完成,每一层的容量都是上一层的两倍(默认)。

如果直接bf.add插入元素,则默认给的“error_rate”参数 是 0.01,“capacity”参数是 100。
Redis 还提供了自定义参数的布隆过滤器,bf.reserve 过滤器名 error_rate initial_size

二、缓存击穿(定点爆破)

2.1 基础概念

概念: 指redis中一个热点key在过期时,有大量的并发请求过来,从而会全部到达数据库,压垮数据库。

  • 例子:微博爆出一条大瓜,海量吃瓜群众同时去查看这条新闻,刚开始能正常看,可突然微博redis集群中的这条数过期了,大量的请求就会直接访问数据库,从而会导致数据库宕机。

执行流程:

  1. 客户端请求redis缓存里的热点key。
  2. 热点key失效,client直接访问数据库获取数据。
  3. 数据库将该热点key数据返回给各个客户端。
  4. 数据库再将该热点key重新缓存到redis里。

在这里插入图片描述

2.2 解决方案

2.2.1 热key永不过期

简单粗暴的不设置过期时间,但需要根据特定场景尝试。

2.2.2 定时更新热key

比如可以将某个 key 的缓存时间设置为 25 小时,用一个异步线程定时更新和设置过期时间。

2.2.3 采用互斥锁

互斥锁流程:

  1. 当client_1去请求内存数据时,发现热key过期没有命中,这时原子性执行setnx 命令,如果返回1则获取锁并对key设置过期时间。
  2. client_1获取到锁后,其他clients进入睡眠,睡眠一段时间继续来获取锁。
  3. client_1发起第二个线程来监控第一个去数据库获取数据的线程执行状态,若在key的过期时间内没有获取到则延长加锁时间。
  4. 当client_1第一个线程成功取得数据后,会将数据写到redis缓存中,同时释放锁让其他客户端直接访问redis黎的缓存数据。
  5. 如果client_1获得锁后突然宕机,锁就不能被释放了,client_2也就没办法获取到锁,就造成了死锁现象。这时,就等锁过期后,client_2就会来获取锁并重复前面动作。
  • 死锁怎么处理?
    • 设置锁的自动超时时间,等Key过了超时时间就会自动删除。即使服务宕机没有调用del释放锁,那么锁本身也有超时时间,可以自动删除锁,其余客户端就可以获取锁了。
  • 锁过期未拿到数据怎么处理?
    • 延长锁的过期时间。另起一个线程监控获取锁的线程的查询状态,快到锁过期时间时还没查询结束则延长锁的过期时间,避免多次查询多次锁过期造成计算资源的浪费.

三、缓存雪崩(没有一片雪花是无辜的!)

3.1 基础概念

概念: 在某个时刻 Redis 集群中的热点 key 同时失效,或者Redis宕机,从而会导致大量请求直接到数据库,压垮数据库。可以说,缓存雪崩是缓存击穿的升级版。
执行流程:

  1. 客户端请求大量热key,key1、key2、key3、key4…
  2. 大量热key在redis缓存里同时失效,客户端直接访问数据库。
  3. 数据库将这些key返回给各个客户端。
  4. 数据库再将这些数据重新缓存到redis里。

在这里插入图片描述

3.2 解决方案

3.2.1 设置有效期均匀分布(一视同仁)

  • 设置有效期时增加随机值,分散key的过期时间,防止大量key在同一时间过期。
  • 统一规划有效期,使得过期时间均匀分布。
  • 设置热key永不过期。

3.2.2 缓存限流(层层关卡)

也可以同缓存击穿一样,增加互斥锁,控制数据库请求数量,重新建立缓存。

3.2.3 搭建集群(安全加固)

采用redis主从复制哨兵模式集群来实现高可用。

3.2.4 数据预热(未卜先知)

对于即将来临的大量请求,我们可以提前走一遍系统,将数据提前缓存在Redis中,并设置不同的过期时间。
流程步骤:

  1. 提前把可能出现的部分热点key放到redis中。不可把所有数据都写进redis,数据量太大,耗时不说,还存不下。
  2. 需要根据当天的具体访问情况,实时统计出访问频率较高的热数据。
  3. 将访问频率较高的热数据写入redis中,多个服务并行读取数据去写,并行的分布式的缓存预热。
  4. 将灌入了热数据的redis对外提供服务,这样就不至于冷启动导致数据库宕机。

3.2.5 缓存降级(弃驹保帅)

概念: 缓存降级是指当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,即使是有损部分其他服务,仍然需要保证主服务可用。可以先停止其他次要服务的运行,从而提升主服务的稳定性。

作用: 目的是保证核心服务可用,即使是有损的。
使用情景: 比如双十一的时候淘宝购物车无法修改地址只能使用默认地址,这个服务就是被降级了,阿里保证了订单可以正常提交和付款,但修改地址的服务可以在服务器压力降低,并发量相对减少的时候再恢复。
注意点: 降级可以根据实时的监控数据进行自动降级也可以配置开关人工降级。是否需要降级,哪些服务需要降级,在什么情况下再降级,取决于大家对于系统功能的取舍。

3.2.6 高压熔断(实时监控)

  • 这种模式的产生灵感来自于电路熔断,如果一条线路电压过高,保险丝会熔断,防止火灾。
  • 那在系统中,如果某个目标服务调用慢或者有大量超时,此时熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。等目标服务情况好转则恢复调用。
  • 监控资源指标:
    • cpu负载、内存、
    • mysql监控长事务(这里与sql查询超时是紧密结合的,需要重点监控)
    • sql超时
    • 线程数等

3.2.7 及时隔离(画地为牢)

这种模式就像对系统请求按类型划分成一个个小岛的一样,当某个小岛被火少光了,不会影响到其他的小岛。

  • 可以对不同类型的请求使用线程池来资源隔离,每种类型的请求互不影响,如果一种类型的请求线程资源耗尽,则对后续的该类型请求直接返回,不再调用后续资源。
  • 例如将这种服务拆开单独部署。

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

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

相关文章

华为机试 - 最大化控制资源成本

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 公司创新实验室正在研究如何最小化资源成本,最大化资源利用率,请你设计算法帮他们解决一个任务混部问题: 有taskNum项任务,每个任务有开始时间&#xf…

数字图像处理实验(一)|图像的基本操作和基本统计指标计算

文章目录一、实验目的二、实验主要仪器设备三、实验原理(1)将一幅图像视为一个二维矩阵。(2)利用MATLAB图像处理工具箱读、写和显示图像文件。(3)计算图像的有关统计参数。(4)改变图像尺寸、旋转图像、裁剪图像四、实验内容(1)用imwrite写入图像(2) 用imread读入一幅图像(自选)…

opencv c++ 图像形态学操作

1、图像的形态学操作 包括图像的腐蚀、膨胀、开、闭、形态学梯度、顶帽、黑帽、分支主题、结构元素等操作。 具体概念参考:(41条消息) 图像处理-形态学处理_Gooddz的博客-CSDN博客_图像处理 形态学 1.1、膨胀 用33的核去扫描二值图像,当核与图像中的前景…

[附源码]JAVA毕业设计仟侬堂茶具网站(系统+LW)

[附源码]JAVA毕业设计仟侬堂茶具网站(系统LW) 项目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术&a…

LeetCode中等题之查找和替换模式

题目 你有一个单词列表 words 和一个模式 pattern,你想知道 words 中的哪些单词与模式匹配。 如果存在字母的排列 p ,使得将模式中的每个字母 x 替换为 p(x) 之后,我们就得到了所需的单词,那么单词与模式是匹配的。 &#xff0…

Git(第二篇)——Git的常见操作

Git(第二篇)——Git的常见操作 目录Git(第二篇)——Git的常见操作一、Git版本控制介绍组成结构图命令速查常用命令二、下载并安装GIT设置字体查询git三、码云上的操作码云配置环境注册账号登录码云创建仓库创建远程仓库(在码云官网…

通讯录管理系统

目录 1.系统需求 2.创建项目 3.菜单功能 4.退出功能 5.添加联系人 5.1设计联系人结构体、设计通讯录结构体 5.2main函数中创建通讯录 5.3封装添加联系人函数 5.4测试添加联系人 6.显示联系人 7.删除联系人 7.1封装检测联系人是否存在 7.2删除联系人,测试删除联…

当我们的执行 java -jar xxx.jar 的时候底层到底做了什么?

大家都知道我们常用的 SpringBoot 项目最终在线上运行的时候都是通过启动 java -jar xxx.jar 命令来运行的。 那你有没有想过一个问题,那就是当我们执行 java -jar 命令后,到底底层做了什么就启动了我们的 SpringBoot 应用呢? 或者说一个 S…

Redux使用详解(一) Redux的核心思想与基本使用

Redux 理解javascript纯函数 函数式编程中有一个非常重要的概念叫纯函数,JavaScript符合函数式编程的范式,所以也有纯函数的概念; 在react开发中纯函数是被多次提及的; 比如react中组件就被要求像是一个纯函数(为什么…

使用STM32F103C8T自制freejoy控制板

1. 软件准备 1.1 STM公司的官方工具: STM32 ST-LINK Utility 已经更名为 STM32CubeProgrammer STSW-LINK004 - STM32 ST-LINK utility (replaced by STM32CubeProgrammer) - STMicroelectronics 1.2 FreeJoyConfiguratorQt V1.7.1 这个是刷好固件后的配置、调…

D-025 DP硬件电路设计

DP硬件电路设计1 简介1.1 DP接口分类1.2 DP接口和HDMI接口的区别1.3 DP接口的优势2 硬件层3 接口定义4 原理图设计1 简介 Display是一种新型的标准化的数字式视频接口标准,其支持的功能与HDMI相似,但是其目标是作为HDMI的补充,而非取代。DP …

红队渗透靶场之SickOs1.1

靶场考察知识 shellshock漏洞 shellshock即unix系统下的bash shell的一个漏洞, Bash 4.3以及之前的版本在处理某些构造的环境变量时存在安全漏洞, 向环境变量值内的函数定义后添加多余的字符串会触发此漏洞, 攻击者可利用此漏洞改变或绕过环境限制,以执行任意的sh…

Notepad++ ,json 、xml 格式化插件安装不了 和 github 网站访问不了 最佳解决方案

文章目录1.背景:2. 解决方法:方法一:修改hosts方法二: 通过 Watt Toolkit 加速1.简介:2.安装步骤:1.背景: 最近notpad 安装 JSON 和 xml 格式化工具安装不上,发现插件的地址 github…

docker之数据卷(Data Volumes)dockerfile

这里写目录标题宿主机与容器之间的文件拷贝数据卷数据卷容器Dockerfile自定义centos,具备vim及ifconfig作用(体会学习Dockerfile的意义)自定义tomcat8(熟悉几乎所有的Dockerfile命令)宿主机与容器之间的文件拷贝 引言…

故障分析 | Greenplum 集群 standby 故障处理

作者:杨文 DBA,负责客户项目的需求与维护,没有擅长,会点数据库,不限于MySQL、Redis、Cassandra、GreenPlum、ClickHouse、Elastic、TDSQL等等。 本文来源:原创投稿 *爱可生开源社区出品,原创内容…

SM4分组密码算法

对称加密算法SM4SM4算法介绍一、SM4加密流程二、轮函数F1.合成置换T3.非线性变换τ2.线性变换L4.加密的结果总结SM4算法介绍 SM4.0于2013年3月被列为国家密码行业标准“GM/T 0002-2012《SM4分组密码算法》(原SMS4分组密码算法)”。2016年被列入国家标准…

blender assetBrowser 资产浏览器

文章目录简介.基础操作打开资产浏览器.标记资产.资产库位置设置与加载其他工程的资产库.为资产设置分类.设置资产的属性.根据类型筛选资产.标记材质为资产.标记天空盒材质为资产.标记动作为资产.简介. 1 类似于unity的预制体,可以直接从资产浏览器里拖出来 2 创建时…

什么是缓存架构,什么是后端分布式多级缓存架构,全文解析带你了解其中门道

文章目录浏览器缓存客户端缓存CDN缓存反向代理缓存本地缓存分布式缓存其他:缓存命中率缓存问题:缓存穿透缓存问题:缓存击穿缓存问题:缓存雪崩缓存问题:缓存一致性缓存的其他问题开篇01数据库缓存1.1.MySQL查询缓存1.2.…

CAS登录认证

CAS最基本的协议过程: 名词解释 Ticket Grangting Ticket(TGT) : TGT是CAS为用户签发的登录票据,拥有了TGT,用户就可以证明自己在CAS成功登录过。TGT封装了Cookie值以及此Cookie值对应的用户信息。用户在CAS认证成功后&#xff0c…

应用于供暖、供水管道等场景的一种智能控制阀

智能控制阀,顾名思义就是能够实现智能化控制功能的一种控制阀。它有什么用处呢? TSM-04V无线智能控制阀由锂亚电池供电、超长续航,具有无线远程配置功能,是一种高可靠性阀控设备。自带断码显示屏,可以查看设备的电量、…