Redis 运维与监控实战

0 阅读57分钟

概述

前文《Redis Stack 与模块化扩展》扩展了 Redis 的能力边界。但无论 Redis 承载了多少业务模块,一旦上线运行,运维的挑战才真正开始——内存碎片何时需要关注?慢查询如何定位?主从延迟何时会触发告警?本文将从 INFO 命令的每一条关键指标到 Prometheus + Grafana 的完整监控体系,从 SLOWLOG 的慢命令分析到 LATENCY DOCTOR 的延迟诊断,构建 Redis 生产级运维的完整知识体系。

Redis 运维不是“部署完就跑”的事。没有监控,内存碎片可能悄悄从 1.2 涨到 3.0 直到 OOM;没有慢查询日志,一条 KEYS * 可能拖垮整个集群;没有延迟诊断,BGSAVEfork 阻塞可能让你在业务高峰期经历毫秒级的卡顿。本文将从 INFO 的指标解读到 Prometheus 的告警规则,从 MEMORY DOCTOR 的碎片分析到 redis-cli --bigkeys 的大 Key 扫描,系统拆解 Redis 运维的方方面面,帮助你将 Redis 从“能跑”提升到“可靠、可观测、可恢复”的生产级别。

核心要点

  • 监控指标体系INFO 各模块的 20+ 核心指标解读与告警阈值,涵盖 7 大模块,揭示服务器、客户端、内存、统计、复制、CPU 和集群的健康细节。
  • 慢查询日志SLOWLOG 的配置、输出解读与优化策略,关联第 2 篇线程模型,理解阻塞根源。
  • 延迟监控LATENCY DOCTOR/LATENCY LATEST/LATENCY HISTORY 的诊断方法论,直击 fork、AOF、过期等阻塞源。
  • 内存诊断MEMORY STATS/MEMORY DOCTOR/MEMORY USAGE/redis-cli --bigkeys 的内存分析工具链,结合第 3 篇内部编码,量化内存开销。
  • Prometheus + Grafanaredis_exporter 指标采集、Grafana 面板设计、告警规则 P0/P1/P2 分级,构建可观测性闭环。
  • 运维工具速查redis-cli --stat/--latency/--bigkeys/--cluster check 等,快速定位问题。

文章组织架构图

flowchart TD
    1[1. 核心监控指标体系: INFO命令全解]
    2[2. 慢查询日志: SLOWLOG配置与分析]
    3[3. 延迟监控: LATENCY命令诊断]
    4[4. 内存诊断: MEMORY命令与大Key扫描]
    5[5. Prometheus + Grafana 监控体系]
    6[6. 告警规则设计 P0/P1/P2分级]
    7[7. 运维工具速查]
    8[8. 面试高频专题]
    1 --> 2 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8

架构图说明

  • 总览说明:全文 8 个模块从 Redis 自身的监控诊断命令出发,逐步深入到 Prometheus + Grafana 的外部监控体系,最后以告警规则、运维工具速查和面试题收尾。整体逻辑遵循从内置工具到外部可观测性平台,再回归生产实践的闭环,强调内建能力与外部平台互补。
  • 逐模块说明:模块 1-4 是全文核心,深度解读 Redis 内置的四维诊断工具(INFO/SLOWLOG/LATENCY/MEMORY),这四者共同构成“发现-定位-分析-优化”的本地诊断链;模块 5-6 构建外部可观测性体系与告警分级,将指标转化为行动,实现无人值守;模块 7 提供运维工具箱速查,应对日常操作与应急;模块 8 面试巩固,将知识转化为职业竞争力,并包含复杂故障排查场景。
  • 关键结论Redis 运维的核心在于建立多层次的监控与诊断体系——通过 INFO 和 Prometheus 持续采集关键指标,通过 SLOWLOGLATENCY 定位性能瓶颈,通过 MEMORY 系列命令发现内存隐患。建立 P0/P1/P2 三级告警体系,才能让 Redis 在无人值守的情况下稳定运行。诊断能力的深度,直接决定系统可恢复的速度。

1. 核心监控指标体系:INFO 命令全解

INFO 是 Redis 内建的完整状态报告命令,其输出按模块分组,覆盖了从操作系统基础资源到业务级统计的所有维度。所有外部监控系统(如 Prometheus 的 redis_exporter)本质上都是通过周期性执行 INFO 命令来采集指标,因此深刻理解其每一条输出是构建生产级监控的第一性原理。

INFO 命令支持按模块获取,如 INFO memory 仅返回内存部分;INFO ALL 输出全量,默认分块以 # Section 起始。下面我们对七大核心模块进行深度拆解,并为每项关键指标提供正常基线、告警阈值与生产解读。

1.1 Server 模块:服务器静态与动态属性

Server 模块记录了 Redis 服务器的身份信息、运行时长、操作系统环境等,是识别节点、判断重启和检查版本兼容性的入口。

示例输出 (截选)

# Server
redis_version:7.2.4
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:3b3c3b3c3b3c3b3c
redis_mode:standalone
os:Linux 5.15.0-91-generic x86_64
arch_bits:64
monotonic_clock:POSIX
multiplexing_api:epoll
atomicvar_api:c11-builtin
gcc_version:12.2.0
process_id:1042
process_supervised:systemd
run_id:a1b2c3d4e5f6...
tcp_port:6379
server_time_usec:1698123456789012
uptime_in_seconds:864000
uptime_in_days:10
hz:10
configured_hz:10
lru_clock:1234567
executable:/usr/bin/redis-server
config_file:/etc/redis/redis.conf
io_threads_active:0

关键指标深度解读

  • redis_version:版本号,如 7.2.4。版本决定了可用的特性(如 Redis 7 的 Functions、ACL v2、MP-AOF、Sharded Pub/Sub 等)。在滚动升级或功能兼容性检查时,必须确认所有节点版本一致。
  • redis_modestandalonesentinelcluster。确认节点在架构中的角色,错误的模式会导致排查方向偏离。
  • uptime_in_seconds / uptime_in_days:运行时长。突然变小(小于业务已知启动时间)说明发生了重启,可能由崩溃、OOM Killer 或人工操作引起,应立即触发告警并检查持久化与主从状态。
  • process_id:PID,用于 stracegdb 或直接发送信号(如 SIGTERM)进行调试与维护。
  • hzserverCron 执行频率,默认 10 Hz,即每秒 10 次。Redis 7 允许通过 CONFIG SET hz 100 动态调整,这会使定时任务(过期键清理、渐进式 rehash、client timeout 检查)更密集,减少每次任务的最大阻塞时间,但增加 CPU 开销。第 2 篇线程模型已详述 serverCron 内部逻辑。
  • multiplexing_api:事件多路复用 API,通常为 epoll (Linux) 或 kqueue (macOS)。保证高性能 I/O 的基础。
  • io_threads_active:指示 I/O 线程是否正在使用。Redis 6 引入多线程 I/O,仅在大量写请求时激活以降低网络读写开销。

告警策略uptime_in_seconds 突变需立即关注,可通过 run_id 变化辅助确认是否为新进程。process_id 变化但 run_id 不变通常不会发生(两者一般同时变化)。

1.2 Clients 模块:客户端连接全景

该模块展示了连接到 Redis 的所有客户端状态,对于诊断连接泄漏、发现阻塞命令滥用以及分析输入/输出缓冲区压力至关重要。

示例输出

# Clients
connected_clients:185
cluster_connections:0
maxclients:10000
client_recent_max_input_buffer:1024
client_recent_max_output_buffer:20480
blocked_clients:2
tracking_clients:0
clients_in_timeout_table:0

关键指标深度解读

  • connected_clients:当前客户端连接总数,包括普通客户端、从节点(主节点视角)、Sentinel 连接等。正常基线取决于业务连接池大小和实例数量。突然飙升可能是连接池配置错误或下游服务雪崩重连。当 connected_clients / maxclients > 0.8 时,应触发 P1 告警,因为剩余连接数可能无法应对流量高峰。
  • maxclients:系统允许的最大连接数。此值受操作系统文件描述符限制(ulimit -n)和 redis.confmaxclients 配置的共同制约。实际可用的最大连接数为两者中较小者减 1(保留内部使用)。可以通过 CONFIG SET maxclients 动态上调,前提是系统 fd 限制足够。
  • blocked_clients:当前因执行 BLPOPBRPOPBRPOPLPUSHWAIT 等阻塞原语而挂起的客户端数量。该值 >0 不一定异常,但当其持续高位且不下降时,说明消费者处理速度跟不上生产,或根本就没有数据写入。大量阻塞客户端会消耗内存并占用连接数,进而可能触发 maxclients 拒绝。需要结合业务逻辑检查队列消费情况。
  • rejected_connections:因达到 maxclients 限制而被拒绝的连接总数(累计)。这是一个非常重要的信号:一旦 >0,说明系统已无法接受新连接,对应客户端会收到连接错误。必须立即扩容连接数或排查连接泄漏源头。应配合 connected_clients 趋势分析。Prometheus 中可监控 rate(redis_rejected_connections_total[5m]) > 0 触发 P1 告警。
  • client_recent_max_input_buffer:当前连接中客户端最大输入缓冲区大小(字节)。如果该值很大(如 >10MB),说明有客户端在发送超大命令(如巨大的 SET 值)或命令管道堆积,可能导致内存激增和主线程卡顿。
  • client_recent_max_output_buffer:当前连接中客户端最大输出缓冲区大小。这通常指示有慢客户端:例如某个从节点长时间无法消费复制数据,或某个普通客户端订阅了大量 Pub/Sub 消息但网络慢。输出缓冲区过大可触发 Redis 强制断开,以保护服务端内存(通过 client-output-buffer-limit 配置)。若该值异常增高,应检查 CLIENT LIST 找出相应客户端并优化。

