【软件测试】盘一盘工作中遇到的 Redis 异常测试

2023-12-05 07:01

本文主要是介绍【软件测试】盘一盘工作中遇到的 Redis 异常测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在测试工作中,涉及到与 redis 交互的场景变的越来越多了。关于redis本身就不作赘述了,网上随便搜,本人也做过一些整理。

今天只来复盘一下,在测试过程中与 redis 的二三事儿。其中提到的案例是经过抽象化的,用作辅助说明作用,仅供参考。

一、更新 Key 异常

注意点:先删除原 key 再存,还是直接覆盖原 key?

比如:之前 A 服务每8小时去查询一次数据库,更新到缓存里去。后来需求调整,变成当数据库里有变动的时候就会发送MQ消息给服务 A,然后A就去全量拉取库里数据,再更新到缓存。

开发小哥实现的是先删除key再更新,那么可能会导致这个时间如果有大量的请求进来,就不能命中缓存。于是乎建议,当从数据库拉来数据之后,可以先和redis中原来的key值进行对比,删除多余的缓存,其他的覆盖更新。

二、Key的删除和丢失

注意点:考虑key被删除,或者key丢失后对上游的影响

比如:服务A 会同步一类数据到 redis,然后发消息告诉 服务B。B 收到消息后,拿到 redis 数据去找自己那边 MongoDB里的对应 key,做更新操作,若查不到key,就会删除数据。

此时如果 redis 里产生了数据丢失,key就不存在了,那么同步过后,会导致 MongoDB 里的数据被勿删。

于是乎这里建议方案是:redis 那边涉及要删除key的话,就更新key的值为空[],这时候 MongoDB 查询到值为空的key,就去删除对应数据。 另外,如果redis那边key 丢失了,MongoDB这边也别就删数据了,去调用一个实时接口去查询数据然后更新。

三、KEY 过期策略不当造成内存泄漏

首先回顾一下 redis 中 ttl key指令:

  • 当 key 不存在时,返回 -2
  • 当 key 存在但没有设置剩余生存时间时,返回 -1
  • 否则,返回 key 的剩余生存时间,单位是 s

通常,大多数业务用到redis 都会设置过期时间。接下来,了解一下 key 过期是如何清理的。

定期清理

Redis会定期主动淘汰一批已过期的key(随机抽取一批key检查)。

缺点:可能存在很多KEY已过期,仍未清理。

惰性清理

在获取某个 key 的时候,redis 会检查一下这个 key 如果设置了过期时间并且已经过期,就会删除这个 key,不会返回任何东西。

缺点:如果存在很多未去查询的过期key,就没法走到惰性删除,于是可能会有大量过期的key堆积在内存里,导致内存耗尽。

一般来说,业务会惰性和定期清理配合使用

内存淘汰机制

但是,如果定期清理漏掉了很多过期的key,然后你也没及时去查,也就没走惰性删除。此时依旧有可能大量过期的key堆积在内存里,导致内存耗尽。

这时候需要内存淘汰机制,有如下几个:

  • noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。这个一般很少用。
  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key,这个是最常用的。
  • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
  • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。
  • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。

以上可以作个了解。

现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036【暗号:csdn999】

四、查询Redis异常时处理

很多时候,redis 只是做一个缓存机制,如果redis异常或者未取到数据,是否有实时获取数据的兜底方案(查接口 or 查库?),需要考虑。

五、redis 穿透、击穿、雪崩

穿透

用户想要查询一个数据,发现redis内存数据库中没有,也就是说没有命中缓存,也是会向持久层数据库查询,发现也没有,那么本次查询失败。 如果此时,用户很多,高并发场景下都去查这个数据,由于缓存都没有命中,于是压力直接打到持久层数据库那里,这就是缓存穿透。

解决方案可以用布隆过滤器、返回空对象(设置过期时间)。

击穿

缓存击穿,是指一个key非常热点,在不停的扛着高并发,如果这个key失效了,在失效的瞬间,持续的并发量就会穿破缓存,直接打到持久层数据库,就像一个防御墙被凿开一个洞。

解决方案可以设置热点数据永不过期、加互斥锁等。

雪崩

是指在某一个时间段,缓存集中过期失效,或者redis宕机了。

解决方案:

  • 事前:redis 高可用,主从+哨兵,redis cluster,避免全盘崩溃。
  • 事中:本地 ehcache 缓存 + hystrix 限流&降级,避免 MySQL 被打死。
  • 事后:redis 持久化,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。

六、Redis死锁

Redis锁,小心使用不当造成锁不能释放,陷入死锁。

目前常用的2种锁:

