当前位置:首页 > 文章列表 > 数据库 > Redis > Redis 延迟监控如何区分慢命令与系统抖动

Redis 延迟监控如何区分慢命令与系统抖动

来源:17golang原创 2026-10-09 17:53:17 0浏览 收藏

Redis 出现延迟尖峰时,不能只看一张客户端耗时图就下结论。慢命令会占住 Redis 主线程,但操作系统调度、虚拟机邻居噪声、fork、AOF 写入、过期或淘汰周期也会让命令一起变慢。区分它们的关键,是同时对齐三类证据:SLOWLOG 中的命令执行时间、LATENCY 记录的事件类型,以及宿主机的固有延迟。

本文搭一个最小的只读采集器:它不跑压测,也不制造慢命令,只在出现尖峰时保存 Redis 内部证据。随后再用一次受控的 --intrinsic-latency 测试判断系统调度基线。若慢日志与 command 事件在同一时间窗口出现,优先查命令和大对象;若慢日志为空而 fork、AOF、过期事件或宿主机固有延迟同时升高,就应转向持久化和系统环境。

官方文档:https://redis.io/docs/latest/operate/oss_and_stack/management/optimization/latency-monitor/

项目目标:保存一组能够互相印证的证据

这个小工具解决的不是“算一个平均延迟”,而是保留一次故障现场。最终每次采集会生成四类文本:

  • LATENCY LATEST:各事件最近一次峰值、历史最大值等摘要;
  • LATENCY DOCTOR:Redis 根据已记录事件生成的可读分析;
  • SLOWLOG GET:超过慢日志阈值的命令记录;
  • INFO persistence:RDB、AOF 与后台子进程的状态线索。

这些数据的边界必须先讲清楚。SLOWLOG 只统计命令在 Redis 内部执行的时间,不包含与客户端通信等 I/O 时间;应用监控测到的则是端到端耗时,通常还包含连接池等待、网络往返、序列化和业务代码。两者不一致并不矛盾,反而是定位方向的重要证据。

应用请求、Redis 主线程、SLOWLOG、LATENCY 事件和宿主机固有延迟之间的静态测量边界说明图

图1:应用、Redis 实例和宿主机三层延迟证据的静态关系说明图,不是运行截图。

环境准备:让 LATENCY 与 SLOWLOG 的阈值能够配合

Redis 的 Latency Monitoring 默认关闭,latency-monitor-threshold 为 0 时不会记录事件。该阈值单位是毫秒,应按业务能够接受的阻塞时间设置。SLOWLOG 的 slowlog-log-slower-than 单位则是微秒,两个单位不要混淆。

下面以“关注 20 毫秒以上的服务器事件,并保留 10 毫秒以上的命令”为例。先查看当前值,再在变更窗口内调整:

# 读取当前阈值,先记录原值以便回退
redis-cli CONFIG GET latency-monitor-threshold
redis-cli CONFIG GET slowlog-log-slower-than
redis-cli CONFIG GET slowlog-max-len

# LATENCY 阈值单位为毫秒:记录 20ms 及以上的事件
redis-cli CONFIG SET latency-monitor-threshold 20

# SLOWLOG 阈值单位为微秒:记录 10ms 及以上的命令
redis-cli CONFIG SET slowlog-log-slower-than 10000

# 增大环形记录长度,具体值按流量和内存预算调整
redis-cli CONFIG SET slowlog-max-len 256

为什么让慢日志阈值略低于 LATENCY 阈值?因为我们希望在一次 20 毫秒级 command 峰值出现时,慢日志大概率已经留下相关命令。若慢日志阈值反而高于 LATENCY 阈值,就可能看到 command 事件,却找不到对应命令。

CONFIG SET 是运行时变更。是否要把配置持久化,应遵循现有配置管理流程,不能在生产实例上随手执行 CONFIG REWRITE。使用 ACL 的环境还要给采集账号最小必要权限,采集脚本本身不应包含明文口令。

核心脚本:一次保存四类快照

创建 redis-latency-triage.sh,通过环境变量传入地址、端口和输出目录。认证继续使用现有的 redis-cli 安全配置或受控环境变量,脚本里不拼接口令:

#!/usr/bin/env bash
set -euo pipefail

