【redis】慢查询分析与优化
慢查询指在Redis中执行时间超过预设阈值的命令,其日志记录是排查性能瓶颈的核心工具。Redis采用单线程模型,任何耗时操作都可能阻塞后续请求,导致整体性能下降。
命令的执行流程
根据Redis的核心机制,命令执行流程可分为以下步骤:
- 客户端发送命令
客户端将用户输入的命令(如 SET key value)序列化为Redis协议格式(RESP),通过Socket发送到服务器。
关键耗时点:网络传输时间(RTT)、序列化时间(取决于命令复杂度)。
- 服务端接收与解析
服务器读取Socket数据到客户端的输入缓冲区(querybuf),解析出命令参数(argv和argc),然后放入命令的执行队列。
关键步骤:命令合法性校验(如参数个数、权限检查)和查找命令表(redisCommand 结构)。
- 命令执行
根据命令在命令表中找到对应的实现函数(如setCommand),执行核心逻辑(如数据读写)。
唯一被慢查询记录的耗时阶段:此阶段的执行时间(微秒级)会被记录到慢查询日志。
- 返回结果与清理
将执行结果写入客户端输出缓冲区,通过Socket返回给客户端,并清理缓冲区和连接状态。
关键耗时点:结果反序列化、网络传输时间(不包含在慢查询日志中)。
核心配置参数
参数名 | 默认值 | 说明 |
---|---|---|
slowlog-log-slower-than | 10ms | 执行时间阈值(微秒),设为0 记录所有命令,负数 则关闭记录 |
slowlog-max-len | 128 | 日志最大存储条数,采用 FIFO 机制淘汰旧日志 |
$ cat /etc/redis/redis.conf | grep slowlog
slowlog-log-slower-than 10000
slowlog-max-len 128
生产建议:阈值设为1ms(1000μs),日志长度≥512条以覆盖更多历史记录。
动态修改配置参数
上面的参数可以直接修改/etc/redis/redis.conf
配置文件,然后重启redis服务。
同时redis提供了一种不重启服务动态修改配置参数的方式。
127.0.0.1:6379> config set slowlog-log-slower-than 1000
OK127.0.0.1:6379> config get slowlog-log-slower-than
1) "slowlog-log-slower-than"
2) "1000"127.0.0.1:6379> config set slowlog-max-len 512
OK127.0.0.1:6379> config get slowlog-max-len
1) "slowlog-max-len"
2) "512"
最后需要将配置持久化到配置文件中,否则重启就恢复成默认配置参数了。
127.0.0.1:6379> config rewrite
OK
然后去配置文件中查看,发现修改成功了。
$ cat /etc/redis/redis.conf | grep slow
slowlog-log-slower-than 1000
slowlog-max-len 512
慢查询日志查看与分析
127.0.0.1:6379> slowlog help1) SLOWLOG <subcommand> [<arg> [value] [opt] ...]. Subcommands are:2) GET [<count>]3) Return top <count> entries from the slowlog (default: 10). Entries are4) made of:5) id, timestamp, time in microseconds, arguments array, client IP and port,6) client name7) LEN8) Return the length of the slowlog.9) RESET
10) Reset the slowlog.
11) HELP
12) Prints this help.
慢查询的日志可以通过如下命令:
SLOWLOG GET [n] # 查看最近n条慢日志(不指定n则返回全部)
日志字段说明:
- timestamp:命令执行时间戳
- duration:耗时(微秒)
- command:完整命令及参数
为了看到慢查询日志的效果,我们这里先将slowlog-log-slower-than
文件参数改为0,这样所有的命令都会记录到慢查询中。
# 改为0,记录所有命令
127.0.0.1:6379> config set slowlog-log-slower-than 0
OK# 将日志重置
127.0.0.1:6379> slowlog reset
OK127.0.0.1:6379> set k1 v1
OK127.0.0.1:6379> set k2 v2
OK# 查询慢查询日志
127.0.0.1:6379> slowlog get
1) 1) (integer) 122) (integer) 17414932153) (integer) 74) 1) "set"2) "k2"3) "v2"5) "127.0.0.1:55264"6) ""
2) 1) (integer) 112) (integer) 17414932103) (integer) 64) 1) "set"2) "k1"3) "v1"5) "127.0.0.1:55264"6) ""
3) 1) (integer) 102) (integer) 17414932053) (integer) 34) 1) "slowlog"2) "reset"5) "127.0.0.1:55264"6) ""# 慢查询的数量
127.0.0.1:6379> slowlog len
(integer) 4
慢查询的常见原因
- 高复杂度命令
-
问题:使用时间复杂度为O(N)或更高的命令(如
KEYS *
、SORT
、SUNION
、ZUNIONSTORE
),尤其当数据量较大时,会导致CPU资源消耗过高,执行时间显著增加。 -
示例:
KEYS *
遍历所有键,时间复杂度 O(N),可能阻塞Redis服务。
- BigKey操作
-
问题:对存储大量数据的Key(如百万级列表、哈希表)进行读写或删除操作(如
DEL
、GET
),会因内存分配/释放耗时过长而阻塞主线程,BigKey可以通过命令redis-cli --bigkeys -i 0.01
查找。 -
示例:删除一个存储100万条数据的列表时,直接使用
DEL
可能导致服务暂停。
- 集中过期Key
-
问题:大量Key在同一时间段过期,触发Redis主动删除机制(默认每100ms随机扫描20个Key),若过期比例超过25%,会循环扫描直至完成,导致主线程阻塞。
-
表现:周期性延迟突增,尤其在业务高峰期。
- 持久化与后台进程影响
-
AOF刷盘:若配置
appendfsync always
或everysec
,频繁刷盘可能导致磁盘I/O压力增大,影响主线程性能。 -
Fork操作:执行RDB快照或AOF重写时,fork子进程拷贝内存页表,若实例内存过大(如超过10GB),会导致主线程阻塞(耗时可能达秒级)。
- 外部环境问题
-
网络延迟:客户端与Redis服务器间的网络不稳定,导致请求响应时间变长。
-
资源竞争:CPU被其他进程占用(Redis单线程依赖CPU),或物理内存不足触发Swap交换,降低性能。
慢查询的优化策略
- 命令与数据结构优化
-
避免高复杂度命令:用
SCAN
替代KEYS
,客户端聚合数据替代SORT
,分页处理大数据(如LRANGE
分页读取)。 -
拆分BigKey:将大Key拆分为多个小Key(如分片列表),或使用渐进式删除(通过Lua脚本分批次删除)。
-
批量操作:使用
MGET
、MSET
减少网络往返,或通过管道(Pipeline)合并多个命令。
- 配置调优
-
慢查询日志:调整
slowlog-log-slower-than
(建议 1ms)和slowlog-max-len
(建议 512),定期分析日志定位瓶颈。 -
内存与持久化:
-
开启
lazy-free
机制(lazyfree-lazy-expire yes
),后台异步释放BigKey内存。 -
根据业务需求选择AOF刷盘策略(如
everysec
平衡性能与安全),避免与RDB同时运行。
-
- 资源与环境优化
-
分散Key过期时间:为Key的过期时间添加随机偏移,避免集中过期(例如
expireat key (base_time + random(500))
)。 -
集群与分片:使用Redis Cluster或代理分片(如 Codis)分散负载,降低单节点压力。
-
监控与告警:通过
INFO
命令、SLOWLOG GET
或Prometheus+Grafana监控内存、CPU、命令耗时等指标。
- 运维最佳实践
-
控制实例内存:单实例内存建议不超过10GB,减少fork耗时。
-
预热缓存:在业务高峰前预加载热点数据,避免缓存穿透/击穿。
-
使用连接池:减少频繁建立连接的开销,提升吞吐量。
相关文章:

