← [ BACK_TO_NOTES ]

BodySense Redis 第 11 课:Operations 与 Observability

学习 Redis INFO、SLOWLOG、MEMORY、LATENCY、SCAN 与关键运行指标,并把 BodySense 的认证状态、连接池、持久化和缓存观测收敛成可运维的健康模型。

#course #growing #backend #ops #redis #bodysense

[!info] related notes

BodySense Redis 第 11 课:Operations 与 Observability

[!abstract] 学习目标 从“会用 Redis 命令”提升到“知道 Redis 在生产中现在是否健康、哪里慢、是否正在丢状态”。

先从零解释:Operations、Monitoring、Observability 分别是什么

这一课不再主要问“Redis 命令怎么写”,而是问:

系统已经跑在生产里了,我怎么知道它现在健康不健康、哪里开始变慢、故障到底发生在哪一层?

Operations / 运维

广义上是让 Redis 在真实环境中持续可用:

配置
部署
容量
升级
备份/恢复
故障处理
安全
监控

Monitoring / 监控

监控更像:

提前选好一组指标,然后持续观察这些指标是否越过阈值。

例如:

used_memory > 80%
evicted_keys increases
connected_clients > threshold
Redis command p99 > 20ms

Observability / 可观测性

可观测性更强调:

当你事先不知道故障是什么时,系统是否提供足够的内部信号,让你从外部行为反推出内部状态。

常见信号:

Metrics
Logs
Traces
Profiles / runtime introspection

Redis 自身提供 INFO / SLOWLOG / LATENCY / MEMORY / CLIENT 等 introspection;应用侧还要记录 Redis operation latency、error classification、request trace。

所以:

Redis PING = OK

只是一个非常窄的信号,绝不能代表“生产 Redis 健康”。

先学一个排障原则:从用户症状向下收集证据

假设:

Login API p95
100 ms → 2 s

不要第一步就:

重启 Redis

而应该逐层问:

1. HTTP request 到底慢在哪个 span?
2. Redis operation 本身慢,还是在等 client pool?
3. Redis server 是否有 slow command / latency spike?
4. memory / eviction / persistence 是否异常?
5. network / DNS / TLS 是否异常?

这个思路叫 evidence-driven diagnosis:先区分假设,再修复。

基础诊断命令

INFO
CLIENT LIST
SLOWLOG
MEMORY
LATENCY
SCAN
DBSIZE

每个命令回答的问题不同。

INFO:Redis Server 的“体检总表”

INFO 返回 Redis Server 的运行信息和统计。

可以直接:

INFO

也可以只看某一类:

INFO memory
INFO clients
INFO persistence
INFO stats
INFO replication
INFO keyspace
INFO commandstats
INFO latencystats

当前官方文档还包含 errorstats、keysizes、hotkeys 等 section;不同版本/发行形态可能有差异,因此生产排查先确认实际 Redis 版本。

为什么不要一上来 INFO all 然后盯着一大屏数字

因为指标必须对应一个问题。

例如“登录延迟变高”:

clients
→ 是否连接数量/拒绝连接异常?

memory
→ 是否接近上限、RSS/fragmentation 异常?

commandstats / latencystats
→ 哪类命令 CPU/latency 上升?

persistence
→ AOF rewrite / fork 是否发生?

只有带着假设看指标,数字才有意义。

关键指标

used_memory

Redis 自己统计的分配内存。

used_memory_rss

操作系统层面 Redis 进程实际 RSS。

两者差距很大时,需要考虑:

  • allocator;
  • fragmentation;
  • fork / copy-on-write;
  • 操作系统内存行为。

connected_clients

当前客户端连接。

突然升高可能意味着:

  • connection leak;
  • pool 配置异常;
  • 流量增长;
  • retry storm。

rejected_connections

连接因资源限制被拒绝。

增长时属于明显可用性信号。

blocked_clients

存在阻塞等待的客户端。

需要结合使用的 blocking command / workload 判断。

expired_keys

业务 TTL 到期

通常可以正常增长。

evicted_keys

Redis 因 memory policy 淘汰 Key

对于 BodySense 当前承载认证 authority 的实例:

长期关键 invariant:evicted_keys 应保持 0。

keyspace_hits / keyspace_misses

对于 Cache 可以推导 hit ratio。

但对 Session authority:

miss

可能表示正常过期、Logout、无效 Token,而不是“缓存性能差”。

指标含义必须结合 Key 类型。

instantaneous_ops_per_sec

观察当前命令吞吐。

不能只用它评价健康,还要同时看:

  • latency;
  • CPU;
  • network;
  • error rate。

SLOWLOG:记录“Redis 自己执行得慢”的命令

SLOWLOG 是 Redis 内置的慢命令日志。

最重要的边界:

Slow Log 统计的是 Redis 执行命令所花的时间,不包含客户端网络 I/O。

所以:

Application sees 500ms
SLOWLOG sees 1ms

可能意味着:

