专项测试系列-缓存击穿穿透雪崩专项测试

author author     2022-12-07     361

关键词:

作者:刘须华

一、背景概述: R2M 缓存的使用,极大的提升了应用程序的性能和效率,特别是数据查询方面。而缓存最常见的问题是缓存穿透、击穿和雪崩,在高并发下这三种情况都会有大量请求落到数据库,导致数据库资源占满,引起数据库故障。平时对缓存测试时除了关注增删修改查询等基本功能,应该要重点关注缓存穿透、击穿和雪崩三种异常场景的测试覆盖,避免出现线上事故。

二、基本概念说明

1、缓存击穿:是指在超级热点数据突然过期,导致针对超级热点的数据请求在过期期间直接打到数据库,这样数据库服务器会因为某一超热数据导致压力过大而崩掉。

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据库



2、缓存穿透:是指查找的数据在缓存和数据库中都不存在,导致每一次请求数据从缓存中都获取不到,而将请求打到数据库服务器,但数据库中也没有对应的数据,最后每一次请求都到数据库;如果在高并发场景或有人恶意攻击,就会导致后台数据库服务器压力增大,最终系统可能崩掉。

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据_02



3、缓存雪崩:是指突然缓存层不可用,导致大量请求直接打到数据库,最终由于数据库压力过大可能导致系统崩掉。缓存层不可用指以下两方面:缓存服务器宕机,系统将请求打到数据库; 缓存数据突然大范围集中过期失效,导致大量请求打到数据库重新加载数据,与缓存击穿的区别在于这里针对很多 key 缓存,前者则是某一个 key。

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据库_03



三、测试工具 (非必须)

1、使用 Titan 压测平台进行并发请求测试

2、使用 jmeter 工具模拟并发请求

四、测试方法举例说明 (非必须)

环境:测试环境

工具:jmeter

(1)缓存穿透场景

测试方法:查询一个根本不存在的数据,缓存层和存储层都不会命中。

查询接口相关代码实现:

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据_04



通过 JMETER 模拟多次重复调用:单线程重复调用

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据库_05



查看日志结果:从日志可以看出:执行并发请求后, 所有请求每次都走向了数据库。

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_缓存_06



预防方案:

当数据库查询为空时,将缓存赋值默认值,后续查询都走缓存,减少数据库压力。

上述接口,增加赋值为 empty,则第一次查询到数据库为空,后续查询都查询到缓存中,缓存值为 empty。

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据_07



再次执行并发测试:从日志可以看出,可以看出每个 ID 都只执行了一次数据库查询并设置缓存,之后请求都命中了缓存,有效防止了缓存穿透问题。

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据库_08



(2)缓存击穿场景

测试方法:对某个 Key 有大量的并发请求,这时从缓存中删除这个 key。模拟热 key 过期失效的场景。这个时候大并发的请求可能会瞬间把后端 DB 压垮。

接口相关部分代码实现:

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_缓存_09



操作步骤:

1、查询 pin 为 liuxuhua 的请求,这时 pin 为 liuxuhua 的数据会加载到缓存

2、再次查询 pin 为 liuxuhua 的请求,命中缓存

3、50 并发请求 pin 为 liuxuhua 的数据,这个时候请求全部命中缓存

4、将 pin 为 liuxuhua 的缓存手动删除,模拟缓存失效

5、50 并发请求 pin 为 liuxuhua 的数据,这个时候大量请求走向数据库,pin 为 liuxuhua 的缓存被击穿

 

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据_10



查看日志结果:

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_缓存_11



预防方案:

在设置默认缓存值的基础上,进行加锁处理。只有拿到锁的第一个线程去请求数据库,然后插入缓存,当然每次拿到锁的时候都要去查询一下缓存有没有。

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据_12



从日志记录可以看到只有一个请求执行了数据库查询并设置缓存,其他请求都命中了缓存, 有效防止了缓存的击穿。

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据库_13



(3)缓存雪崩

测试方法:对多个使用到缓存的接口进行并发调用,设置这些缓存时间已过期(即删除缓存),调用时这些接口查询缓存时无数据,去查询数据库,这些请求都指向数据库,数据库压力增大,耗时增加。

模拟接口:

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_缓存_14



【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据_15



通过 JMETER 模拟多次重复调用:单线程多接口重复调用

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_缓存_16



查看日志结果:可以看出大量请求到达数据库,并且同一个 pin 或 id 执行了多次数据库查询

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据库_17



预防方案:

增加限流操作,即接口频繁调用时,增加一个缓存,设置时间为 3s,3s 内处理一定次数的请求,超过限制次数的请求直接返回结果,不做处理。