SET Key UniqId Seconds

仅在单实例的场景下是安全的。如果不使用setnx+expire+del中间环节断了仍可能造成死锁; 如果不用SET Key UnixTimestamp Seconds NX,高并发下可能存在相同时间戳。

分布式Redis锁:Redlock

此种方式比原先的单节点的方法更安全。

  • 安全性:在同一时间不允许多个Client同时持有锁。
  • 活性死锁:锁最终应该能够被释放,即使Client端crash或者出现网络分区(通常基于超时机制)。
  • 容错性:只要超过半数Redis节点可用,锁都能被正确获取和释放。

七、Redis持久化

当Redis数据需要长久有效时,需要考虑是否做RDB和AOF持久化,一般RDB和AOF配合使用,但做持久化,会影响性能。

目前接触到的业务做持久化的很少见。比如有个推荐系统Redis数据是长久有效的,但却为了响应快不影响性能,未做持久化,而采用了其他的降级方案Hbase,以及业务的兜底等。

八、缓存与数据库双写时的数据一致性

一般来说,就是如果你的系统不是严格要求缓存+数据库必须一致性的话,允许缓存跟数据库偶尔不一致的情况,那么最后好不要做这个一致性方案。

如果实现这个方案,读请求和写请求串行化,串到一个内存队列里去,这样就可以保证一定不会出现不一致的情况。

但是串行化之后,就会导致系统的吞吐量会大幅度的降低,用比正常情况下多几倍的机器去支撑线上的一个请求。

还有一种适中的方式就是,就是先更新数据库,然后再删除缓存。可能会暂时产生不一致的情况,但是发生的几率特别小。这时候通常并行写数据库和缓存,可以加个事务,都写成功才成功,有一个环节失败了就回滚事务,全失败。

关于双写一致性的问题,其实可以另起一个篇幅来说了,有兴趣的可以网上搜索一下,后续可能会再进行整理。

END,今天的分享就到此结束了,点赞关注不迷路!

这篇关于【软件测试】盘一盘工作中遇到的 Redis 异常测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/456609

相关文章

Knife4j+Axios+Redis前后端分离架构下的 API 管理与会话方案(最新推荐)

《Knife4j+Axios+Redis前后端分离架构下的API管理与会话方案(最新推荐)》本文主要介绍了Swagger与Knife4j的配置要点、前后端对接方法以及分布式Session实现原理,... 目录一、Swagger 与 Knife4j 的深度理解及配置要点Knife4j 配置关键要点1.Spri

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

SpringBoot集成LiteFlow工作流引擎的完整指南

《SpringBoot集成LiteFlow工作流引擎的完整指南》LiteFlow作为一款国产轻量级规则引擎/流程引擎,以其零学习成本、高可扩展性和极致性能成为微服务架构下的理想选择,本文将详细讲解Sp... 目录一、LiteFlow核心优势二、SpringBoot集成实战三、高级特性应用1. 异步并行执行2

Redis的持久化之RDB和AOF机制详解

《Redis的持久化之RDB和AOF机制详解》:本文主要介绍Redis的持久化之RDB和AOF机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述RDB(Redis Database)核心原理触发方式手动触发自动触发AOF(Append-Only File)核

Redis分片集群、数据读写规则问题小结

《Redis分片集群、数据读写规则问题小结》本文介绍了Redis分片集群的原理,通过数据分片和哈希槽机制解决单机内存限制与写瓶颈问题,实现分布式存储和高并发处理,但存在通信开销大、维护复杂及对事务支持... 目录一、分片集群解android决的问题二、分片集群图解 分片集群特征如何解决的上述问题?(与哨兵模

使用Python进行GRPC和Dubbo协议的高级测试

《使用Python进行GRPC和Dubbo协议的高级测试》GRPC(GoogleRemoteProcedureCall)是一种高性能、开源的远程过程调用(RPC)框架,Dubbo是一种高性能的分布式服... 目录01 GRPC测试安装gRPC编写.proto文件实现服务02 Dubbo测试1. 安装Dubb

SpringBoot连接Redis集群教程

《SpringBoot连接Redis集群教程》:本文主要介绍SpringBoot连接Redis集群教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 依赖2. 修改配置文件3. 创建RedisClusterConfig4. 测试总结1. 依赖 <de

SpringBoot+Redis防止接口重复提交问题

《SpringBoot+Redis防止接口重复提交问题》:本文主要介绍SpringBoot+Redis防止接口重复提交问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录前言实现思路代码示例测试总结前言在项目的使用使用过程中,经常会出现某些操作在短时间内频繁提交。例