network
client pool wait
TLS
application scheduling
连接建立

而不是 Redis command CPU 本身慢。

查看:

SLOWLOG GET 20
SLOWLOG LEN

Redis 通过配置阈值决定多慢才进入 slowlog,并限制保存条数。

什么命令容易慢

不应只背某几个命令,而要看两个因素:

command algorithmic complexity
+
这个 Key / collection 到底有多大

例如:

对一个 5-member Set 做 SMEMBERS
→ 很轻

对一个几百万成员的大 Set 做全量操作
→ 可能很重

Lua 同理:脚本本身是原子执行,如果内部做巨大循环,就会把其他请求一起挡住。

因此排障时要把:

SLOWLOG
+ Big Key
+ command complexity

一起看。

MEMORY:到底是“数据多”,还是内存组织出了问题

常用:

MEMORY STATS
MEMORY USAGE some:key
MEMORY DOCTOR

used_memory 与 used_memory_rss

used_memory 可以粗略理解为 Redis allocator 认为当前分配给 Redis 数据结构等的内存。

used_memory_rss 是操作系统视角下 Redis 进程实际驻留的物理内存。

如果:

RSS >> used_memory

可能涉及 allocator fragmentation、历史峰值后未返还给 OS、fork/copy-on-write 等。

如果:

used_memory >> RSS

官方文档提示可能有一部分 Redis 内存被操作系统 swap 出去,这通常会带来显著延迟风险。

为什么删除很多 Key 后 RSS 不一定马上下降

Redis 释放对象后,内存先还给 allocator;allocator 不一定立刻把 page 还给操作系统。

所以:

used_memory ↓
RSS 仍然高

不自动等于“Redis memory leak”。

需要结合:

used_memory_peak
allocator fragmentation
实际 key count
长时间趋势

判断。

Big Key 是什么

Big Key 不是只有“Value 超过某个固定 MB”才算。

它更像:

一个 Key 的大小/成员数已经让单次读取、遍历、删除、复制、迁移或持久化形成明显延迟/资源风险。

例如:

一个 String 50 MB
一个 Set 300 万 members
一个 Hash 200 万 fields

风险形态不同,但都可能是 Big Key。

Hot Key 又是什么

Hot Key 不是“大”,而是访问特别集中。

key 很小
但每秒 100k 次 GET

也可能成为 CPU/network/shard 单点热点。

因此:

Big Key = size / operation cost 问题
Hot Key = traffic concentration 问题

两者可能重合,也可能完全不同。

LATENCY:观察 Redis Server 内部出现过哪些延迟尖峰

Redis 有 Latency Monitoring Framework。

例如:

LATENCY LATEST

可以看到最近记录的 latency event、发生时间、最近延迟和实例启动以来的最大值。

它和 SLOWLOG 不是一回事:

SLOWLOG
→ 具体哪条 command 执行时间超过阈值

LATENCY
→ Redis 内部某类 latency event / spike

潜在来源可能包括:

slow command
fork
persistence
CPU scheduling
storage
memory pressure

所以“某条 API 慢”不能只看一个工具,要把 server latency event 与应用 trace 对齐时间。

SCAN vs KEYS:遍历 Keyspace 也有执行模型

KEYS pattern 的危险不是“这个命令被官方讨厌”,而是它尝试一次性遍历匹配整个 keyspace。

当数据很多时:

KEYS *
→ 长时间占用命令执行路径
→ 其他请求等待

Redis 官方延迟排障文档明确建议生产环境避免把 KEYS 当常规遍历工具。

SCAN 是 cursor-based incremental iteration

开始:

SCAN 0 MATCH 'session:*' COUNT 100

Redis 返回:

next cursor
+
这一批 keys

下一轮:

SCAN <next-cursor> MATCH 'session:*' COUNT 100

直到 cursor 再次返回 0,完成一次 full iteration。

COUNT 是 Hint,不是严格 page size

COUNT 100

不保证“每次一定返回 100 个”。Redis 官方文档明确把它定义成工作量提示;一次可能返回更少、更多,甚至 0 个。

SCAN 也不是 Snapshot

遍历期间 keyspace 可能在变化。

官方语义允许:

  • 某些元素重复返回;
  • 在遍历期间忽隐忽现的元素结果不确定。

所以应用使用 SCAN 时要能处理重复,并且不要把它当作一致性快照查询。

为什么它仍不应该成为业务查询方式

假设需求:

找 user 42 的所有 Session。

错误思路:

SCAN all session:*
→ GET each
→ parse user
→ filter user 42

正确建模更像:

user_sessions:42
→ direct Set index

SCAN 是运维/维护遍历工具,不是“Redis 没 SQL,所以业务查询就全库扫”。

MONITOR 的风险

MONITOR 可以看到服务器执行的大量命令,对排查非常直观。

但生产常驻风险包括:

  • 性能开销;
  • 巨量输出;
  • 可能暴露敏感命令参数。