与第 2 篇线程模型的关联:所有客户端的命令执行和回复写入都在主事件循环中处理,如果输出缓冲区过大或阻塞客户端过多,都会直接影响事件处理延迟。

1.3 Memory 模块:内存占用全透视

Memory 模块是 INFO 中最复杂、最重要的部分,提供了从 Redis 数据视图到操作系统进程视图的完整内存画像。

示例输出

# Memory
used_memory:2634567890
used_memory_human:2.45G
used_memory_rss:4200000000
used_memory_rss_human:3.91G
used_memory_peak:5500000000
used_memory_peak_human:5.12G
used_memory_peak_perc:47.87%
used_memory_overhead:215000000
used_memory_startup:1024000
used_memory_dataset:2419567890
used_memory_dataset_perc:91.84%
allocator_allocated:2630000000
allocator_active:2640000000
allocator_resident:2700000000
total_system_memory:32785008640
total_system_memory_human:30.53G
maxmemory:6442450944
maxmemory_human:6.00G
maxmemory_policy:allkeys-lru
mem_fragmentation_ratio:1.55
mem_fragmentation_bytes:1700000000
allocator_frag_ratio:1.05
allocator_frag_bytes:12000000
rss_overhead_ratio:1.55
rss_overhead_bytes:1500000000
mem_not_counted_for_evict:0
mem_replication_backlog:1048576
mem_total_replication_buffers:1048576
mem_clients_slaves:0
mem_clients_normal:150000000
mem_aof_buffer:0
mem_allocator:jemalloc-5.2.1
active_defrag_running:0
lazyfree_pending_objects:0
lazyfreed_objects:0

核心指标及告警阈值

  • used_memory:从分配器视角看,Redis 存储的所有数据以及内部数据结构占用的总内存(字节)。这是 Redis “认为自己使用了多少内存”。
  • used_memory_rss:操作系统视角,Redis 进程实际占用的物理内存(Resident Set Size)。used_memory_rss / used_memory 即为 mem_fragmentation_ratio。内存碎片率 = 1 表示完美无碎片;1~1.5 正常;>1.5 需关注;>2 时 RSS 是逻辑内存的两倍以上,内存浪费严重,应触发 P2 告警并安排排查或重启。持续升高可能导致系统 OOM。
  • maxmemory:配置的最大内存限制。当 used_memory 达到此值时,Redis 会根据 maxmemory-policy 执行键驱逐。used_memory / maxmemory 称为内存使用率,通常设置 80% 为警告线,85% 为紧急线 (P1),预留内存以应对写突发和碎片。
  • evicted_keys:因内存满而被逐出的键总数(位于 Stats 模块)。如果驱逐速率持续增加,说明实际数据需求已超出内存容量,应考虑扩容、优化数据结构或调整过期策略。驱逐与缓存命中率下降高度相关。
  • used_memory_overhead:用于内部机制的内存,如复制积压缓冲区、客户端缓冲区、Lua 脚本、AOF 缓冲区等,不包含实际数据。如果此值异常增长,可能指向复制缓冲区过大、客户端输出缓冲区堆积等问题。
  • used_memory_dataset:实际数据占用的内存,即 used_memory - used_memory_overhead。其占比 used_memory_dataset_perc 应保持高位,若下降则说明内部开销过大。
  • mem_fragmentation_ratio:即 RSS/used_memory,见上。
  • allocator_frag_ratio:分配器内部碎片率,allocator_active / allocator_allocatedallocator_allocated 是分配器分配给 Redis 的内存总量;allocator_active 是分配器向操作系统实际申请(并在池中)的总内存。此比率 > 1.1 表示分配器内部存在无法利用的空洞,通常是由于大量不同大小的对象分配和释放所致。
  • rss_overhead_ratioused_memory_rss / allocator_residentallocator_resident 是分配器常驻内存。该比率反映了分配器之外的额外开销,主要包括操作系统页表、Redis 进程代码段、栈、以及 copy-on-write 未被释放的页(来自 fork 子进程)。若该值 > 1.5,表示这些额外开销很大。
  • active_defrag_running:指示自动内存碎片整理是否正在进行。若长期为 1,CPU 开销会增加,可能影响延迟,需要调整 activedefrag 参数(如 active-defrag-threshold-lower)。
  • lazyfree_pending_objects:等待异步释放的对象数量。如果数值持续较高,说明后台释放线程来不及处理,可能是大 Key 删除频率太高,可能需要降低异步删除的请求速度。

与第 3 篇内部编码的关联used_memory 的实际组成取决于对象的内部编码(如 ziplist、listpack、hashtable)。例如,哈希对象在字段很少时使用 listpack,占用极少内存;一旦转成 hashtable,内存开销会大幅增加。因此,MEMORY USAGE 命令可以精确反映编码带来的开销,帮助第 3 篇的内存优化落地。

1.4 Stats 模块:吞吐量、命中率与事件统计

Stats 模块记录自启动以来的累积计数器和某些瞬时速率,是衡量 Redis 服务负载与缓存有效性的核心仪表。

关键指标

  • instantaneous_ops_per_sec:基于指数移动平均估算的当前每秒操作数。该值可迅速反映流量突变,比如活动开始时飙升。若突然跌至接近 0,可能服务被阻塞或网络故障;若突然飙升但 CPU 已满,则接近性能极限。
  • total_commands_processed:启动至今处理的命令总数。结合 Prometheus rate() 可平滑计算实际 QPS。
  • keyspace_hits / keyspace_misses:缓存命中和未命中次数。缓存命中率 = keyspace_hits / (keyspace_hits + keyspace_misses)。正常业务下应 > 90%(根据场景可调整)。若命中率下降,需分析:
    • 是否内存不足导致驱逐增加;
    • 是否大量请求不存在的键(缓存穿透);
    • 是否过期键集中在同一时间点,造成批量 miss。
  • expired_keys:被动或主动过期的键总数。若短时间内激增,且伴随 CPU 毛刺,可能是大量键集中过期导致 activeExpireCycle 执行时间变长。可以调高 hz 或使用随机过期时间来分散负载。
  • evicted_keys:因达到 maxmemory 而被驱逐的键数量。若该值持续增长,应立即检查内存使用率和策略,必要时扩容。
  • latest_fork_usec:最近一次 fork() 系统调用的耗时,单位微秒。此指标揭示了 BGSAVEBGREWRITEAOF 时主线程的阻塞时长。阈值建议:>100ms (100000us) 必须告警,通常应保持在 10ms 以内。详见 3.4。
  • pubsub_channels / pubsub_patterns:订阅的频道和模式数量。如果数量异常多(如数十万),可能消耗大量内存并影响全量 PUBSUB CHANNELS 操作的性能。
  • total_net_input_bytes / total_net_output_bytes:网络 I/O 总量,可用于流量统计和带宽规划。

1.5 Replication 模块:主从复制健康

该模块在不同角色下输出不同。主节点展示挂载的从节点列表和复制积压;从节点展示与主节点的连接和同步状态。

主节点关键指标

  • connected_slaves:已连接的从节点数量。若低于预期值,说明有从节点掉线,需立即检查其状态。应设置 Prometheus 告警:redis_connected_slaves < desired_count
  • master_repl_offset:主节点当前的复制偏移量(累计写入字节数),是衡量写入吞吐的参考。
  • repl_backlog_active:积压缓冲区是否启用(通常为 1)。若为 0,说明 repl-backlog-size 设置太小或发生意外。
  • repl_backlog_size / repl_backlog_histlen:积压缓冲区的总大小和当前存储的数据长度。如果从节点频繁需要全量同步,很可能是因为积压缓冲区不足以容纳断开期间的写流量,导致 repl_backlog_histlen 已满,无法进行部分重同步。

从节点关键指标(通过 INFO replication 查看):

  • master_link_statusupdowndown 为 P0 告警,意味着复制中断,数据可能滞后。
  • master_last_io_seconds_ago:距离上次与主节点的 I/O 操作的秒数。若此值持续 > 10,表示主从间可能网络异常或主节点过载无响应,触发 P1 告警。
  • master_sync_in_progress:是否正在进行全量同步。若为 1,从节点正在接收 RDB 文件,期间可能无法提供服务(取决于 replica-serve-stale-data 配置)。
  • slave_repl_offset:从节点已处理完成的复制偏移量。与 master_repl_offset 的差值即为复制延迟字节数。可通过 (master_repl_offset - slave_repl_offset) 结合写入速率估算延迟时间。

1.6 CPU 模块:CPU 时间与子进程消耗

CPU 模块记录服务器进程及其子进程的 CPU 时间累计值,可用来估算 CPU 使用率。

  • used_cpu_sys / used_cpu_user:主进程在内核态和用户态消耗的 CPU 累积时间(秒)。通过两次采样计算差值,可得到一段时间内的 CPU 利用率。used_cpu_sys 过高通常与频繁的网络系统调用、fork 操作、或大量 I/O 有关。
  • used_cpu_sys_children / used_cpu_user_children:所有后台子进程(RDB/AOF 重写)累计消耗的 CPU 时间。如果子进程 CPU 时间长期保持高位,说明持久化写入压力大,可能需要优化 RDB 保存频率或 AOF 重写参数。

1.7 Cluster 模块:集群全局状态

仅在 redis_mode = cluster 时有效。

  • cluster_enabled:1 表示集群模式开启。
  • cluster_stateok 表示所有 slot 都有服务节点且状态正常;fail 表示有 slot 无法提供服务,触发 P0 告警。
  • cluster_slots_assigned:已分配的槽数,应为 16384。
  • cluster_slots_ok / cluster_slots_pfail / cluster_slots_fail:表示槽的状态分布。任何 cluster_slots_fail > 0 都为 P0 级别。
  • cluster_known_nodes:集群已知节点总数,应等于实际成员数。
  • cluster_size:负责槽的主节点数量。
  • cluster_current_epoch:集群当前配置纪元,用于故障转移。