# 连接参数允许由运行环境覆盖,脚本不保存密码
REDIS_HOST="${REDIS_HOST:-127.0.0.1}"
REDIS_PORT="${REDIS_PORT:-6379}"
OUTPUT_ROOT="${OUTPUT_ROOT:-./redis-latency-reports}"
SLOWLOG_COUNT="${SLOWLOG_COUNT:-32}"

# 用 UTC 时间创建独立目录,便于与应用监控时间对齐
STAMP="$(date -u +%Y%m%dT%H%M%SZ)"
REPORT_DIR="${OUTPUT_ROOT}/${STAMP}"
mkdir -p "${REPORT_DIR}"

# 公共连接参数集中在数组中,避免后续命令漏写主机或端口
REDIS_ARGS=(-h "${REDIS_HOST}" -p "${REDIS_PORT}" --raw)

# 保存最新事件摘要与可读诊断,不重置服务器中的历史数据
redis-cli "${REDIS_ARGS[@]}" LATENCY LATEST \
  > "${REPORT_DIR}/latency-latest.txt"
redis-cli "${REDIS_ARGS[@]}" LATENCY DOCTOR \
  > "${REPORT_DIR}/latency-doctor.txt"

# 保存最近的慢命令记录;数量可按现场流量调整
redis-cli "${REDIS_ARGS[@]}" SLOWLOG GET "${SLOWLOG_COUNT}" \
  > "${REPORT_DIR}/slowlog.txt"

# 保存持久化与后台任务状态,用于对照 fork、RDB、AOF 事件
redis-cli "${REDIS_ARGS[@]}" INFO persistence \
  > "${REPORT_DIR}/info-persistence.txt"

# 输出本次报告目录,不打印凭据或连接串
printf '%s\n' "${REPORT_DIR}"

脚本刻意没有调用 LATENCY RESET 或 SLOWLOG RESET。采集阶段先保留现场,确认报告已归档后,再由运维流程决定是否清空基线。Redis 的每类 LATENCY 事件时间序列容量有限,同一事件同一秒内的多次峰值还会合并为该秒最大值,因此采集间隔不宜过长。

运行与读取:先看事件名,再看慢日志

在应用告警或人工复现后立即运行一次采集器:

# 指向目标实例;认证信息由既有安全配置提供
REDIS_HOST=10.0.8.21 \
REDIS_PORT=6379 \
OUTPUT_ROOT=/var/tmp/redis-latency-reports \
bash ./redis-latency-triage.sh

读报告时先不要搜索某个熟悉的命令名,而是先看 LATENCY LATEST 的事件分类:

  • command:普通命令执行出现峰值,需要与 SLOWLOG 对齐;
  • fast-command:本应为 O(1) 或 O(log N) 的命令也发生延迟,系统调度或内部阻塞的嫌疑会上升;
  • fork:创建后台子进程耗时,常与 RDB 保存、AOF 重写及内存规模有关;
  • aof-write、aof-write-pending-fsync 等:指向 AOF 写入或 fsync 相关压力;
  • expire-cycle、eviction-cycle、eviction-del:指向过期或内存淘汰处理;
  • active-defrag-cycle:指向主动碎片整理周期。

如果 command 事件与 SLOWLOG 在相近时间出现,继续看命令、参数规模和数据结构大小。常见问题不是命令名字本身,而是它处理的元素数量。例如集合运算、排序、删除大对象或在生产使用 KEYS,都可能让单线程长时间无法服务其他客户端。

若应用报告高延迟,SLOWLOG 却没有相近记录,不能直接得出“Redis 没问题”。依次检查三件事:

  1. SLOWLOG 阈值是否设得过高,导致相关命令没被记录;
  2. LATENCY 是否出现 fork、AOF、过期、淘汰或碎片整理事件;
  3. 应用耗时是否主要来自网络、连接池或宿主机调度。

补上宿主机基线:intrinsic latency 只测系统调度

redis-cli --intrinsic-latency 不连接 Redis,它持续观察当前进程有多长时间没有获得 CPU。这个值代表内核、虚拟化和调度环境给 Redis 设下的延迟下限。测试必须在 Redis 所在服务器上运行;若在客户端机器运行,测到的是另一台主机,没有判因价值。

# 必须在 Redis 所在服务器本机执行;30 秒用于初步采样
# 该测试会占满一个 CPU 核心,应选择受控窗口并限制持续时间
redis-cli --intrinsic-latency 30