【redis】慢查询分析与优化
慢查询指在Redis中执行时间超过预设阈值的命令,其日志记录是排查性能瓶颈的核心工具。Redis采用单线程模型,任何耗时操作都可能阻塞后续请求,导致整体性能下降。 命令的执行流程 根据Redis的核心机制,命令执行流程可分为以下步骤…...

P8925 「GMOI R1-T2」Light 题解
P8925 「GMOI R1-T2」Light 让我们好好观察样例解释的这一张图: 左边第 1 1 1 个像到 O O O 点的距离 : L 2 2 L L\times22L L22L 右边第 1 1 1 个像到 O O O 点的距离 : R 2 2 R R\times22R R22R 左边第 2 2 2 个像到 O O O 点…...
Spring Boot + MyBatis + MySQL:快速搭建CRUD应用
一、引言 1. 项目背景与目标 在现代Web开发中,CRUD(创建、读取、更新、删除)操作是几乎所有应用程序的核心功能。本项目旨在通过Spring Boot、MyBatis和MySQL技术栈,快速搭建一个高效、简洁的CRUD应用。我们将从零开始ÿ…...
python中os库的常用举例
os 库是Python中用于与操作系统进行交互的标准库,以下是一些 os 库的常用示例: 获取当前工作目录 python import os current_dir os.getcwd() print(current_dir) os.getcwd() 函数用于获取当前工作目录的路径。 列出目录内容 python import os …...

Unity 通用UI界面逻辑总结
概述 在游戏开发中,常常会遇到一些通用的界面逻辑,它不论在什么类型的游戏中都会出现。为了避免重复造轮子,本文总结并提供了一些常用UI界面的实现逻辑。希望可以帮助大家快速开发通用界面模块,也可以在次基础上进行扩展修改&…...
Python3 与 VSCode:深度对比分析
Python3 与 VSCode:深度对比分析 引言 Python3 和 Visual Studio Code(VSCode)在软件开发领域扮演着举足轻重的角色。Python3 作为一门强大的编程语言,拥有丰富的库和框架,广泛应用于数据科学、人工智能、网络开发等多个领域。而 VSCode 作为一款轻量级且功能强大的代码…...