1.8 核心监控指标全景图

以下 Mermaid 图汇总了上述七大类中的 20+ 核心指标、正常基线和告警阈值,形成一张运维监控全景地图。

flowchart TD
    subgraph Server
        S1[uptime_in_seconds 重启告警]
        S2[redis_mode 模式]
        S3[hz 定时精度]
    end
    subgraph Clients
        C1[connected_clients >80% maxclients P1]
        C2[blocked_clients 持续>0 关注]
        C3[rejected_connections >0 P1]
        C4[max_input/output_buffer 异常大]
    end
    subgraph Memory
        M1[used_memory/maxmemory >85% P1]
        M2[mem_fragmentation_ratio >2 P2]
        M3[evicted_keys 速率 P1]
        M4[allocator_frag_ratio >1.3 P2]
        M5[rss_overhead_ratio >1.5 P2]
    end
    subgraph Stats
        ST1[instantaneous_ops_per_sec 突变]
        ST2[keyspace_hits/misses 命中率<85% P2]
        ST3[latest_fork_usec >100ms P0]
        ST4[expired_keys 骤升]
    end
    subgraph Replication
        R1[master_link_status=down P0]
        R2[master_last_io_seconds_ago>10 P1]
        R3[connected_slaves 低于预期 P0]
        R4[复制积压不足 全量同步]
    end
    subgraph CPU
        CPU1[used_cpu_sys 飙升]
        CPU2[子进程CPU]
    end
    subgraph Cluster
        CL1[cluster_state=fail P0]
        CL2[cluster_slots_fail>0 P0]
    end
    Server --- Clients --- Memory --- Stats --- Replication --- CPU --- Cluster

四层说明

  • 指标解读:图以模块化形式展示 P0/P1/P2 告警,帮助快速聚焦关键异常。Server 和 CPU 模块补充背景信息;Clients 和 Replication 直接影响可用性;Memory 和 Stats 关联性能与容量;Cluster 关乎分布式健康。
  • 架构说明:所有指标均来自 INFO,监控系统通过周期抓取注入时序库。它们分别映射到不同的资源域:连接、内存、吞吐、复制、计算和拓扑,覆盖故障排查的各个起点。
  • 原因分析:这些指标能够直接回答“服务是否可用”(如 master_link_status)、“资源是否充足”(如内存使用率)、“性能是否正常”(如命中率)三大根本问题。例如,rejected_connections 表明连接池已耗尽,根源可能是连接泄漏或配置不足。
  • 应对建议:根据业务影响建立分级告警,P0 立即通知,P1 30分钟内处理,P2 纳入日常优化迭代。图中指标应与 Prometheus Alertmanager 集成,并配合 Grafana 面板实现可视化。

2. 慢查询日志:SLOWLOG 配置与分析

Redis 的慢查询日志系统将执行时间超过指定阈值的命令记录到内存中的固定大小队列里,这一机制对性能的影响极小(仅记录耗时命令的信息),但却是发现命令级性能瓶颈的最直接手段。

2.1 配置参数详解

redis.conf 中:

# 执行时间超过多少微秒的命令会被记录
# 生产建议设置为 1000 (1ms),以便捕捉到延迟毛刺
slowlog-log-slower-than 10000

# 最多保留多少条慢查询记录,FIFO
slowlog-max-len 128
  • slowlog-log-slower-than:单位微秒。设置为 0 记录所有命令(调试或临时压测分析用);设置为负数则禁用慢查询日志。Redis 执行任何命令所需的时间包括命令解析、排队、执行和回复,通常要求绝大多数命令在微秒级完成。因此,将阈值设在 1000μs 可以帮你发现那些“不寻常”的慢命令。许多团队为了性能极致,甚至设置为 500μs。
  • slowlog-max-len:存储在内存中的最大条目数,达到上限后最旧的记录会被丢弃。在高吞吐环境中,慢日志可能很快被冲刷,建议设置为 1024 或更高,以避免丢失关键线索。每条记录大约占用几十字节,成本极低。

2.2 SLOWLOG GET 输出详解

使用 SLOWLOG GET 5 获取最近 5 条记录:

1) 1) (integer) 42           # 1. 唯一递增ID
   2) (integer) 1698123456   # 2. 命令执行的Unix时间戳(秒)
   3) (integer) 15678        # 3. 执行耗时,单位:微秒
   4) 1) "KEYS"              # 4. 命令及其参数数组
      2) "user:*"
   5) "127.0.0.1:53142"      # 5. 客户端IP:端口
   6) "my-client-name"       # 6. 客户端名称(若通过 CLIENT SETNAME 设置)

解读:

  • ID:可通过 SLOWLOG RESET 后重新从 0 开始。
  • 执行时间:15.6ms,远超 10ms 阈值,是典型的阻塞操作。
  • 命令KEYS user:* 遍历所有键空间,在生产中严格禁止。
  • 客户端信息:可以快速溯源到具体应用服务器,以便定位有问题的代码。

通过 SLOWLOG LEN 可获取当前记录总数,用于告警(如 slowlog_len > 100 触发 P2)。

2.3 慢命令分类、根源与优化策略

常见慢命令及优化方案:

  1. KEYS pattern:遍历所有键,时间复杂度 O(N),N 为键总数。替代方案:使用 SCAN 命令家族(SCAN, SSCAN, HSCAN, ZSCAN)进行增量迭代,每次只占用少量时间。也可用 redis-cli --scan --pattern 'user:*',其内部即使用 SCAN

  2. 集合全量返回SMEMBERSHGETALLLRANGE 0 -1ZRANGE 0 -1 等命令可能返回数百万个元素,消耗大量网络带宽和 CPU 进行编码传输。优化:

    • 使用 SSCAN/HSCAN/ZSCAN 游标迭代。
    • 对 List 限定范围 LRANGE 0 100
    • 结构设计上拆分大集合为多个小集合(例如按用户 ID 取模分桶)。
  3. 聚合与运算命令SUNIONZINTERSTORESORT 等可能涉及大量计算。若数据量大,应将计算移至应用层或使用 Redis Gears(第 10 篇)异步处理,避免阻塞主线程。

  4. 删除大 KeyDEL big_set 如果元素数量极大,释放内存的操作可能阻塞数百毫秒。Redis 4.0 起提供 UNLINK 命令(以及 FLUSHDB/FLUSHALL ASYNC),将释放操作交给后台线程惰性处理,主线程仅移除键名即可返回。这是解决大 Key 删除阻塞的标准手段。

  5. 过期键集中清理:Redis 的 activeExpireCycle 会定期扫描随机键,删除过期键。如果某一瞬间大量键过期,serverCron 在一次执行中可能多次循环,导致主线程短暂停顿。优化方法:在设置过期时间时引入随机偏移量(例如 EXPIRE key 3600 + random(0, 600)),平滑过期分布;适当提高 hz 值,使每次扫描更快但时间片更短。

2.4 SLOWLOG 诊断与优化决策流程

flowchart TD
    A["SLOWLOG GET 发现慢命令"] --> B{"命令类型识别"}
    B -- "KEYS *" --> C["替换为 SCAN 家族游标迭代"]
    B -- "SMEMBERS/HGETALL 等全量" --> D["使用 SSCAN/HSCAN 或 LIMIT 范围"]
    B -- "DEL 大Key" --> E["改用 UNLINK 异步删除"]
    B -- "SUNION/ZINTERSTORE" --> F["计算迁移至应用层或 Gears"]
    B -- "集中过期" --> G["随机化 TTL,调高 hz"]
    C --> H["代码修复并压测验证"]
    D --> H
    E --> H
    F --> H
    G --> H
    H --> I["监控慢查询长度,确认减少"]

    classDef decision fill:#f1f5f9,stroke:#334155,stroke-width:2px,color:#0f172a
    classDef process fill:#f8fafc,stroke:#64748b,stroke-width:2px,color:#1e293b

    class B decision
    class A,C,D,E,F,G,H,I process

流程详解

  • 第一步:通过 SLOWLOG GET 或 Prometheus 的 redis_slowlog_length 发现新增慢命令,逐条分析命令和参数。
  • 第二步:根据命令类型进入不同优化分支,流程图给出了最常见的几类问题及对应解决策略。
  • 第三步:优化实施后,用 SLOWLOG RESET 清空日志,观察一段时间,确认新慢查询不再出现,或长度恢复正常。

架构说明:慢查询日志依托于 Redis 的单线程模型(第 2 篇),任何慢命令都会直接拖慢所有后续请求。因此,消除慢命令是保证 P99/P999 延迟的关键。

原因分析:慢命令的产生根源通常有三:不合理的数据访问模式(全量遍历)、过大的键值(大 Key)以及高计算复杂度命令。它们都违背了 Redis “快”的设计原则。

应对建议:建立代码审查规范,禁止 KEYS 等危险命令;使用 UNLINK 替代 DEL;在 DevOps 流程中加入 redis-cli --bigkeys 定期扫描,对发现的慢命令进行根本性重构。

3. 延迟监控:LATENCY 命令诊断

除了慢命令,Redis 还可能因为操作系统层面的因素(如 fork、磁盘 I/O)或内部机制(如过期清理)产生短暂的延迟尖峰。LATENCY 命令框架会持续监测这些事件,并提供自动诊断报告,是排查“不明卡顿”的利器。

3.1 LATENCY LATEST 与延迟事件类型

LATENCY LATEST 列出每种已监控事件的最新延迟记录:

