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

news2024/11/26 2:45:47

目录

前言:

一、更新 Key 异常

二、Key的删除和丢失

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

四、查询Redis异常时处理

五、redis 穿透、击穿、雪崩

六、Redis死锁

七、Redis持久化

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


前言:

在软件测试过程中,我们常常会遇到与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 持久化,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。

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

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

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

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

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

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

  作为一位过来人也是希望大家少走一些弯路

在这里我给大家分享一些自动化测试前进之路的必须品,希望能对你带来帮助。

(WEB自动化测试、app自动化测试、接口自动化测试、持续集成、自动化测试开发、大厂面试真题、简历模板等等)

相信能使你更好的进步!

点击下方小卡片

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

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

相关文章

第八章、【Linux】文件与文件系统的压缩,打包与备份

8.1 压缩文件的用途与技术 8.2 Linux 系统常见的压缩指令 列几个常见的压缩文件扩展名: 8.2.1 gzip, zcat/zmore/zless/zgrep gzip 可以说是应用度最广的压缩指令了!目前 gzip 可以解开 compress, zip 与 gzip 等软件所压缩的文件。 当你使用 gzip 进…

Error: 系统错误,错误码:80051,source size 2649KB exceed max limit 2MB [202306

小程序主包体积过大,预览到手机失败 把这个勾选一下,上限调整到4MB

Android性能优化问题方案的总结~

虽然总说“英雄不问出处”,但大厂卡学历是默认的“潜规则”。不过最近一个老弟,让我挺振奋的!人家完全靠实力上岸。他就属于死磕型的,是我近2年见过的少有的Android性能优化高手。 要说他也挺聪明,贼会选领域。你出去随…

力扣 -- 740. 删除并获得点数

题目链接&#xff1a;740. 删除并获得点数 - 力扣&#xff08;LeetCode&#xff09; 下面是用动态规划的思想解决这道题的过程&#xff0c;相信各位小伙伴都能看懂并且掌握这道经典的动规题目滴。 参考代码&#xff1a; class Solution { public:int deleteAndEarn(vector<…

【MySQL】 MySQL安装

文章目录 1. MySQL安装配置内置环境关闭MySQL卸载MySQL确认环境是否干净 配置MySQL yum源yum源 的安装注意事项检测是否安装成功 MySQL的启动MySQL的登录登录方案一 获取临时密码登录方案二 免密码登录 MySQL的配置文件 1. MySQL安装 配置内置环境 输入 ps axj | grep mysql …

SpringBoot教学补充资料3-Maven安装

Maven下载地址&#xff1a;https://maven.apache.org/download.cgi 下载后进行解压&#xff0c;记住解压路径。 mvn -v

大文件下载

背景 google chrome下载大文件的时候&#xff0c;没有断点续传的功能&#xff0c;会因为网络不稳定多次下载失败。 google drive大文件 安装google drive客户端 点开别人的goole drive链接&#xff0c;保存在自己的文件夹下 本人的goole drive获取file_id # 链接格式 h…

mapbox icon-allow-overlap 和 icon-ignore-placement的区别

icon-allow-overlap 和 icon-ignore-placement的区别 官网解释&#xff1a;If true, the icon will be visible even if it collides with other previously drawn symbols. 翻译&#xff1a;如果该属性为true那么他会显示即便会冲突和在它之前已经添加的图层。 官网解释&am…

NSS [鹏城杯 2022]简单包含

NSS [鹏城杯 2022]简单包含 看代码觉得不就直接post flagdata://text/plain,<?php system(ls);?>行了。 但是事实上没有什么软用。 用了php://伪协议之后发现有WAF。 可以读源码 解码得到 <?php$path $_POST["flag"];if (strlen(file_get_contents(ph…

UE5 MetaHuman SDK插件的使用【一、编辑器创建音波与蓝图创建获取音波,语音与嘴唇口型的同步】

目录 打开插件 创建音频 编辑器这直接创建音频&#xff1a; 蓝图中创建和获取音频&#xff1a; 唇语&#xff1a; 声音与嘴唇同步&#xff1a; 方法一【效果不是很好】&#xff1a; 方法二【效果很好&#xff0c;但有一段时间延迟在处理】&#xff1a; 逻辑&#xff1…

Mysql数据库,Navicat上给表创建索引一直等待

问题背景&#xff1a; 对查询语句进行索引优化&#xff0c;针对以下表添加联合索引&#xff0c;语句如下&#xff1a; ALTER TABLE hzz_patrol_period_config add index IDX_PERIOD_CONFIG_YEAR_TYPE_VAL (EFFECT_YEAR,CHECK_CYCLE_TYPE,CHECK_CYCLE_VAL); Navicat上执行一直…

linux_driver_day02

作业1 题目&#xff1a; 映射 GPIOE、GPIOF、RCC 虚拟地址&#xff0c;实现控制三盏LED的驱动 效果&#xff1a; 代码&#xff1a; mycdev.h #ifndef _MYCDEV_H_ #define _MYCDEV_H_#include <linux/fs.h> #include <linux/init.h> #include <linux/io.h&g…

如何使用ChatGPT写好简历?如何使用ChatGPT优化简历?21个写简历的ChatGPT的Prompts!

你是一位求职者&#xff0c;即将要参加一场面试&#xff0c;你的工作经历是[2年国企会计经验]&#xff0c;教育背景是[国内211本科毕业&#xff0c;会计学专业]&#xff0c;请基于上述内容生成一份简历&#xff0c;要求加上自我评价。 根据这份工作描述写一份[TITLE]的简历。[…

Python——— 字典

&#xff08;一&#xff09;初识字典 字典是 “ 键值对 ” 的无序可变序列&#xff0c;字典中的每个元素都是一个 “ 键值对” &#xff0c;包含&#xff1a; “ 键对象 ” 和 “ 值对象 ” 。可以通过 “ 键对象 ” 实现快速获取、 删除、更新对应的“ 值对象 ” 。 一个典…

Scala入门学习

Scala入门学习 文章目录 Scala入门学习0. 写在前面1. 概述1.1 什么是Scala1.2 Java and Scala 2. Scala简单使用2.1 Scala环境安装2.2 Scala插件安装2.3 Scala第一个案例 0. 写在前面 操作系统&#xff1a;Windows10JDK版本&#xff1a;jdk1.8Maven版本&#xff1a;Maven-3.5.…

调整图片大小需要注意哪些问题?在线改图片大小的方法介绍

调整图片大小&#xff1a;打造完美尺寸的视觉体验 为什么需要调整图片大小&#xff1f; 在现代社交媒体和网络传媒中&#xff0c;图片已经成为信息传递和内容表达的重要元素。然而&#xff0c;不同平台和设备对于图片尺寸有着各自的要求。过大或过小的图片尺寸可能导致加载速…

计算机网络_ 1.3 网络核心 (数据交换_电路交换)

计算机网络_数据交换_电路交换 计算机网络_数据交换_电路交换 计算机网络_数据交换_电路交换 最典型电路交换网络&#xff1a;电话网络电路交换的三个阶段 建立连接&#xff08;呼叫/电路建立&#xff09;通信释放连接&#xff08;拆除电路&#xff09; 独占资源 电路交换网络…

OSPFv2基础01_整体介绍

目录 1.OSPF简介 2.OSPF工作原理简介 3.OSPF基础概念 3.1 OSPF系统 3.1.1 OSPF路由器分类 3.1.2 OSPF区域 &#xff08;1&#xff09;OSPF区域分类 &#xff08;2&#xff09;OSPF特殊区域 3.1.3 OSPF路由类型 3.2 OSPF报文 3.2.1 OSPF首部格式 3.2.2 OSPF报文格式 …

【软考】数据库理论

文章目录 一、函数依赖闭包 一、函数依赖闭包 视频连接&#xff1a;https://open.163.com/newview/movie/free?pidEGVFE2HM4&midOGVFE3RKQ 其他的概念&#xff1a; 函数依赖集候选关键字闭包

Ribbon快速入门

1.Ribbon 概述 Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具&#xff0c;它基于 Netflix Ribbon 实现。通过 Spring Cloud 的封装&#xff0c;可以让我们轻松地将面向服务的 REST 模版请求自动转换成客户端负载均衡的服务调用。 轮询 hash 权重 … 简单…