Redis慢查询分析优化

embedded/2024/10/30 22:33:46/

文章目录

  • 一、定义
  • 二、慢查询参数配置
  • 三、慢查询日志
  • 四、排查步骤
  • 五、Redis变慢原因


一、定义

在Redis执行时耗时超过某个阈值的命令,称为慢查询。

慢查询日志帮助开发和运维人员定位系统存在的慢操作。慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阀值,就将这条命令的相关信息(慢查询ID,发生时间戳,耗时,命令的详细信息)记录下来。


二、慢查询参数配置

1、通过配置指定慢查询的阈值

slowlog-log-slower-than:慢查询阈值,单位是微秒。默认是10000,建议1000

2、慢查询会被放入慢查询日志中,日志的长度有上限,可以通过配置指定

slowlog-max-len:慢查询日志(本质是一个队列)的长度。默认是128,建议1000
在这里插入图片描述


三、慢查询日志

查看慢查询日志列表

  • slowlog len:查询慢查询日志长度
  • slowlog get[n]:读取n条慢查询日志
  • slowlog reset:清空慢查询列表
    在这里插入图片描述

四、排查步骤

查看slowlog(慢日志)

Redis 提供了慢日志命令的统计功能,它记录了有哪些命令在执行时耗时比较久。

查看 Redis 慢日志之前,你需要设置慢日志的阈值。例如,设置慢日志的阈值为 5 毫秒,并且保留最近 500 条慢日志记录:

# 命令执行耗时超过 5 毫秒,记录慢日志
CONFIG SET slowlog-log-slower-than 5000
# 只保留最近 500 条慢日志
CONFIG SET slowlog-max-len 500

设置完成之后,所有执行的命令如果操作耗时超过了 5 毫秒,都会被 Redis 记录下来。

此时,你可以执行以下命令,就可以查询到最近记录的慢日志:

127.0.0.1:6379> SLOWLOG get 5
1) 1) (integer) 32693       # 慢日志ID2) (integer) 1593763337  # 执行时间戳3) (integer) 5299        # 执行耗时(微秒)4) 1) "LRANGE"           # 具体执行的命令和参数2) "user_list:2000"3) "0"4) "-1"
2) 1) (integer) 326922) (integer) 15937633373) (integer) 50444) 1) "GET"2) "user_info:1000"

通过查看慢日志,我们就可以知道在什么时间点,执行了哪些命令比较耗时。


五、Redis变慢原因

原因1:使用复杂度过高的命令

排查思路:

查看慢日志,看是否有复杂度过高的命令。

导致变慢的操作:

  • 经常使用 O(N) 以上复杂度的命令,例如 SORT、SUNION、ZUNIONSTORE 聚合类命令

  •  原因:Redis 在操作内存数据时,时间复杂度过高,要花费更多的 CPU 资源
    
  • 使用 O(N) 复杂度的命令,但 N 的值非常大

  •   原因:Redis 一次需要返回给客户端的数据过多,更多时间花费在数据协议的组装和网络传输过程中
    

除此之外,Redis 是单线程处理客户端请求的,如果你经常使用以上命令,那么当 Redis 处理客户端请求时,一旦前面某个命令发生耗时,就会导致后面的请求发生排队,对于客户端来说,响应延迟也会变长。
解决方案

  • 尽量不使用 O(N) 以上复杂度过高的命令,对于数据的聚合操作,放在客户端做
  • 执行 O(N) 命令,保证 N 尽量的小(推荐 N <= 300),每次获取尽量少的数据,让 Redis 可以及时处理返回

原因2:操作bigkey(value很大)

排查思路

若你查询慢日志发现,并不是复杂度过高的命令导致的,而都是 SET / DEL 这种简单命令出现在慢日志中,那么你就要怀疑你的实例否写入了 bigkey。

导致变慢的操作

Redis 在写入数据时,需要为新的数据分配内存,相对应的,当从 Redis 中删除数据时,它会释放对应的内存空间。如果一个 key 写入的 value 非常大,那么 Redis 在分配内存时就会比较耗时。同样的,当删除这个 key 时,释放内存也会比较耗时,这种类型的 key 我们一般称之为 bigkey。此时,需要检查业务代码是否存在写入 bigkey 的情况。你需要评估写入一个 key 的数据大小,尽量避免一个 key 存入过大的数据。

针对 bigkey 导致延迟的解决方案

  1. 业务应用尽量避免写入 bigkey
  2. 将释放key的操作放到后台线程执行
  •  Redis4.0 以上版本:用 UNLINK 命令替代 DEL,此命令可以把释放 key 内存的操作,放到后台线程中去执行,从而降低对 Redis 的影响
    
  •   Redis6.0 以上版本:可以开启 lazy-free 机制(lazyfree-lazy-user-del = yes),在执行 DEL 命令时,释放内存也会放到后台线程中执行
    

在此不建议在实例中存入 bigkey。这是因为 bigkey 在很多场景下,依旧会产生性能问题。例如,bigkey 在分片集群模式下,对于数据的迁移也会有性能影响,以及我后面即将讲到的数据过期、数据淘汰、透明大页,都会受到 bigkey 的影响。

原因3:集中过期

排查思路

如果你发现,平时在操作 Redis 时,并没有延迟很大的情况发生,但在某个时间点突然出现一波延时,其现象表现为:变慢的时间点很有规律,例如某个整点,或者每间隔多久就会发生一波延迟。

如果是出现这种情况,那么你需要排查一下,业务代码中是否存在设置大量 key 集中过期的情况。

导致变慢的原因

如果有大量的 key 在某个固定时间点集中过期,在这个时间点访问 Redis 时,就有可能导致延时变大。