127.0.0.1:6379> LATENCY LATEST
1) 1) "command"
   2) (integer) 1698123456
   3) (integer) 250
   4) (integer) 1000
2) 1) "fork"
   2) (integer) 1698123400
   3) (integer) 15000
   4) (integer) 80000

各字段依次为:事件名、最近发生时间戳、最新延迟(毫秒)、该事件历史最大延迟(毫秒)。

核心事件类型解析

  • command:命令执行总耗时(包含排队和网络写回)。当它出现异常值时,通常对应慢查询。
  • forkfork() 系统调用造成的阻塞。Redis 在 BGSAVEBGREWRITEAOF 时必须 fork 子进程,此时内核需要复制父进程的页表,内存越大、页数越多,耗时越长。latest_fork_usec 也是衡量此事件。
  • aof-fsync-always:当 appendfsync always 时,每个写命令都需等待 fsync 将 AOF 缓冲区刷入磁盘,这完全受磁盘性能影响。
  • aof-write-pending-fsync:在 everysec 模式下,AOF 写入线程与 fsync 线程可能竞争,导致写操作在特定条件下被挂起。
  • expire-cycle:执行过期键清理循环时的阻塞。当大量键同时过期时,该值可能突然升高。
  • eviction-cycle:执行键驱逐时的阻塞,与 maxmemory-policy 和内存压力有关。
  • fast-command / slow-command(Redis 7):更细粒度的命令延迟分类。

3.2 LATENCY HISTORY 事件历史趋势

LATENCY HISTORY fork 可获取该事件最近 160 个观测样本(默认),输出为 (timestamp, latency) 对。通过分析这些数据点,可以绘制出延迟的周期性模式。例如,如果每 5 分钟出现一次 fork 延迟峰,可能对应 save 配置的触发频率。

3.3 LATENCY DOCTOR:智能诊断报告

LATENCY DOCTOR 分析采集的延迟事件,输出人类可读的优化建议,是延迟排查的第一站。示例片段:

I have a few advices for you:

- I detected a high fork time. This usually happens when the server is
  running with very big memory maps and the kernel's transparent huge pages
  (THP) support is enabled. Please disable THP:
  echo never > /sys/kernel/mm/transparent_hugepage/enabled

- Latency generated by AOF fsync is high. If you can tolerate some data loss
  consider switching the appendfsync mode to everysec.
  Otherwise, consider using an SSD or improving the I/O performance.

- I detected a potential issue with the AOF rewriter. The time spent in the
  `BGREWRITEAOF` process is too high. Consider reducing the `auto-aof-rewrite-
  percentage` parameter.

该报告直接给出可能的根因和修复命令,极大地降低了诊断门槛。

3.4 常见延迟来源深入剖析与调优

3.4.1 fork 阻塞与优化

  • 根源fork() 在 Linux 下采用 copy-on-write,但创建子进程时必须复制父进程的页表,该操作与进程的虚拟内存大小成正比。一个 20GB 内存的 Redis 进程,页表可能有 5GB 以上,复制需几百毫秒。同时,若开启了 Transparent Huge Pages (THP),内核还需处理大页的 COW,加剧了阻塞。
  • 监控INFO stats 中的 latest_fork_usec 精确记录了最近一次 fork 的微秒耗时。建议告警阈值为 >50000 (50ms)。Prometheus 可用 redis_latest_fork_usec 配置规则。
  • 优化
    • 禁用 THP:务必在操作系统层面禁用:echo never > /sys/kernel/mm/transparent_hugepage/enabled,并将其写入启动脚本。
    • 控制内存大小:尽可能将单个 Redis 实例的内存限制在 10GB 以内,如果数据量大,采用集群分片,而不是单机大内存。
    • 调整 RDB 保存频率:减少不必要的 BGSAVE,例如取消过于频繁的 save 配置,或仅在低峰期执行。
    • 调整 vm.overcommit_memory:设置为 1,防止 fork 时因内存不足失败,但不会直接减少阻塞时间。

3.4.2 AOF fsync 与磁盘 I/O 延迟

  • appendfsync always:每个命令都触发 fsync,强数据安全,但延迟严重依赖磁盘。如果磁盘是机械盘,延迟可达数毫秒,直接拖慢所有写请求。建议改用 everysec,平衡性能与安全。如果必须用 always,必须使用企业级 SSD。
  • everysec 下的竞争:当 AOF 写入缓冲区速度和 fsync 操作竞争时,可能出现 aof-write-pending-fsync 延迟。配置 aof-rewrite-incremental-fsync yes,可将重写进程的 fsync 分块执行,减少竞争。
  • 建议:将 AOF 文件目录置于低延迟磁盘(如本地 SSD),避免网络文件系统(NFS)。

3.4.3 网络抖动与内部延迟

  • 网络延迟:可通过 redis-cli --latency--latency-history 直接测量客户端到服务器的 RTT。LATENCY LATEST 不会报告网络问题,因为它测量的是服务端内部事件。但网络抖动会导致客户端视角的延迟增加,需协同排查。
  • CPU 调度延迟:使用 redis-cli --intrinsic-latency 可测试 Redis 服务器所在机器的内在延迟(上下文切换、CPU 缓存等),提供基准参考。

4. 内存诊断:MEMORY 命令与大 Key 扫描

内存是 Redis 的生命线,不当的内存使用会导致碎片、OOM 和延迟抖动。Redis 7 的 MEMORY 命令族提供了从宏观碎片到微观单键占用的全套诊断工具,结合 redis-cli 的大 Key 扫描,能够建立起完整的内存分析链路。

4.1 MEMORY STATS:深入分配器与碎片细节

MEMORY STATS 提供比 INFO memory 更细致的分类,特别是将内存碎片分解为分配器碎片和 RSS 开销两部分。

关键输出字段解读

  • dataset.bytes:净数据大小,即 used_memory_dataset
  • allocator_frag_ratioallocator_active / allocator_allocatedallocator_allocated 是 Redis 从分配器申请到的内存总量(包含数据结构和对象头等);allocator_active 是分配器实际向 OS 申请的内存池大小。该比率 > 1.1 表示分配器内部有碎片,即空闲内存分散在已申请的池中,无法被 OS 回收。
  • rss_overhead_ratioused_memory_rss / allocator_residentallocator_resident 是分配器实际在物理内存中的常驻部分。若此值过高,意味着大量内存被页表、fork 子进程的 COW 页、或者进程的代码栈占用。结合 mem_fragmentation_ratio 可以判断碎片是在分配器内部还是额外开销。
  • allocator_active vs allocator_resident:如果 allocator_active 远大于 allocator_resident,说明分配器有大量内存被 OS swap 到磁盘,这会严重拖慢性能,必须检查系统 swappiness 设置。

生产分析案例

  • mem_fragmentation_ratio = 3.0allocator_frag_ratio = 1.05rss_overhead_ratio = 2.85。结论:分配器内部碎片正常,问题出在 RSS 额外开销。此时应重点排查 THP、fork 或 swap 导致的问题,而非内存分配器本身。

4.2 MEMORY DOCTOR:智能内存诊断报告

MEMORY DOCTOR 分析当前内存状况并给出优化建议。输出如:

Peak memory usage is 5.12G (84.27% of total memory).
High allocator fragmentation: 1.80 (this means your memory allocator is
fragmenting a lot). To improve allocator internal fragmentation, consider
restarting Redis if possible.
High RSS overhead: 2.0. There is additional memory used by the process that
is not directly related to Redis data. Check THP, fork overhead.
Big keys: The following keys appear to be very large:
- "big_hash" (type hash, size 10MB)
- "big_list" (type list, size 8MB)

它整合了碎片、RSS、大 Key 警告,是内存优化的首要参考。报告中的重启建议是解决分配器内部碎片的终极手段,因为 jemalloc 不会主动将内存归还给 OS,重启后碎片清零。若不能重启,可开启 activedefrag yes 尝试在线整理,但会消耗 CPU 资源并可能增加延迟毛刺。

4.3 MEMORY USAGE key:单键内存的显微镜

MEMORY USAGE key [SAMPLES count] 返回某个键及其值占用的总内存字节数,包含内部数据结构开销(如 dictEntry、redisObject、SDS、ziplist/listpack 等,详见第 3 篇内部编码)。这对于评估拆分大 Key 的收益、比较不同编码的内存效率极为有用。

127.0.0.1:6379> MEMORY USAGE big_hash
(integer) 10485800

对于嵌套集合,可通过 SAMPLES 参数指定抽样数量以估算(默认 5)。这个值是后续容量规划的重要输入。

4.4 redis-cli --bigkeys / --memkeys:大 Key 扫描器

redis-cli --bigkeys 使用 SCAN 遍历所有键,非阻塞地统计每种数据类型的最大键(基于元素个数或长度)。示例输出:

[00:00:00.123] Scanning the keyspace...
[00:00:05.456] Biggest string found: 'large_cache' has 5242880 bytes
[00:00:10.789] Biggest hash found: 'big_hash' has 100000 fields
-------- summary -------
Sampled 1000000 keys!
Biggest string found 'large_cache' has 5242880 bytes
Biggest hash found 'big_hash' has 100000 fields

但它不反映实际内存占用(例如一个 ziplist 的 hash 有 1000 字段可能比一个 100 字段的 hashtable 内存还要小)。于是有了 --memkeys,它会为每个 key 执行 MEMORY USAGE 估算内存占用,并按内存大小排序,真正找到内存大头。缺点是扫描速度变慢,因为有额外的内存估算调用。

大 Key 的危害

  • 阻塞删除DEL 大集合时,主线程会长时间阻塞。
  • 读写延迟HGETALL 等命令返回大量数据,网络包变大,内存拷贝和传输耗时增加。
  • 内存碎片:大 Key 的分配和释放容易留下难以利用的空洞。