因此:

不把 MONITOR 当长期 observability 方案。

Client Policy:Redis Server 健康,Client 也可能把自己拖死

应用并不是“每次命令都临时建 TCP 连接”。Redis 客户端通常维护连接池/复用连接。

因此客户端本身也有容量与失败策略:

Dial / Connect timeout
Read timeout
Write timeout
Pool size
Pool wait timeout
Idle connections
Retries
Reconnect / backoff
TLS

Timeout 为什么必须是有界的

Auth Redis 如果慢 30 秒,而 HTTP request 也一直等 30 秒:

request goroutines pile up
connections stay occupied
upstream retries
more traffic
→ cascading failure

所以安全关键依赖不是“等得越久越可靠”。

目标是:

在一个明确时间预算内
成功获得可信结果
或者
明确失败并执行 failure policy

Retry 为什么可能把故障放大

假设 Redis 已经过载:

1000 failed requests
× each retry 5 times
= up to 5000 extra attempts

这叫 retry amplification / retry storm。

好的 retry 通常需要:

bounded attempt count
backoff
jitter
only retry transient errors
respect request deadline
operation retry must be safe/idempotent

后面第 12 课会把它放进 Failure Engineering。

BodySense 当前代码要区分“现在是什么”和“未来该补什么”

当前 apps/api/internal/database/redis.go 显式设置的是:

Addr
Password
DB
optional TLS
startup PING

它目前没有在这里显式配置完整的 Dial/Read/Write timeout、PoolSize、MaxRetries 等策略。

所以课程列出这些参数时,含义是:

生产审计应该显式评估这些 client policy;不是声称当前 BodySense 已经全部配置完成。

Redis Health 不等于 PING

PING → PONG

只证明最基础连接可用。

生产健康还包括:

latency
memory headroom
eviction
persistence status
connection pool
command errors
replication/failover
hot key / big key

BodySense 推荐观测

Auth

session lookup latency
session lookup error
refresh rotation success/error
refresh replay detected
rate-limit decision
Redis auth dependency unavailable

Cache

hit
miss
fill latency
fallback count
invalidation
stampede suppression

Notification

publish error
subscribe reconnect
fallback reconciliation count

Prediction

[!question]

  1. expired_keys 很高是否一定是故障?
  2. evicted_keys 在 BodySense Auth Redis 增长意味着什么?
  3. 为什么 Cache miss rate 和 Session miss rate 不能用同一语义解读?
  4. 为什么 SCAN 不应该替代业务 secondary index?
  5. PING 正常但 p95 Redis latency 已经极高,能否说 Redis “健康”?

[!success]- Answer / 解析 1. expired_keys 很高是否一定是故障?
不一定。大量验证码、Session、Rate Limit counter 正常 TTL 到期,本来就会推动 expired_keys 增长。要结合业务创建速率、TTL 分布和异常变化趋势判断。

2. evicted_keys 在 BodySense Auth Redis 增长意味着什么?
表示 Redis 正因内存压力提前淘汰 Key。若其中包含 Session / Refresh / security rate-limit 状态,就可能造成提前掉登录、授权状态丢失或安全窗口重置,因此对 critical Auth Redis 是高优先级告警。

3. Cache miss rate 与 Session miss rate 为什么不能同义解释?
Cache miss 主要描述缓存命中效率;Session miss 可能是正常 Logout、TTL 到期、无效 Token 或撤销结果,是认证业务语义。把 Session miss 当“缓存命中率差”会得出错误优化方向。

4. 为什么 SCAN 不应该替代业务 secondary index?
SCAN 是渐进遍历 Keyspace 的运维工具,不提供针对业务查询的稳定数据模型。每次为了“找某用户的 Session”去遍历整个 Keyspace,复杂度和延迟都随总 Key 数增长;更合理的是维护 user_sessions: 这样的专用索引。

5. PING 正常但 p95 Redis latency 很高,Redis 能算健康吗?
不能。PING 只证明基础连接和最简单命令还能返回。生产健康还包括业务命令延迟、pool 等待、memory headroom、eviction、slowlog、persistence、network 等。如果用户请求已经受到明显延迟影响,系统就不是健康状态。

Lab

redis-cli INFO
redis-cli SLOWLOG GET
redis-cli MEMORY STATS
redis-cli LATENCY LATEST
redis-cli SCAN 0 MATCH 'session:*' COUNT 100

同时从 BodySense 侧记录:

request latency
Redis operation latency
error classification
user-visible HTTP result

把“Redis 内部指标”与“用户请求结果”关联起来。

L4 Gate

给出一次事故:

登录 API p95 突然从 100ms → 2s
Redis PING still OK

能够提出有顺序的证据收集:

application error/latency
→ Redis op latency
→ pool saturation
→ slowlog/latency
→ memory/eviction
→ persistence/fork
→ network

而不是直接“重启 Redis”。

创建于 2026/9/18 更新于 2026/9/18
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本