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

简介: 【软件测试】盘一盘工作中遇到的 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优先移除。


以上可以作个了解。


四、查询Redis异常时处理


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


五、redis 穿透、击穿、雪崩


穿透


用户想要查询一个数据,发现redis内存数据库中没有,也就是说没有命中缓存,也是会向持久层数据库查询,发现也没有,那么本次查询失败。


如果此时,用户很多,高并发场景下都去查这个数据,由于缓存都没有命中,于是压力直接打到持久层数据库那里,这就是缓存穿透。


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


击穿


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


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


雪崩


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


解决方案:


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


关于这3个,之前有过一篇整理:https://www.cnblogs.com/pingguo-softwaretesting/p/14911080.html


六、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,以及业务的兜底等。


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


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


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


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


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


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

相关文章
|
人工智能 搜索推荐 数据管理
探索软件测试中的自动化测试框架选择与优化策略
本文深入探讨了在现代软件开发流程中,如何根据项目特性、团队技能和长期维护需求,精准选择合适的自动化测试框架。
540 11
|
测试技术 持续交付
探索软件测试中的自动化测试策略
随着软件开发周期的加速和市场需求的不断增长,传统的手动软件测试方法已难以满足现代软件开发的高效性和准确性要求。本文旨在探讨自动化测试在软件测试中的重要性、实施策略及其对提高软件质量的影响。通过分析自动化测试的优势与挑战,以及提供实用的自动化测试工具和框架选择指南,旨在帮助读者理解并应用自动化测试以提升软件开发效率和产品质量。
|
机器学习/深度学习 人工智能 监控
软件测试中的自动化测试策略与最佳实践##
在当今快速发展的软件行业中,自动化测试已成为确保软件质量和加速产品上市的关键工具。本文将探讨自动化测试的重要性,分析不同类型的自动化测试工具和框架,并深入讨论实施自动化测试的最佳实践。通过案例研究和数据分析,我们将揭示如何有效整合自动化测试到软件开发生命周期中,以及它如何帮助团队提高测试效率和覆盖率。 ##
291 1
|
Java 测试技术 API
探索软件测试中的自动化测试框架
本文深入探讨了自动化测试在软件开发中的重要性,并详细介绍了几种流行的自动化测试框架。通过比较它们的优缺点和适用场景,旨在为读者提供选择合适自动化测试工具的参考依据。
|
数据管理 测试技术 持续交付
软件测试中的自动化测试策略与最佳实践
在当今快速迭代的软件开发环境中,自动化测试已成为确保软件质量和加速产品上市的关键手段。本文旨在探讨软件测试中的自动化测试策略,包括选择合适的自动化测试工具、构建有效的自动化测试框架以及实施持续集成和持续部署(CI/CD)。通过分析自动化测试的最佳实践,本文为软件开发团队提供了一系列实用的指南,以优化测试流程、提高测试效率并减少人为错误。
529 4
|
监控 测试技术 定位技术
探索软件测试中的自动化测试框架选择与实施###
本文不概述传统意义上的摘要内容,而是直接以一段对话形式引入,旨在激发读者兴趣。想象一下,你是一名勇敢的探险家,面前摆满了各式各样的自动化测试工具地图,每张地图都指向未知的宝藏——高效、精准的软件测试领域。我们将一起踏上这段旅程,探讨如何根据项目特性选择合适的自动化测试框架,并分享实施过程中的关键步骤与避坑指南。 ###
262 4
|
测试技术 持续交付 数据安全/隐私保护
软件测试的艺术与科学:探索自动化测试框架
在软件开发的世界中,测试是确保产品质量的关键环节。本文将深入探讨自动化测试框架的重要性和实现方法,旨在为读者揭示如何通过自动化测试提升软件测试效率和准确性。我们将从测试的基本概念出发,逐步引导读者了解自动化测试框架的设计和实施过程,以及如何选择合适的工具来支持测试活动。文章不仅提供理论知识,还将分享实用的代码示例,帮助读者将理论应用于实践。无论你是测试新手还是经验丰富的开发者,这篇文章都将为你打开一扇通往更高效、更可靠软件测试的大门。
228 1
|
数据可视化 前端开发 测试技术
接口测试新选择:Postman替代方案全解析
在软件开发中,接口测试工具至关重要。Postman长期占据主导地位,但随着国产工具的崛起,越来越多开发者转向更适合中国市场的替代方案——Apifox。它不仅支持中英文切换、完全免费不限人数,还具备强大的可视化操作、自动生成文档和API调试功能,极大简化了开发流程。
|
10月前
|
Java 测试技术 容器
Jmeter工具使用:HTTP接口性能测试实战
希望这篇文章能够帮助你初步理解如何使用JMeter进行HTTP接口性能测试,有兴趣的话,你可以研究更多关于JMeter的内容。记住,只有理解并掌握了这些工具,你才能充分利用它们发挥其应有的价值。+
1451 23
|
SQL 安全 测试技术
2025接口测试全攻略:高并发、安全防护与六大工具实战指南
本文探讨高并发稳定性验证、安全防护实战及六大工具(Postman、RunnerGo、Apipost、JMeter、SoapUI、Fiddler)选型指南,助力构建未来接口测试体系。接口测试旨在验证数据传输、参数合法性、错误处理能力及性能安全性,其重要性体现在早期发现问题、保障系统稳定和支撑持续集成。常用方法包括功能、性能、安全性及兼容性测试,典型场景涵盖前后端分离开发、第三方服务集成与数据一致性检查。选择合适的工具需综合考虑需求与团队协作等因素。
1914 24