4.5 MEMORY 诊断与碎片分析决策图

flowchart TD
    A["MEMORY STATS 获取碎片指标"] --> B{"mem_fragmentation_ratio"}
    B -- ">2.0" --> C["高碎片告警 P2"]
    B -- "1.5~2.0" --> D["中度碎片, 持续观察"]
    B -- "<1.5" --> E["健康"]
    C --> F["MEMORY DOCTOR 获取建议"]
    D --> F
    F --> G{"建议重启?"}
    G -- "是" --> H["评估维护窗口,主从切换后重启"]
    G -- "否" --> I["按建议: 关闭THP/调整activedefrag/减少fork"]
    H --> J["重启后验证碎片率<1.5"]
    I --> J
    J --> K["定期扫描大Key并拆分"]

    classDef decision fill:#f1f5f9,stroke:#334155,stroke-width:2px,color:#0f172a
    classDef process fill:#f8fafc,stroke:#64748b,stroke-width:2px,color:#1e293b
    class B,G decision
    class A,C,D,E,F,H,I,J,K process

决策流程:从发现高碎片率开始,用 MEMORY DOCTOR 区分是分配器碎片还是 RSS 开销,然后决定是否重启。重启需结合高可用架构(如 Sentinel 主从切换)进行,避免中断服务。在线碎片整理可作为临时缓解。

架构说明:诊断链条以 MEMORY STATS 为基础,DOCTOR 为解读,USAGE--bigkeys 为精细化分析,层层递进。

原因分析:碎片高企主要源于频繁的大小对象分配与释放、fork 触发的 COW 页复制,以及操作系统内存管理特性(THP)。理解 jemalloc 的原理有助于针对性地调优。

应对建议:建立内存巡检 SOP,每月执行 MEMORY DOCTOR--bigkeys,发现异常及时处理。将 mem_fragmentation_ratiolatest_fork_usec 设置为 P2 监控项,长期趋势可视化。

5. Prometheus + Grafana 监控体系

虽然 Redis 自带诊断命令强大,但要实现多实例聚合、历史趋势分析和自动化告警,必须依赖外部可观测性栈。Prometheus + redis_exporter + Grafana 是业界标配,通过周期采集 INFO 命令输出,转化为时序数据。

5.1 监控架构与部署

flowchart LR
    A[Redis 实例1] -->|INFO| B[redis_exporter]
    C[Redis 实例2] -->|INFO| D[redis_exporter]
    E[Redis 实例N] -->|INFO| F[redis_exporter]
    B --> G[Prometheus Server]
    D --> G
    F --> G
    G --> H[Grafana 可视化]
    G --> I[Alertmanager]
    I --> J[邮件/PagerDuty/钉钉]

组件说明

  • redis_exporter:官方推荐 exporter,直接连接 Redis 实例,执行 INFO 和部分 CONFIG 命令,将结果转换为 Prometheus 格式暴露在 /metrics 端点。支持单机或代理模式,可同时采集多个实例(通过 -redis.addr 启动参数或 HTTP 请求传递 target 参数)。
  • Prometheus:定期拉取 exporter 数据,存储在本地 TSDB,通过 PromQL 提供强大的查询与聚合能力。
  • Grafana:以 Prometheus 为数据源,通过丰富的面板将指标可视化,并支持设置告警(亦可由 Alertmanager 统一管理)。

配置示例(Prometheus prometheus.yml):

scrape_configs:
  - job_name: 'redis'
    static_configs:
      - targets:
        - 'redis://10.0.0.1:6379'
        - 'redis://10.0.0.2:6379'
    metrics_path: /scrape
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: redis-exporter-service:9121   # exporter 服务地址

此配置让 Prometheus 通过 exporter 代理采集两个 Redis 实例,并保留实例地址为 instance 标签。生产环境中可通过 Kubernetes Service 或 Consul 实现动态发现。

5.2 核心 PromQL 查询体系

以下为结合上文关键指标编写的监控查询,是构建 Grafana 面板的基础。

QPS(每秒命令数)

rate(redis_commands_processed_total[1m])

缓存命中率

redis_keyspace_hits_total / (redis_keyspace_hits_total + redis_keyspace_misses_total)

内存使用比例

redis_memory_used_bytes / redis_memory_max_bytes

内存碎片率

redis_mem_fragmentation_ratio

连接使用比例

redis_connected_clients / redis_config_maxclients

主从连接状态(1 为 up,0 为 down):

redis_master_link_status

最近 fork 耗时(微秒)

redis_latest_fork_usec

驱逐速率

rate(redis_evicted_keys_total[5m])

慢查询日志长度

redis_slowlog_length

复制延迟字节数(需从主节点获取 master_repl_offset 和从节点 slave_repl_offset 计算):

redis_master_repl_offset - redis_slave_repl_offset

P99 延迟(需 redis_exporter 开启 latency histogram 采集):

histogram_quantile(0.99, rate(redis_commands_duration_seconds_bucket[1m]))

5.3 Grafana 面板设计层次与实现

flowchart TD
    subgraph Overview ["概览面板 - 快速健康检查"]
        O1["QPS 曲线 - Stat"]
        O2["缓存命中率% - Stat"]
        O3["连接数/最大连接 - Gauge"]
        O4["内存使用率% - Gauge"]
    end
    subgraph Memory ["内存面板 - 碎片与构成"]
        M1["used_memory vs maxmemory 趋势"]
        M2["碎片率 趋势线"]
        M3["驱逐速率 每秒"]
        M4["内存构成堆叠图 dataset/overhead"]
    end
    subgraph Latency ["延迟面板 - 性能诊断"]
        L1["P99 命令延迟 曲线"]
        L2["慢查询数量 时间序列"]
        L3["阻塞客户端数 趋势"]
        L4["latest_fork_usec 散点图"]
    end
    subgraph HA ["高可用与持久化面板"]
        H1["RDB 最后保存状态"]
        H2["AOF 最后写入状态"]
        H3["主从连接状态(up/down)"]
        H4["复制延迟字节数"]
        H5["已连接从节点数"]
    end
    Overview --> Memory --> Latency --> HA

设计理念

  • 概览面板:一行放置四个关键指标的大数字或简单图表,让运维一眼看清系统是否健康。颜色阈值:内存使用率 < 70% 绿色,70-85% 黄色,>85% 红色。
  • 内存面板:展示内存随时间的变化趋势,以及碎片率的走向。通过堆叠图展示 used_memory_datasetused_memory_overhead 的比例,当 overhead 面积异常变大时,说明有缓冲区堆积等问题。
  • 延迟面板:这是定位性能毛刺的核心区域。P99延迟 若出现尖峰,可联动慢查询数量和 fork 耗时图表,快速缩小原因范围。
  • 高可用面板:使用状态时间轴 (Status history) 展示持久化状态和主从连接是否异常。表格面板可以列出每个从节点的复制延迟。

Grafana 变量设置

  • 使用 $instance 变量基于 label_values(redis_up, instance),支持多实例切换。
  • 使用 $db 变量基于 label_values(redis_db_keys, db) 过滤数据库维度。

5.4 Spring Boot Actuator + Micrometer 集成

在 Spring Boot 应用中,可以通过 Micrometer 将 Lettuce 客户端指标暴露给 Prometheus,从而实现端到端监控。

  1. 引入依赖:micrometer-registry-prometheusspring-boot-starter-actuator
  2. 配置暴露端点:
management:
  endpoints:
    web:
      exposure:
        include: health,info,prometheus
  metrics:
    export:
      prometheus:
        enabled: true
    tags:
      application: my-service
  1. Lettuce 连接池指标如 lettuce_command_latency_secondslettuce_pool_active_connections 将被自动采集。结合 Redis 服务端指标,可以快速判断是客户端还是服务端的问题。

6. 告警规则设计(P0/P1/P2 分级)

告警规则是运维体系的行动指南。按照影响范围和紧急程度,将告警分为三级:

  • P0 立即响应:影响业务连续性,主从断开、持久化失败、集群不可用,需 5 分钟内介入。
  • P1 紧急处理:容量预警,内存、连接数达高水位,驱逐增多,需 30 分钟内处理。
  • P2 关注计划:性能与优化类,碎片率、命中率、慢查询增多,可纳入下一次迭代。

6.1 PrometheusRule YAML 示例

