缓存设计导致的问题测试要点总结

一、什么是缓存

缓存实质就是一个临时的存储数据的容器。数据在这个容器中可以提高读取速度。

二、缓存的分类

缓存分为硬件缓存和软件缓存

硬件缓存是位于CPU和内存之间的临时存储器

软件缓存又分为内存缓存、数据库缓存、网络缓存

内存缓存
内存缓存的范围比较宽泛,这里只讨论RAM缓存即预先将数据写到容器(list,map,set)等数据存储单元中并将数据存储在RAM缓存中。一般应用设计中最常用的就是Redis。
数据库缓存
数据缓存是数据库本身的缓存,并不是外部缓存例如Redis/Memcache等等。
数据库的数据分为冷数据和热数据库,通俗的讲冷数据是存储在磁盘上不经常查询的数据;而热数据是频繁查询的数据,这部分数据会被缓存到内存中。
网络缓存
网络缓存是一种降低Internet流量和提高终端用户响应时间的网络技术。如CPU中的缓存,用于提高内存存取的速率;各种操作系统在进行磁盘存取时也会利用缓存来提高速率; 分布式文件系统通常也通过缓存来提高客户机和服务器之间的速率,如浏览器缓存、CDN,DNS缓存等等。

三、使用缓存的目的

使用缓存主要的目的有两个:实现高性能、高并发

举个栗子:
假设有一个查询功能,一个查询请求过来应用就会链接到数据库查询结果,然后数据库返回查询结果。整个查询从开始到获得响应整个过程耗时100ms,而且查询的数据在短时间内是不变或者是更新不频繁的。当某一时刻有10000个相同的查询过来时,处理全部的请求总耗时是100*10000ms。

在这里插入图片描述

使用缓存方案,即将第一次查询的结果以K-V形式存储到内存中,当有相同的查询请求时直接通过K从内存中查询出结果,从内存中查询结果耗时1ms,当在有10000个相同的查询过来时,处理请求的总耗时是100+1*9999ms,则相比没有使用缓存时性能提升大约100倍。

在这里插入图片描述

四、使用缓存潜在的问题

1、问题一、缓存与数据库的一致性

在使用缓存时不可避免会涉及到缓存与数据库数据读写的一致性,如何保持缓存的数据和数据库数据的一致。
串行化读写缓存和数据库可以保证数据强一致性,但是串行读写效率低,耗时长,无法支撑高并发请求场景。
缓存与数据库数据不一致的原因

造成缓存与数据库数据不一致的场景是在更新数据的时候发生的,更新数据的操作有以下几种方式。

在这里插入图片描述

方式一:更新数据时先更新数据库中的数据,更新成功之后再删除缓存中对应的数据

存在问题:当更新数据库数据成功,更新或删除缓存数据失败时,后续的查询操作取到的数据是旧数据

解决方案

先更新数据库,成功后往消息队列发消息,消费到消息后再删除缓存,借助消息队列的重试机制来实现,达到最终一致性的效果。

在这里插入图片描述

方式二:更新数据时先删除缓存中的数据,删除成功之后再更新数据库中对应的数据

存在问题:
在高并发场景下两个请求几乎同时到达
请求一是更新操作,先删除了缓存,正在查询数据库,请求二是查询操作,在请求一查询数据库的时候请求二查询缓存没有找到数据,就去数据库查询此时请求一还没更新完毕,请求二查到了就数据并将旧数据放到了缓存中,后续的查询操作查询到的数据都是旧数据

解决方案:
延迟双删,为了避免更新数据库数据的时候,其他线程从缓存中读取不到数据而从数据库取到旧数据更新缓存,就在更新完数据库之后,再 Sleep 一段时间,然后判断缓存中是否有数据有就再次将缓存中的数据删除。

sleep的时间=其他线程读数据时间+写缓存时间

3、问题二、缓存穿透

在这里插入图片描述
缓存穿透一般是应用在遭受黑客攻击时出现的场景,当黑客故意去请求缓存中不存在的数据,从而去数据库中查,数据库中也没有,所以无法加到缓存,当黑客疯狂发起这类请求时超高并发的查询将导致数据库崩溃。

解决方案:
1)利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试。
2)数据库没查到数据,也往缓存中写入一个空值,但是设置失效时间短一点,防止恶意攻击。

4、问题三、缓存击穿

在这里插入图片描述
缓存击穿是指缓存的热点数据刚好过期时(失效),大量并发查询请求到达,此时读缓存没读到数据,应用就直接在数据库中查询数据,引起数据库压力瞬间增大,造成过大压力 ,可能导致数据库崩溃。

解决方案:

1、当多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它 ,其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存
2、可以将爆款的缓存失效时间设置为永久。

5、问题四、缓存雪崩

在这里插入图片描述
缓存雪崩是出现的场景一般是指正常使用的缓存组件突然发生不可用情况,导致系统处理能力大幅度降低此时有需要处理大量请求时导致数据库压力过大进而导致系统的崩溃。
导致缓存突然不可用的情况有很多比如上述提到缓存热点数据同时失效、缓存节点故障等等

解决方案:
缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题。
设置不同的过期时间,让缓存失效的时间点尽量均匀。
设置热点数据永远不过期。

五、缓存测试点

在一个系统中如果使用了缓存方案就不可避免存在上述问题。
测试前需要清楚知道被测系统采用的缓存实现方案以及更新策略,根据方案及策略的特点编写有针对性测试用例。

缓存问题在测试过程中不容易被发现,因为在测试环境中使用系统的用户都是测试员,对系统产生的压力都非常小,只有在开展压测场景下才有可能出现缓存导致的问题。

测试场景:

1、出现数据不一致时对业务的影响

2、是否考虑到系统在发生缓存击穿场景下处理方案

3、是否考虑到了系统在发生缓存穿透情况下的处理方案

4、当系统发生缓存组件服务异常时或是缓存全部失效时在正常的业务量下系统是否撑得住。


欢迎大家关注我的订阅号,会定期分享一些关于测试相关的文章,有问题也欢迎一起讨论学习!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值