第五课:Express框架与RESTful API设计:技术实践与探索
在使用Node.js进行企业应用开发,常用的开发框架Express,其中的中间件、路由配置与参数解析、RESTful API核心技术尤为重要,本文将深入探讨它们在应用开发中的具体使用方法,最后通过Postman来对开发的接口进行测试。 一、Express中…...
Linux 内核自定义协议族开发:从 “No buffer space available“ 错误到解决方案
引言 在 Linux 内核网络协议栈开发中,自定义协议族(Address Family, AF)是实现新型通信协议或扩展内核功能的关键步骤。然而,开发者常因对内核地址族管理机制理解不足,遇到如 insmod: No buffer space available 的错误。本文将以实际案例为基础,深入分析错误根源,并提…...

html-列表标签和表单标签
一、列表标签 表格是用来显示数据的,那么列表就是用来布局的 列表最大的特点就是整齐、整洁、有序,它作为布局会更加自由和方便。 根据使用情景不同,列表可以分为三大类:无序列表、有序列表和自定义列表。 1.无序列表(重…...

HTML-网页介绍
一、网页 1.什么是网页: 网站是指在因特网上根据一定的规则,使用 HTML 等制作的用于展示特定内容相关的网页集合。 网页是网站中的一“页”,通常是 HTML 格式的文件,它要通过浏览器来阅读。 网页是构成网站的基本元素…...

动态ip和静态ip适用于哪个场景?有何区别
在数字化浪潮席卷全球的今天,IP地址作为网络世界的“门牌号”,其重要性不言而喻。然而,面对动态IP与静态IP这两种截然不同的IP分配方式,许多用户往往感到困惑:它们究竟有何区别?又分别适用于哪些场景呢&…...
android13打基础: 保存用户免得下次重新登录逻辑
使用SP来做 创建LoginUser.kt // 登录用户需要Email data class LoginUser(val email: String,val password: String, )创建假数据FakeLoginUser.kt object FakeLoginUser {val fake_login_user_items arrayListOf(LoginUser(email "1690544550qq.com",password …...
Linux 4.4 内核源码的目录结构及其主要内容的介绍
以下是 Linux 4.4 内核源码的目录结构及其主要内容的介绍,适用于理解内核模块和驱动开发的基本框架: Linux 4.4 内核源码目录结构 目录作用与内容arch/平台架构相关代码每个子目录对应一种 CPU 架构(如 x86/、arm/、arm64/),包含硬件相关的启动逻辑、中断处理、内存管理等…...
手脑革命:拆解Manus AI如何用“执行智能体”重构生产力——中国团队突破硅谷未竟的技术深水区
第一章:Manus AI 的技术演进与行业背景 1.1 从工具到智能体:AI 技术的范式跃迁 人工智能的发展经历了从规则驱动(Rule-based)到统计学习(Statistical Learning),再到深度学习(Deep…...

Android 调用c++报错 exception of type std::bad_alloc: std::bad_alloc
一、报错信息 terminating with uncaught exception of type std::bad_alloc: std::bad_alloc 查了那部分报错c++代码 szGridSize因为文件太大,初始化溢出了 pEGM->pData = new float[szGridSize]; 解决办法 直接抛出异常,文件太大就失败吧 最后还增加一个日志输出,给…...

匿名GitHub链接使用教程(Anonymous GitHub)2025
Anonymous GitHub 1. 引言2. 准备3. 进入Anonymous GitHub官网4. 用GitHub登录匿名GitHub并授权5. 进入个人中心,然后点击• Anonymize Repo实例化6. 输入你的GitHub链接7. 填写匿名链接的基础信息8. 提交9. 实例化对应匿名GitHub链接10. 进入个人中心管理项目11. 查…...
【0基础跟AI学软考高项】成本管理
💰「成本管理」是什么? 一句话解释:像家庭装修控制预算,既要买得起好材料,又要避免超支吃泡面——成本管理就是精准算钱、合理花钱、动态盯钱,保证项目不破产! 🌋 真实案例…...
模型的原始输出为什么叫 logits
模型的原始输出为什么叫 logits flyfish 一、Logarithm(对数 log) 定义:对数是指数运算的逆运算,表示某个数在某个底数下的指数。 公式:若 b x a b^x a bxa,则 log b ( a ) x \log_b(a) x logb…...

[SAP MM] 查看物料主数据的物料类型
创建物料主数据时,必须为物料分配物料类型,如原材料或半成品 在标准系统中,物料类型ROH(原材料)的所有物料都要从外部采购,而类型为NLAG(非库存物料)的物料则可从外部采购也可在内部生产 ① 特殊物料类型:NLAG 该物料…...
风控模型算法面试题集结
特征处理 1. 特征工程的一般步骤什么?什么是特征迭代 特征工程一般包含: 数据获取,分析数据的可用性(覆盖率,准确率,获取容易程度)数据探索,分析数据业务含义,对特征有一个大致了解,同时进行数据质量校验,包含缺失值、异常值和一致性等;特征处理,包含数据处理和…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...