groups:
  - name: redis_p0
    rules:
      - alert: RedisMasterLinkDown
        expr: redis_master_link_status == 0
        for: 1m
        labels:
          severity: critical
          level: P0
        annotations:
          summary: "Redis 从节点与主节点断开 ({{ $labels.instance }})"
          description: "复制中断超过1分钟,可能导致数据不一致,立即检查网络或主节点状态。"

      - alert: RedisRDBBgsaveFailed
        expr: redis_rdb_last_bgsave_status == 0
        for: 5m
        labels:
          severity: critical
          level: P0
        annotations:
          summary: "Redis RDB 持久化失败 ({{ $labels.instance }})"
          description: "最近一次 BGSAVE 未成功执行,备份可能缺失,检查磁盘空间和权限。"

      - alert: RedisAOFWriteFailed
        expr: redis_aof_last_write_status == 0
        for: 5m
        labels:
          severity: critical
          level: P0
        annotations:
          summary: "Redis AOF 写入失败"
          description: "AOF 写入磁盘失败,有数据丢失风险,检查磁盘和文件系统。"

      - alert: RedisClusterStateFail
        expr: redis_cluster_state == 0
        for: 1m
        labels:
          severity: critical
          level: P0
        annotations:
          summary: "Redis 集群状态为 FAIL"
          description: "部分哈希槽不可用,集群无法提供完整服务。"

      - alert: RedisLatestForkUsecHigh
        expr: redis_latest_fork_usec > 100000   # >100ms
        for: 5m
        labels:
          severity: critical
          level: P0
        annotations:
          summary: "Redis fork 阻塞时间 >100ms"
          description: "可能因内存巨大或 THP 导致,会严重影响服务延迟。"

  - name: redis_p1
    rules:
      - alert: RedisMemoryUsageHigh
        expr: (redis_memory_used_bytes / redis_memory_max_bytes) > 0.85
        for: 5m
        labels:
          severity: warning
          level: P1
        annotations:
          summary: "Redis 内存使用率超过 85% ({{ $value | humanizePercentage }})"

      - alert: RedisConnectedClientsHigh
        expr: (redis_connected_clients / redis_config_maxclients) > 0.8
        for: 10m
        labels:
          severity: warning
          level: P1
        annotations:
          summary: "Redis 连接数超过 maxclients 的 80%"

      - alert: RedisRejectedConnections
        expr: rate(redis_rejected_connections_total[5m]) > 0
        for: 1m
        labels:
          severity: warning
          level: P1
        annotations:
          summary: "Redis 正在拒绝连接"

      - alert: RedisEvictionRateHigh
        expr: rate(redis_evicted_keys_total[5m]) > 10
        for: 5m
        labels:
          severity: warning
          level: P1
        annotations:
          summary: "Redis 键驱逐速率 >10/s"
          description: "内存不足,可能导致命中率下降,考虑扩容或调整策略。"

      - alert: RedisMasterIONoActivity
        expr: redis_master_last_io_seconds_ago > 30
        for: 5m
        labels:
          severity: warning
          level: P1
        annotations:
          summary: "Redis 主从 I/O 超过30秒无活动"

  - name: redis_p2
    rules:
      - alert: RedisFragmentationHigh
        expr: redis_mem_fragmentation_ratio > 2
        for: 30m
        labels:
          severity: info
          level: P2
        annotations:
          summary: "Redis 内存碎片率 > 2"
          description: "内存浪费严重,计划重启或开启 activedefrag"

      - alert: RedisCacheHitRateLow
        expr: (redis_keyspace_hits_total / (redis_keyspace_hits_total + redis_keyspace_misses_total)) < 0.85
        for: 30m
        labels:
          severity: info
          level: P2
        annotations:
          summary: "Redis 缓存命中率低于 85%"

      - alert: RedisSlowlogLengthHigh
        expr: redis_slowlog_length > 100
        for: 10m
        labels:
          severity: info
          level: P2
        annotations:
          summary: "Redis 慢查询日志堆积 >100条"
          description: "可能存在慢命令或阈值过低,需要分析 SLOWLOG"

告警配置管理:建议使用 Git 仓库管理规则文件,利用 promtool check rules 进行语法验证,并通过 CI/CD 自动更新。

7. 运维工具速查

以下为 redis-cli 高频运维子命令及典型输出解读:

工具命令功能典型输出/说明
redis-cli --stat实时性能监控keys mem clients blocked requests connections 每秒刷新,快速查看 QPS 和内存变化。
redis-cli --latency网络延迟测试min: 0, max: 12, avg: 0.56 (1500 samples) 持续输出 RTT,--latency-history 按间隔输出历史。
redis-cli --bigkeys大 Key 扫描扫描键空间,输出各类型最大键(元素数/字节数),末尾总结。
redis-cli --memkeys按内存排序的 Key 扫描--bigkeys 更精确,通过 MEMORY USAGE 计算实际内存,输出 top 内存消耗键。
redis-cli --rdb dump.rdb离线分析 RDB 文件解析 RDB 内容,输出每个 key 的类型、大小、过期时间等,用于容量规划而不影响在线实例。
redis-cli --cluster check集群健康检查检查所有节点槽分配、一致性、迁移状态,集群故障时必用。
redis-cli --scan非阻塞键遍历结合 --pattern 可替代 KEYS,安全遍历键空间。
redis-cli --pipe管道批量导入高效导入数据,比逐条写入快很多。
redis-cli --intrinsic-latency测试服务器内在延迟输出服务器上下文切换、CPU 调度延迟基值,辅助判断硬件性能。

使用示例

  • 例行巡检:每日执行 redis-cli --stat 观察趋势,每周执行 redis-cli --bigkeys 并分析大 Key。
  • 应急响应:redis-cli --latency 确认网络,SLOWLOG GET 100 分析毛刺,LATENCY DOCTOR 诊断内部事件。

8. 面试高频专题

(以下内容严格与正文分离,用于面试指导,每题均包含完整回答、多角度追问和加分项。)

Q1: INFO 命令中哪些指标最需要关注?各自的告警阈值是多少? 一句话回答:核心关注 used_memory_rss/used_memory 碎片率、connected_clients 饱和度、evicted_keys 驱逐量、master_link_statusinstantaneous_ops_per_sec,阈值分别为 >2、>80% maxclients、速率 >10/s、down、剧烈波动。 详细解释

  • mem_fragmentation_ratio = used_memory_rss / used_memory,正常值 1~1.5,超过 2 意味着大量物理内存被浪费,可能触发 OOM,需要重启或在线碎片整理。
  • connected_clients / maxclients 反映连接池占用,超过 80% 时剩余容量不足以应对突发,应当扩容或排查连接泄漏。
  • evicted_keys 每秒增加说明内存已达 maxmemory,并根据策略驱逐数据,可能导致缓存命中率下降,需扩容或优化模型。
  • master_link_status 指示主从复制状态,为 down 时高可用失效,若此时主节点故障将丢失数据,因此是 P0 告警。
  • instantaneous_ops_per_sec 突变至接近 0 可能表示服务阻塞或死锁,飙升则接近性能极限,需要立即排查。 多角度追问
  • 追问 1:mem_fragmentation_ratioallocator_frag_ratio 有什么区别?前者是 OS 视角 RSS 与 Redis 逻辑内存之比,后者是分配器内部内存池的碎片率,两者共同构成碎片分析。
  • 追问 2:如果 blocked_clients 持续很高,你会怎么做?检查阻塞命令的消费者逻辑,确认是否有数据在往队列写,必要时使用 CLIENT KILL 杀死阻塞过久的客户端。
  • 追问 3:keyspace_hitskeyspace_misses 如何结合分析缓存问题?计算命中率,若降低看 evicted_keys 是否增加,区分是驱逐还是穿透;misses 增长过快且无驱逐,很可能是缓存穿透。 加分回答:结合 Prometheus 的 redis_memory_max_bytes 指标设计分级告警,当内存使用率超 70% 发送低优提醒,超 85% 紧急通知,自动触发弹性扩容(如通过 K8s HPA 或自定义 Operator)。

Q2: SLOWLOG 如何配置?如何定位一个慢命令? 一句话回答:设置 slowlog-log-slower-than 阈值为微秒(生产建议 1000),slowlog-max-len 记录条数,通过 SLOWLOG GET 查看慢命令、耗时和客户端,结合业务代码定位。 详细解释

  • 配置 slowlog-log-slower-than 10000 记录超 10ms 的命令,高吞吐环境降低至 500-1000μs 捕捉毛刺。slowlog-max-len 128 可按需调大至 1024。
  • SLOWLOG GET 10 输出每条记录的 ID、时间戳、耗时(微秒)、命令及参数、客户端 IP。如果多次出现 KEYSSMEMBERS 等全量遍历命令,即可定位到具体业务代码。
  • 还可以结合 LATENCY LATEST 查看命令延迟事件交叉验证。 多角度追问
  • 追问 1:为什么 KEYS 会慢?它会阻塞 Redis 单线程,遍历整个键空间,时间复杂度 O(N),当键数量巨大时造成长时间停顿。
  • 追问 2:SLOWLOG RESET 会丢失数据吗?会清空内存中的慢日志,所以生产环境中应先采集再重置,或通过 Prometheus 持续采集 redis_slowlog_length
  • 追问 3:除了 KEYS,哪些命令可能产生慢查询?DEL 大集合、HGETALLSUNIONZINTERSTOREFLUSHDB 等,任何 O(N) 复杂度的命令都应警惕。 加分回答:利用 CLIENT LIST 查看输出缓冲区异常大的客户端,结合 SLOWLOG 定位可能滥用大数据量返回的应用。在自动化流程中,可将慢查询日志推送到 ELK,通过脚本分析高风险命令模式并报警。

Q3: LATENCY DOCTOR 能诊断哪些延迟问题?fork 阻塞如何监控和优化? 一句话回答LATENCY DOCTOR 可诊断 fork 耗时高、AOF fsync 延迟、THP 影响、过期周期慢等问题;fork 阻塞通过 latest_fork_usec 监控,>50ms 告警,优化包括禁用 THP、控制内存大小和调整 RDB 频率。 详细解释

  • LATENCY DOCTOR 读取内核监控的延迟事件,分析 spike 并给出建议。例如,若检测到 fork 延迟很高,它会提示禁用 THP;若 aof-fsync-always 延迟高,建议改用 everysec
  • latest_fork_usec 来自 INFO stats,精确量化最近一次 fork 阻塞时间。20GB 内存实例在开启 THP 时可能高达 500ms。
  • 优化步骤:echo never > /sys/kernel/mm/transparent_hugepage/enabled;尽量将单实例内存控制在 10GB 以内,通过集群分片扩展;减少 BGSAVE 触发频率;设置 vm.overcommit_memory=1多角度追问
  • 追问 1:除了 LATENCY DOCTOR,还有什么方法查看 fork 历史?LATENCY HISTORY fork 可以查看最近 160 个样本的延迟值,绘制趋势图。
  • 追问 2:如果 latest_fork_usec 很高但无法重启或禁用 THP,怎么办?可以采用 replica-priority 调整从节点接管主节点角色,通过故障转移在新实例上恢复,间接完成重启。
  • 追问 3:AOF 延迟通常与哪些因素有关?磁盘性能(机械盘 vs SSD)、文件系统、appendfsync 策略、aof-rewrite-incremental-fsync 设置等。 加分回答:使用 redis-cli --intrinsic-latency 检查主机基本延迟基线,排除硬件干扰。结合 Prometheus 的 redis_latest_fork_usecredis_commands_duration_seconds 共同构建延迟看板,发现 fork 延迟与命令延迟的时间关联,辅助分析影响面。