接口:3s 内处理 6 次请求,超过则不处理;

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据_18



从日志可以看出:可以看到每个都只查询了一次数据库并设置缓存,之后的请求都命中了缓存

【专项测试系列】-缓存击穿、穿透、雪崩专项测试_数据库_19



五、测试指标:(或者叫通过标准,包括关注点以及意义)

1、模拟缓存穿透场景测试,每个不存在的数据都只执行了一次数据库查询并设置缓存,之后请求都命中了缓存,有效防止了缓存穿透问题。

2、模拟缓存雪崩场景测试,每个缓存失效的数据都只执行了一次数据库查询并设置缓存,之后请求都命中了缓存。

3、模拟缓存击穿场景测试,缓存失效的那个数据只有一个请求执行了数据库查询并设置缓存,其他请求都命中了缓存。

六、适用业务场景:

1、秒杀活动

2、热门营销活动

3、618 和双 11 大促

七、研发侧常见解决方案(参考):

1、缓存穿透解决方案:

1、缓存空值 之所以发生穿透,是因为缓存中没有存储这些数据的 key,从而每次都查询数据库 我们可以为这些 key 在缓存中设置对应的值为 null,后面查询这个 key 的时候就不用查询数据库了 当然为了健壮性,我们要对这些 key 设置过期时间,以防止真的有数据

2、BloomFilter BloomFilter 类似于一个 hbase set 用来判断某个元素(key)是否存在于某个集合中 我们把有数据的 key 都放到 BloomFilter 中,每次查询的时候都先去 BloomFilter 判断,如果没有就直接返回 null 注意 BloomFilter 没有删除操作,对于删除的 key,查询就会经过 BloomFilter 然后查询缓存再查询数据库,所以 BloomFilter 可以结合缓存空值用,对于删除的 key,可以在缓存中缓存 null 缓存击穿

2、缓存击穿解决方案:

采用分布式锁,只有拿到锁的第一个线程去请求数据库,然后插入缓存,当然每次拿到锁的时候都要去查询一下缓存有没有

3、缓存雪崩解决方案:

1、采用集群,降低服务宕机的概率

2、ehcache 本地缓存 + 限流 & 降级

3、均匀过期,通常可以为有效期增加随机值

redis系列缓存击穿穿透雪崩解决方案详解

文章目录前言一、击穿1.介绍2.产生原因3.解决方案二、穿透1.介绍2.产生原因3.解决方案三、雪崩1.介绍2.产生原因3.解决方案结尾前言众所周知,计算机的瓶颈之一就是IO,为了解决内存与磁盘速度不匹配的问题,产生... 查看详情

redis缓存雪崩缓存穿透缓存击穿

Redis缓存雪崩、缓存穿透、缓存击穿Redis缓存过程缓存雪崩解决方案永不过期合理的设置过期时间使用Redis的分布式锁缓存穿透解决方案过滤非法查询缓存空对象布隆过滤器布隆过滤器的新增布隆过滤器的查询布隆过滤器的删除布... 查看详情

缓存雪崩击穿穿透

缓存雪崩、击穿、穿透前言一、缓存雪崩大量数据同时过期Redis故障宕机二、缓存击穿三、缓存穿透布隆过滤器总结前言用户的数据一般都是存储于数据库,数据库的数据是落在磁盘上的,磁盘的读写速度可以说是计算机... 查看详情

缓存雪崩击穿穿透

缓存雪崩、击穿、穿透前言一、缓存雪崩大量数据同时过期Redis故障宕机二、缓存击穿三、缓存穿透布隆过滤器总结前言用户的数据一般都是存储于数据库,数据库的数据是落在磁盘上的,磁盘的读写速度可以说是计算机... 查看详情

redis12_缓存雪崩缓存穿透基于布隆过滤器解决缓存穿透的问题缓存击穿基于缓存击穿工作实际案例(代码片段)

文章目录①.缓存雪崩②.缓存穿透③.在centos7下布隆过滤器2种安装方式④.缓存击穿⑤.高并发的淘宝聚划算案例落地①.缓存雪崩①.问题的产生:缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至... 查看详情

redis12_缓存雪崩缓存穿透基于布隆过滤器解决缓存穿透的问题缓存击穿基于缓存击穿工作实际案例(代码片段)

文章目录①.缓存雪崩②.缓存穿透③.在centos7下布隆过滤器2种安装方式④.缓存击穿⑤.高并发的淘宝聚划算案例落地①.缓存雪崩①.问题的产生:缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至... 查看详情

