Redis 延迟排查与优化全攻略

1 延迟基线:先弄清"天花板"

1.1 内在延迟(intrinsic latency)

同一台机器上任何进程均无法突破的调度极限,可用 redis-cli --intrinsic-latency 测试:

bash 复制代码
redis-cli --intrinsic-latency 100   # 100 秒采样
  • 物理机:常见 50 µs -- 200 µs。
  • 虚拟机 / 容器:受宿主机、超分、邻居噪声影响,可高达 10 ms 以上。
  • 基线即上限:应用层任何优化都无法优于此。

1.2 网络通信延迟

场景 单次 RTT
本机 Unix Socket ~30 µs
千兆局域网 ~200 µs
跨可用区 / 公网 1 ms -- 几十 ms

2 高频排障清单(5 分钟速查版)

步骤 命令 / 操作 重点
① 慢日志 SLOWLOG get 10 是否有 > 1 ms 的命令?
② 延迟监控 LATENCY DOCTOR 哪些 event 触发?持续多久?
③ 内核配置 关闭 Transparent Huge Pages echo never > /sys/.../transparent_hugepage/enabled
④ AOF 策略 appendfsync everysec 是否足够 避免 always 带来的 fsync 堵塞
⑤ 虚拟化平台 EC2 请选择 HVM m6i/m5/m6g 以上 旧版 Xen fork 太慢
--intrinsic-latency > 5 ms?考虑宿主机抖动 / 噪声邻居
⑦ 复核 maxmemory 是否触发 swap / oom_killer

3 延迟来源全景图

graph TD subgraph 内部 A[慢命令
O(N)] --> L1 B[fork
BGSAVE/AOF] --> L2 C[AOF 写盘
fsync] --> L2 D[大批量 expire
主动清理] --> L3 end subgraph 系统 E[内核调度
抢占] --> L0 F[THP / COW] --> L2 G[Swap I/O] --> L3 end subgraph 外部 H[网络 RTT] --> L0 I[客户端
序列化/阻塞] --> L0 end
  • L0:亚毫秒抖动 --- 常规基线。
  • L1:单条慢命令堵塞事件循环。
  • L2 :Redis 主线程被 fork / fsync / COW 暂停。
  • L3:内核级 I/O、Swap 或批量过期导致秒级停顿。

4 监测与定位

4.1 Slow Log -- 捕获单条慢命令

bash 复制代码
CONFIG SET slowlog-log-slower-than 1000   # ≥1ms 记录
SLOWLOG GET 20
  • 重复出现 SORT, ZUNION, KEYS 等 O(N) 命令应警惕。
  • 查询、比对业务代码,必要时用 Lua / Stream 重构。

4.2 Latency Monitor -- 事件级分析

bash 复制代码
CONFIG SET latency-monitor-threshold 200
LATENCY DOCTOR        # 概览
LATENCY GRAPH fork    # 查看 fork 延迟趋势
  • 关注常见 event:command, fork, aof-fsync, expire-cycle

4.3 系统级工具

工具 观察指标
vmstat 1 si/so 是否持续非 0(swap)
iostat -x 1 await, %util 高?磁盘拥堵
strace -p $PID -T -e trace=write,fdatasync 哪些 fsync 阻塞

5 典型场景深度剖析

5.1 慢命令阻塞

  • KEYS、SMEMBERS、SUNION 等,避免在生产使用 ;改用 SCAN 家族增量遍历。
  • 大集合运算需在 Replica 执行或迁往离线任务。

5.2 fork 带来的「瞬时卡顿」

  • 触发时机:BGSAVE, BGREWRITEAOF, MEMORY PURGE

  • 复制页表是瓶颈:24 GB 实例约 48 MB 页表。

  • 优化手段

    • 使用 HVM + 新一代云主机 / 物理机。
    • 降低备份频率;外部持久化(如 rdb snapshot in replica)分摊 IO。
    • 大实例(> 64 GB)用 diskless replication 减少磁盘 IO。

5.3 AOF fsync 阻塞

appendfsync 延迟风险 适用场景
always 高,高速盘必备 金融级强一致
everysec 中(可忍受) 通用推荐
no + RAID/UPS 延迟敏感 & 有其他持久化
  • 勾选 no-appendfsync-on-rewrite yes,后台重写期间只写不 fsync。
  • 核心业务最好用独立 SSD,避免与数据库 / 日志混用。

5.4 Swap & 内存抖动

  • grep Swap /proc/$pid/smaps | awk '{s+=$2} END {print s/1024 " MB"}'

    检查 Redis 进程已换出量。

  • 若 swap > 100 MB:

    • 提升 vm.swappiness=0,或直接 sudo swapoff -a
    • 降低 maxmemory 或下线其他占内存服务。

5.5 大量 key 同时过期

  • 主动过期算法每 100 ms 采样 20 个 key,若 25% 过期则循环。

  • 场景:海量秒杀 coupon、会话一次性设置同一 EXPIREAT

  • 解决:

    • 将时间戳随机 + - 60 s 打散;
    • 批量存到 Sorted-Set TTL Wheel,定时 Lua 扫描。

6 生产环境调优建议

类别 建议
系统 关闭 THP;nofile ≥ 65535;物理机 CPU performance governor
Redis 配置 latency-monitor-threshold 200;禁用 save 或错峰快照
客户端 使用 连接池 + Pipeline;跨区走腾讯云内网或 AWS Global Accelerator
运维 定期收集 SLOWLOG LENLATENCY LATESTfork/used_cpu_sys_children
容灾 母机宕机延迟 > 基线 ×10;双 AZ master-replica + Sentinel 自动切换

7 总结

  1. 先测基线--intrinsic-latency 了解物理/虚拟机极限。
  2. 定位热点:Slow Log + Latency Monitor 快速锁定事件。
  3. 分层治理:命令层、持久化层、操作系统层各有对策。
  4. 以闲养忙:独占 SSD、错峰慢操作、随机化大量过期。
  5. 持续观测:关键指标告警 + 业务 P99 延迟回溯。

做到以上,即可让 Redis 处理路径保持 微秒级稳定,轻松应对高并发与突发流量。愿你的 QPS 再高,延迟依旧顺滑如丝!

相关推荐
wertyuytrewm9 小时前
自动化与脚本
jvm·数据库·python
Lyyaoo.9 小时前
Spring Boot日志
spring boot·缓存·单元测试
Hello.Reader9 小时前
PySpark DataFrame 快速入门创建、查询、分组、读写、SQL 实战一篇讲透
数据库·sql·spark
无籽西瓜a9 小时前
Docker 环境下 Redis Lua 脚本部署与执行
redis·docker·lua
qq_417695059 小时前
Python深度学习入门:TensorFlow 2.0/Keras实战
jvm·数据库·python
疯狂成瘾者9 小时前
Redis 实用学习清单
redis·学习
只能是遇见10 小时前
ERROR 1524 (HY000) Plugin ‘mysql_native_password‘ is not loaded
android·数据库·mysql
七夜zippoe10 小时前
消息队列选型:Kafka vs RabbitMQ vs Redis 深度对比
redis·python·kafka·消息队列·rabbitmq
番茄去哪了10 小时前
从0到1独立开发一个论坛项目(一)
java·数据库·oracle·maven
API开发10 小时前
一个MCP操作所有的数据库
数据库·api·api接口·apisql·mcp·mcpserver·openclaw