不要把一次测试结果当作永久基线。虚拟机的邻居噪声、CPU 超售和系统负载会随时间变化,可以在正常时段和故障时段各做几次短测试。若应用要求 5 毫秒,而故障窗口里宿主机固有延迟已经接近或超过 5 毫秒,即使 SLOWLOG 很干净,Redis 也不可能稳定提供更低的尾延迟。

这个测试会消耗一个 CPU 核心,所以不要在 CPU 已经紧张的实例上无限运行。它用于验证调度假设,不是常驻监控。常驻数据应来自操作系统 CPU steal、运行队列、上下文切换、磁盘 I/O,以及应用与 Redis 两侧的时间序列。

把采集结果放进判因矩阵

Redis 慢命令、后台事件和系统抖动对应的 SLOWLOG、LATENCY、intrinsic latency 与 CPU IO 证据组合图

图2:慢命令、Redis 内部事件和系统抖动的证据组合说明图,不是运行结果。

证据组合优先判断下一步
SLOWLOG 有同窗记录,LATENCY 有 command慢命令或大对象阻塞核对命令复杂度、参数规模、键大小,改为渐进式操作或拆分对象
SLOWLOG 为空,LATENCY 有 fork/AOF持久化后台事件或磁盘压力对齐 INFO persistence、子进程状态与系统 I/O
SLOWLOG 为空,LATENCY 有 expire/eviction集中到期或内存淘汰压力检查 TTL 分布、maxmemory 策略和大对象删除
Redis 内部证据弱,intrinsic latency 明显升高内核、虚拟化或 CPU 调度抖动检查 CPU steal、运行队列、NUMA 与邻居噪声
Redis 证据都低,只有应用耗时高网络、连接池或应用路径分解 DNS、建连、池等待、网络往返和序列化耗时

矩阵里最重要的是“同窗”。LATENCY 事件使用秒级时间戳,同一事件同一秒只保留最大值;SLOWLOG 也带时间与执行耗时。应用告警、Redis 事件和系统指标必须统一时区并尽量同步时钟,否则很容易把两个无关峰值错误关联。

验收:让结论能够被下一次故障复用

小项目完成后,可以用下面的清单验收:

  • LATENCY 与 SLOWLOG 阈值单位已经注明,且阈值能覆盖业务关心的尖峰;
  • 采集账号没有把密码写进脚本或命令历史;
  • 报告目录包含最新事件、Doctor、慢日志和持久化状态四份文件;
  • 报告时间使用 UTC 或与监控系统一致的时区;
  • 宿主机基线测试只在本机、受控时长内运行;
  • 结论基于至少两类证据,不因一条空 SLOWLOG 就排除 Redis 内部事件。

最后给出一个简单判断:SLOWLOG 回答“哪条命令在 Redis 主线程里执行得久”,LATENCY 回答“Redis 哪类敏感代码路径出现了峰值”,intrinsic latency 回答“宿主机是否连最基本的 CPU 调度都不稳定”。把这三把尺放在同一时间窗口里,慢命令与系统抖动就不再只能靠猜。

相关问题

SLOWLOG 没记录,为什么 LATENCY 仍有 command 事件?

先比较两套阈值。LATENCY 使用毫秒,SLOWLOG 使用微秒;如果慢日志阈值更高,就可能漏掉该命令。还要确认慢日志容量是否太小、记录是否已被覆盖。

LATENCY DOCTOR 可以代替 SLOWLOG 吗?

不能。Doctor 根据已记录的事件给出分析与建议,但定位具体慢命令仍要查看 SLOWLOG,并结合键大小和命令复杂度。

客户端延迟高而 Redis 内部延迟低,先查哪里?

优先拆分连接池等待、网络往返、TLS、序列化和应用线程调度。Redis 内部执行时间不包含完整客户端路径,二者本来就可能不同。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
MySQL Clone 插件恢复后复制坐标如何衔接MySQL Clone 插件恢复后复制坐标如何衔接
上一篇
MySQL Clone 插件恢复后复制坐标如何衔接
用 ResponseController 在代理中逐块刷新数据
下一篇
用 ResponseController 在代理中逐块刷新数据
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    394次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    473次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    479次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    423次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    249次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码