为什么集中过期会导致 Redis 延迟变大?这就需要我们了解 Redis 的过期策略是怎样的。

Redis 的过期数据采用被动过期 + 主动过期两种策略:

  • 被动过期:只有当访问某个 key 时,才判断这个 key 是否已过期,如果已过期,则从实例中删除
  • 主动过期:Redis 内部维护了一个定时任务,默认每隔 100 毫秒(1秒10次)就会从全局的过期哈希表中随机取出 20 个 key,然后删除其中过期的 key,如果过期 key 的比例超过了 25%,则继续重复此过程,直到过期 key 的比例下降到 25% 以下,或者这次任务的执行耗时超过了 25 毫秒,才会退出循环。

注意,这个主动过期 key 的定时任务,是在 Redis 主线程中执行的。也就是说如果在执行主动过期的过程中,出现了需要大量删除过期 key 的情况,那么此时应用程序在访问 Redis 时,必须要等待这个过期任务执行结束,Redis 才可以服务这个客户端请求。此时就会出现,应用访问 Redis 延时变大。

如果此时需要过期删除的是一个 bigkey,那么这个耗时会更久。而且,这个操作延迟的命令并不会记录在慢日志中。因为慢日志中只记录一个命令真正操作内存数据的耗时,而 Redis 主动删除过期 key 的逻辑,是在命令真正执行之前执行的。所以,此时你会看到,慢日志中没有操作耗时的命令,但我们的应用程序却感知到了延迟变大,其实时间都花费在了删除过期 key 上,这种情况我们需要尤为注意。

解决方案

如果你使用的 Redis 是 4.0 以上版本,可以开启 lazy-free 机制
这样当删除过期 key 时,把释放内存的操作放到后台线程中执行,避免阻塞主线程
集中过期 key 增加一个随机过期时间,把集中过期的时间打散,降低 Redis 清理过期 key 的压力

  • 第1种方案
    Redis 4.0 以上版本,开启 lazy-free 机制:
# 释放过期 key 的内存,放到后台线程执行
lazyfree-lazy-expire yes
  • 第2种方案
    在设置 key 的过期时间时,增加一个随机时间,伪代码可以这么写:
# 在过期时间点之后的 5 分钟内随机过期掉
redis.expireat(key, expire_time + random(300))Copy

这样一来,Redis 在处理过期时,不会因为集中删除过多的 key 导致压力过大,从而避免阻塞主线程。

文章如有不足之处,欢迎大家在评论区指出进行讨论,大家一起进步!


http://www.ppmy.cn/embedded/133723.html

相关文章

【GO实战课】第七讲:电子商务网站(7):性能优化和测试

1. 简介 本课程将探讨电子商务网站的性能优化和测试,以及使用GO语言实现。在本课程中,我们将介绍如何设计一个高性能、可扩展和可靠的电子商务网站,并演示如何使用GO语言编写相关代码。 本课程的目标是帮助学生理解电子商务网站的性能优化和测试原则,并提供一个实际的项目…

解决ElasticSearch启动成功却无法在浏览器访问问题

目录 前言&#xff1a; 问题复现 &#xff1a; 解决问题&#xff1a; 1、修改sysctl.conf文件 2、在sysctl.conf文件增加这段东西 3、 然后保存退出&#xff0c;输入以下命令使其生效 结语&#xff1a; 前言&#xff1a; 这篇文章是小白我今天突然启动es&#xff0c;发现e…

【视频混剪Demo】FFmpeg的使用【Windows】

#1024程序员节 | 征文# 目录 一、简介 二、音频素材页 2.1 功能描述 &#x1f449; 搜索 &#x1f449; 添加 &#x1f449; 删除 2.2 效果展示 2.3 代码实现 &#x1f449; 前端 &#x1f449; 后端 三、视频素材页 3.1 功能描述 &#x1f449; 搜索 &#x1…

力扣hot100-->递归/回溯

目录 递归/回溯 1. 17. 电话号码的字母组合 2. 22. 括号生成 3. 39. 组合总和 4. 46. 全排列 5. 78. 子集 递归/回溯 1. 17. 电话号码的字母组合 中等 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到…

macOS 15 Sequoia dmg格式转用于虚拟机的iso格式教程

想要把dmg格式转成iso格式&#xff0c;然后能在虚拟机上用&#xff0c;最起码新版的macOS镜像是不能用UltraISO&#xff0c;dmg2iso这种软件了&#xff0c;你直接转放到VMware里绝对读不出来&#xff0c;办法就是&#xff0c;在Mac系统中转换为cdr&#xff0c;然后再转成iso&am…

Knife4j配置 ▎使用 ▎教程 ▎实例

knife4j简介 支持 API 自动生成同步的在线文档:使用 Swagger 后可以直接通过代码生成文档,不再需要自己手动编写接口文档了,对程序员来说非常方便,可以节约写文档的时间去学习新技术。 提供 Web 页面在线测试 API:光有文档还不够,Swagger 生成的文档还支持在线测试.参数和格式都…

docker部署SQL审核平台Archery

1、概述 Archery 是一个开源的 SQL 审核平台,专为数据库的 SQL 运维和管理而设计,广泛应用于企业的数据库运维工作中。其主要功能是帮助数据库管理员和开发人员实现 SQL 审核、SQL 执行、在线执行、查询、工单管理、权限控制等数据库管理相关的操作。 Archery 的主要功能包括…

pycharm 中提示ModuleNotFoundError: No module named ‘distutils‘

在Pycharm 中的命令行中输入 pip install setuptools&#xff0c;即可解决