Q4: MEMORY STATSMEMORY DOCTOR 能提供哪些内存诊断信息? 一句话回答MEMORY STATS 提供分配器碎片、RSS 开销、数据集大小等精确指标;MEMORY DOCTOR 则将这些指标转化为人类可读的优化建议,指出碎片原因、大 Key 警告及 THP 问题。 详细解释

  • MEMORY STATS 的输出包含 allocator_frag_ratiorss_overhead_ratio,可以区分碎片来源。当 allocator_frag_ratio 高时,说明分配器内存池碎片多,需要重启;rss_overhead_ratio 高时,可能是 THP 或 fork 开销,应系统调优。
  • MEMORY DOCTOR 整合这些信息,给出类似 “High allocator fragmentation: 1.80” 的报告,并指出最大的几个 Key,辅助制定重构计划。 多角度追问
  • 追问 1:MEMORY DOCTOR 建议重启,除了重启还能做什么?可启用 activedefrag yes,但会消耗 CPU;也可通过 MEMORY PURGE 尝试释放脏页(Redis 7),但效果有限。
  • 追问 2:如何计算单个 Key 的内存?用 MEMORY USAGE key,它返回包含内部编码开销的总字节数,对于优化数据结构很有用。
  • 追问 3:碎片率 1.8 需要紧张吗?1.8 属于中等偏高,若稳定不增长可计划内优化,若持续增长则必须干预。 加分回答:制定内存巡检计划,定期运行 MEMORY DOCTOR 并采集报告,结合 redis-cli --bigkeys 扫描结果形成内存优化台账,提升运维成熟度。

Q5: 如何通过 redis-cli --bigkeys 扫描大 Key?大 Key 对性能有什么影响? 一句话回答:执行 redis-cli -h host -p port --bigkeys,它非阻塞地遍历所有键,输出每种类型中最大的键及其大小(元素数/字节数);大 Key 的读写和删除会阻塞主线程,造成延迟尖峰、内存碎片和网络拥堵。 详细解释

  • 扫描过程使用 SCAN 命令,所以不会阻塞服务器。输出会按 String、Hash、List、Set、ZSet 分别给出最大键的统计。
  • 大 Key 的危害:删除一个大集合 O(M) 会长时间占用主线程;读取(HGETALL)会使输出缓冲区暴涨,拖垮网络;fork 持久化时大 Key 增加 COW 复制压力。
  • 应对方法:拆分大 Key 为多个小 Key(如按 ID 分桶),使用 UNLINK 异步删除,禁止全量返回命令。 多角度追问
  • 追问 1:--bigkeys--memkeys 区别是什么?--bigkeys 按元素数统计,--memkeys 通过 MEMORY USAGE 按实际内存占用排序,更能反映内存杀手。
  • 追问 2:大 Key 是怎么产生的?设计时未考虑规模,如把所有用户粉丝存为一个 Set,或缓存一个极大的 JSON 字符串。
  • 追问 3:如何安全删除一个 1000 万元素的 Set?使用 UNLINK 命令,内存回收将在后台线程进行,主线程立即可响应。 加分回答:结合 Redis 7 的 MEMORY USAGE,可在应用代码中增加运行时大 Key 检查,自动报警或拒绝写入。同时,在 CI/CD 中加入 redis-cli --bigkeys 扫描测试环境,预防大 Key 进入生产。

Q6: Prometheus 如何采集 Redis 指标?redis_exporter 的作用是什么? 一句话回答:Prometheus 通过 redis_exporter 代理采集,exporter 连接到 Redis 执行 INFO 等命令,将文本输出解析为 Prometheus metrics 格式,暴露 /metrics 端点供拉取。 详细解释

  • 部署 redis_exporter,通常与 Prometheus 在同一网络,通过 -redis.addr 指定目标实例,或者使用 HTTP target 参数动态指定。
  • Prometheus 配置 scrape_config,定期从 exporter 的 /scrape(或默认 /metrics)端点采集数据。redis_exporterINFO 的每一行转化为带有标签的 metric,如 redis_connected_clients
  • 单个 exporter 可采集多个 Redis 实例,只需传递不同的 target 参数,但会增加 exporter 自身的负担,高可用建议多实例部署。 多角度追问
  • 追问 1:redis_exporter 如何安全连接到 Redis?可以通过 -redis.password 或 Redis ACL 用户密码,以及 TLS 配置。
  • 追问 2:如何监控 Redis 集群所有节点?可以使用 redis_exporter-redis-only-metrics-check-keys 选项,或为每个节点部署一个 exporter,由 Prometheus 服务发现自动抓取。
  • 追问 3:exporter 本身挂了会导致指标缺失吗?会,所以需要确保 exporter 高可用(多副本),或者让 Prometheus 直接使用 redis_exporter 的集群模式。 加分回答:通过 relabel_configs 将 Redis 实例地址动态映射为 instance 标签,结合 Consul 或 Kubernetes 服务发现,实现完全自动化的指标采集。同时,启用 --script 选项运行 Lua 脚本采集自定义指标,扩展监控维度。

Q7: 如何设计一套 Redis 的告警规则?P0/P1/P2 分别监控什么? 一句话回答:P0 监控可用性(主从断开、持久化失败、集群 fail、fork 阻塞严重);P1 监控资源高水位(内存、连接、驱逐、复制延迟);P2 监控性能与优化指标(碎片率、命中率、慢查询堆积)。 详细解释

  • 分级原则:P0 需要立即通知,直接威胁服务连续性;P1 是容量告警,若持续将升级为 P0;P2 是性能基线与技术债务,可在工作时间处理。
  • 示例规则:redis_master_link_status == 0 为 P0,持续 1 分钟触发;(redis_memory_used_bytes / redis_memory_max_bytes) > 0.85 为 P1,持续 5 分钟;redis_mem_fragmentation_ratio > 2 为 P2,持续 30 分钟。
  • 所有规则都应设置 for 持续时间,防止因短暂抖动引发告警风暴。同时配置告警分组和路由,将不同级别送往不同通知渠道(P0 电话/PagerDuty,P1 即时消息,P2 邮件)。 多角度追问
  • 追问 1:master_link_status == 0 为什么是 P0?因为这意味着复制中断,如果此时主宕机将丢失数据,高可用完全失效。
  • 追问 2:内存使用率阈值可以调整吗?可以根据 maxmemory-policy 调整,如 noeviction 则需更保守(80%),allkeys-lru 可略高(90%)。
  • 追问 3:如何防止告警重复?使用 Alertmanager 的 group_byrepeat_interval 机制,相同告警抑制重复通知。 加分回答:将告警规则与自动化联动,如 P1 内存高水位触发自动扩容脚本(通过 K8s Operator 增加分片或调整内存配额),P0 主从断开触发自动故障转移确认,实现部分自愈。

Q8: mem_fragmentation_ratio 偏高是什么原因?如何解决? 一句话回答:内存分配器无法高效重用已释放的内存块,常见原因包括频繁修改不同大小的键值、大量小对象分配、fork 子进程引起的 COW 页未释放;可通过重启 Redis 或启用 activedefrag yes 解决。 详细解释

  • jemalloc 使用大小类分配,当应用程序频繁分配和释放大小不一致的对象时,会产生内存碎片,即 allocator_frag_ratio 升高。另外,RSS 开销(rss_overhead_ratio)高则可能是因 THP 或 fork 导致的未释放内存。
  • 重启是彻底解决碎片的方法,因为进程重启后所有内存归还 OS。在线方案是开启 activedefrag,它会利用 CPU 时间片逐步移动数据、合并空闲块,但会增加 CPU 和潜在延迟。
  • 预防:优化数据模型,尽量使用固定大小的数据结构;避免不必要的键过期和大 Key 删除;利用 Redis 7 的 MEMORY PURGE 尝试回收脏页。 多角度追问
  • 追问 1:activedefrag 有哪些关键参数?active-defrag-threshold-lower(开始整理的最低碎片率)、active-defrag-cycle-min 等,需要按实际负载调优。
  • 追问 2:如何不重启降低碎片?若碎片主要在分配器内部,可尝试 MEMORY PURGE;若为 RSS 开销,可尝试禁用 THP 并重启子进程以释放 COW 页。
  • 追问 3:碎片率 3.5 但内存够用,可以不处理吗?不处理浪费大量内存,降低内存性价比,且可能在未来数据增长时提前触发 OOM,建议计划处理。 加分回答:在监控中加入碎片率趋势,结合 active_defrag_running 指标观察整理效果,形成自动反馈回路。使用 Redis Cluster 主从切换机制实现滚动重启,无感解决碎片问题。