redis08_缓存雪崩缓存穿透基于布隆过滤器解决缓存穿透的问题缓存击穿基于缓存击穿工作实际案例(代码片段)

文章目录①.缓存雪崩②.缓存穿透③.在centos7下布隆过滤器2种安装方式④.缓存击穿⑤.高并发的淘宝聚划算案例落地①.缓存雪崩①.问题的产生:缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至... 查看详情

缓存雪崩击穿穿透

   缓存雪崩:   为了保证缓存中的数据与数据库中的数据一致性,会给Redis里的数据设置过期时间,当缓存数据过期后,用户访问的数据如果不在缓存里,业务系统需要重新生成缓存,因此就会访问数据库... 查看详情

go分布式缓存防止缓存击穿(day6)(代码片段)

...透的概念简介。使用singleflight防止缓存击穿,实现与测试。代码约70行1缓存雪崩、缓存击穿与缓存穿透GeeCache第五天提到了缓存雪崩和缓存击穿,在这里做下总结:缓存雪崩:缓存在同一时刻全部失效,造成瞬... 查看详情

go分布式缓存防止缓存击穿(day6)(代码片段)

...透的概念简介。使用singleflight防止缓存击穿,实现与测试。代码约70行1缓存雪崩、缓存击穿与缓存穿透GeeCache第五天提到了缓存雪崩和缓存击穿,在这里做下总结:缓存雪崩:缓存在同一时刻全部失效,造成瞬... 查看详情

redis——缓存穿透缓存击穿缓存雪崩分布式锁(代码片段)

文章目录:1.缓存穿透1.1什么是缓存穿透?1.2缓存穿透的解决方案2.缓存击穿2.1什么是缓存击穿?2.2缓存击穿的解决方啊3.缓存雪崩3.1什么是缓存雪崩?3.2缓存雪崩的解决方案4.分布式锁4.1使用setnx+del实现分布式... 查看详情

redis——缓存穿透缓存击穿缓存雪崩分布式锁(代码片段)

文章目录:1.缓存穿透1.1什么是缓存穿透?1.2缓存穿透的解决方案2.缓存击穿2.1什么是缓存击穿?2.2缓存击穿的解决方啊3.缓存雪崩3.1什么是缓存雪崩?3.2缓存雪崩的解决方案4.分布式锁4.1使用setnx+del实现分布式... 查看详情

redis系列缓存击穿穿透雪崩解决方案详解

文章目录前言一、击穿1.介绍2.产生原因3.解决方案二、穿透1.介绍2.产生原因3.解决方案三、雪崩1.介绍2.产生原因3.解决方案结尾前言众所周知,计算机的瓶颈之一就是IO,为了解决内存与磁盘速度不匹配的问题,产生... 查看详情

redis的缓存穿透缓存雪崩缓存击穿问题的概念与解决办法(代码片段)

详细介绍了Redis的缓存穿透、缓存雪崩、缓存击穿等问题的概念与解决办法。文章目录1缓存穿透1.1什么是缓存穿透?1.2怎么解决1.3BloomFilter布隆过滤器1.3.1BloomFilter的原理1.3.2BloomFilter的优缺点1.3.3GuavaBloomFilter1.3.4RedisBloomFilter2... 查看详情

redis的缓存问题之缓存穿透缓存雪崩缓存击穿(代码片段)

目录一、什么是缓存穿透?二、常见的解决方案有两种:1、缓存空对象2、布隆过滤综上所述三、编码解决商品查询的缓存穿透问题四、缓存雪崩问题及解决思路1、什么是缓存雪崩?五、缓存击穿问题及解决思路 1、... 查看详情

缓存的雪崩,击穿,穿透

缓存的雪崩,击穿,穿透前言在将今天的内容之前,我们先来了解一下什么是缓存,缓存是用来干什么的,常用的缓存有哪些?什么是缓存我们要知道缓存其实就是一个临时的存储器,那么缓存里的数... 查看详情

redis缓存雪崩缓存击穿缓存穿透原因,解决方案?(代码片段)

缓存雪崩、缓存击穿、缓存穿透原因,解决方案?缓存雪崩由于设置缓存时,key都采用了相同expire,导致缓存在某刻同时失效,请求全部直到DB,DB瞬时负载过重而雪崩解决方案在原有失效时间基础上增加一个随机值,比如1~5分钟... 查看详情

缓存穿透缓存击穿缓存雪崩解决方案分析

前言设计一个缓存系统,不得不要考虑的问题就是:缓存穿透、缓存击穿与失效时的雪崩效应。一、缓存穿透缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如... 查看详情