Q9: keyspace_hitskeyspace_misses 如何计算缓存命中率?命中率低可能是什么原因? 一句话回答:命中率 = hits / (hits + misses);低的原因通常是内存不足导致驱逐、大量请求不存在的键(缓存穿透)、集中过期或业务访问模式变更。 详细解释

  • 计算公式需基于累加值,Prometheus 查询为 redis_keyspace_hits_total / (redis_keyspace_hits_total + redis_keyspace_misses_total)
  • 分析流程:若 evicted_keys 也在增长,说明因内存满而驱逐热键,需扩容;若 misses 高而 evicted_keys 无变化,可能是缓存穿透,应检查请求的键是否有效,考虑添加布隆过滤器;若 expired_keys 剧增,可能是集中过期导致短期命中率低,分散过期时间即可。
  • 命中率低于 80% 通常不正常,需结合业务预期判断,但一般建议保持在 90% 以上。 多角度追问
  • 追问 1:如何区分是驱逐还是穿透导致的低命中率?观察 evicted_keys 速率,若无驱逐则大概率是穿透。
  • 追问 2:缓存穿透有什么解决方案?缓存空值(短期)、布隆过滤器拦截非法键、接口层校验。
  • 追问 3:命中率突然从 99% 降到 50%,怎么快速恢复?检查监控看是否大量键集中过期,可查看 expired_keys 曲线;如果是驱逐,临时提高 maxmemory 或紧急扩容,同时分析热点数据。 加分回答:通过 Prometheus 记录命中率并分层(按数据库),配合 redis-cli --hotkeys(Redis 7)发现热点键,对热点键进行专门优化,如二级缓存、本地缓存。

Q10: rejected_connections 指标升高意味着什么?如何排查? 一句话回答:意味着连接数达到 maxclients 限制,新连接被拒绝;排查方向包括连接泄漏、业务连接池配置过大、或 maxclients 设置过低。 详细解释

  • 该指标累计增加,可通过 rate(redis_rejected_connections_total[5m]) 检测当前是否仍在拒绝。
  • 排查:INFO clients 查看 connected_clients,如果接近 maxclients,执行 CLIENT LIST 查看各客户端信息,找出异常多的连接来源(如某个应用服务器连接数远高于其他)。检查是否有连接未正常关闭(TIME_WAIT)。检查 timeout 设置,空闲连接是否及时关闭。
  • 临时解决:CONFIG SET maxclients 提高上限(需保证 ulimit)。根本解决:优化应用连接池(如降低最大连接数、增加等待超时),使用连接池监控。 多角度追问
  • 追问 1:maxclients 受哪些系统参数制约?受限于 ulimit -n(文件描述符限制),实际 maxclients = min(配置值, 系统 fd 限制 - 预留)。
  • 追问 2:如果频繁拒绝连接,但 connected_clients 不高,为什么?可能是连接建立瞬间的尖峰,超过了限制后迅速回落,但仍被拒绝。需调整应用重试策略,平滑启动。
  • 追问 3:如何优雅的杀死部分客户端?CLIENT KILL ADDR ip:port 杀掉异常客户端,但不解决根本问题。 加分回答:配置 min-replicas-to-writemin-replicas-max-lag 可让主节点在从节点不足时拒绝写入,这是一种保护策略,但也会导致 rejected_connections 或写入拒绝,需要区分场景。

Q11: evicted_keys 突然增加可能是什么原因?如何应对? 一句话回答:内存使用达到 maxmemory,Redis 根据淘汰策略逐出键;原因可能是业务量激增、大 Key 写入、内存泄漏或 maxmemory 配置不当;应对包括扩容内存、优化数据模型、调整淘汰策略或切换到 LFU。 详细解释

  • 查看 used_memory 趋势,确认是自然增长还是突增。如果是自然增长,说明容量不足,需水平或垂直扩展。如果是突发,可能是一次性导入了大量数据。
  • 检查 maxmemory-policy,若为 noeviction,则不会驱逐,但写命令会报错,此时 evicted_keys 不会增加。驱逐增加说明策略为 allkeys-lru/lfuvolatile-*
  • 应对:短期内调高 maxmemory(如果机器内存有空闲),或增加分片。长期需优化数据结构,如用 Hash 代替大 String,删除无效数据。 多角度追问
  • 追问 1:LFU 和 LRU 策略下驱逐有何不同?LFU 考虑访问频率,保护高频键,命中率可能更高;LRU 只看最近访问,可能淘汰掉周期性热点键。
  • 追问 2:如何避免驱逐导致雪崩?在应用层增加限流和熔断,使用 Redis 集群时确保所有节点负载均匀。
  • 追问 3:能监控具体被驱逐的键吗?Redis 不提供被驱逐键的列表,但可以通过 SLOWLOG 观察 DEL 命令来部分推断(驱逐可能直接内部删除,不记录慢日志)。 加分回答:利用 redis-cli --hotkeys 识别热点键,在内存紧张时可优先保护热点键或将其放入本地缓存,减少对 Redis 的依赖。结合自动化扩缩容工具,当驱逐速率持续超阈值时自动扩容集群分片。

Q12: (故障排查题)线上 Redis 内存持续增长但 Key 数量并未增加,mem_fragmentation_ratio 达到 3.5,如何诊断根因并给出解决方案? 一句话回答:这通常表明内存碎片严重或存在隐藏内存消耗(如客户端输出缓冲区、复制积压、Lua 脚本缓存等),诊断步骤为:检查 MEMORY STATS 分解碎片来源,用 MEMORY DOCTOR 获取建议,通过 CLIENT LIST 定位输出缓冲区大的客户端,确认后重启进程或主从切换平滑重启。 详细解释

  • 诊断流程
    1. 执行 MEMORY STATS,查看 allocator_frag_ratiorss_overhead_ratio。若 allocator_frag_ratio 很高(>1.5),说明分配器内部碎片严重,往往需重启。若 rss_overhead_ratio 很高(>2.0),则可能是 THP 或 fork 子进程残留。
    2. 执行 MEMORY DOCTOR,它会直接给出碎片率报告和大 Key 警告。
    3. 查看 used_memory_overhead 趋势。若增长主要由 overhead 驱动,检查 mem_clients_normal(客户端输出缓冲区)、mem_replication_backlogmem_aof_buffer 等。用 CLIENT LIST 列出 omem 字段,找出输出缓冲区大的客户端并处理。
    4. 确认 active_defrag_running 状态,如已开启但碎片仍高,可能需要调整阈值或考虑重启。
    5. 如果确认是分配器碎片或 RSS 开销过高,最彻底的方案是重启进程。为不中断服务,可借助 Sentinel 或 Cluster 的故障转移,将当前主节点切为从节点,重启后重新加入。
  • 解决方案:短期,如果因客户端输出缓冲区堆积,可杀死该客户端或调整 client-output-buffer-limit;中期,开启 activedefrag 并调优参数;长期,规划滚动重启,并优化操作系统(关闭 THP,设置 vm.overcommit_memory=1),拆分大 Key。 多角度追问
  • 追问 1:如何安全重启 Redis 实例而不丢数据?确认 RDB + AOF 正常,通过 SHUTDOWN NOSAVESAVE 后重启,或利用主从切换:CLUSTER FAILOVER(集群)或 SENTINEL FAILOVER(哨兵),重启原主后成为从节点。
  • 追问 2:如果客户不允许重启,有什么补救措施?强制开启 activedefrag,并逐步提高其积极性(active-defrag-cycle-min),同时监控 CPU 和延迟,直到碎片率降到可接受范围。
  • 追问 3:重启后碎片率为何仍然偏高?可能是重启后 THP 仍然导致后续 fork 开销,或数据模型本身导致快速产生碎片。需要确保彻底禁用 THP,并优化数据写入模式(如避免短命的大量临时键)。 加分回答:建立完善的容量规划模型,提前预测碎片增长。利用 Prometheus 记录碎片率趋势,设置即将达到 2.0 的预警,自动创建维护工单,编排滚动重启流程,实现无人值守的自愈。

文末速查表:Redis 运维速查

监控核心指标与告警阈值

指标分类关键指标正常基线告警阈值级别
连接connected_clients< maxclients 50%>80% maxclientsP1
连接rejected_connections0>0P1
连接blocked_clients0持续 >10P2
内存mem_fragmentation_ratio1.0 ~ 1.5>2.0P2
内存used_memory/maxmemory<70%>85%P1
内存evicted_keys 速率0>10/sP1
性能keyspace_hits/misses 命中率>95%<85%P2
性能latest_fork_usec<10000>50000P1
主从master_link_statusupdownP0
主从master_last_io_seconds_ago<5>30P1
持久化rdb_last_bgsave_statusokerrP0
持久化aof_last_write_statusokerrP0
集群cluster_stateokfailP0

诊断命令速查

用途命令示例
实时状态概览redis-cli --stat每秒 QPS/内存/客户端
网络延迟redis-cli --latency连续延迟采样
慢查询SLOWLOG GET 10获取 10 条慢命令
延迟诊断LATENCY DOCTOR自动报告
内存碎片诊断MEMORY DOCTOR内存建议
单键内存MEMORY USAGE key精确字节数
大 Key 扫描redis-cli --bigkeys遍历最大键
内存排序扫描redis-cli --memkeys内存占用排序
RDB 离线分析redis-cli --rdb dump.rdb无在线影响
集群检查redis-cli --cluster check集群一致性

常用 PromQL

# QPS
rate(redis_commands_processed_total[1m])

# 命中率
redis_keyspace_hits_total / (redis_keyspace_hits_total + redis_keyspace_misses_total)

# 内存使用率
redis_memory_used_bytes / redis_memory_max_bytes

# 碎片率
redis_mem_fragmentation_ratio

# 连接使用率
redis_connected_clients / redis_config_maxclients

# 驱逐速率
rate(redis_evicted_keys_total[5m])

# 主从断开
redis_master_link_status == 0

延伸阅读

  • 《Redis 设计与实现》运维章节
  • Redis 官方文档 Administration 部分:redis.io/docs/manage…
  • Prometheus 与 Grafana 官方文档

通过本体系的建立,运维工程师能够将 Redis 从黑盒运行变为白盒可观测,为生产环境的稳定性提供坚实保障。后续文章将进一步利用这些监控和诊断能力,深入反模式排查和故障定位。