高级篇 08. Redis 最佳实践 - 服务端优化之慢查询排查

4 阅读5分钟

📚 高级篇 08. Redis 最佳实践 - 服务端优化之慢查询排查

一、 核心预警:为什么 Redis 的慢查询极其致命?

如果你之前是搞 MySQL 的,你可能会觉得:“一条慢 SQL 跑个 1 秒钟,虽然慢,但顶多就是这个用户的页面转圈圈嘛,其他用户不受影响。”

💥 认知颠覆:Redis 的 1 秒钟,是地狱级的灾难!

因为 Redis 执行命令的核心逻辑是绝对单线程的。

这意味着如果有一条命令执行了 1 秒钟,那么在这 1 秒内,整个 Redis 服务器完全停止了对外部的响应。全网数以万计的其他用户请求,只能在网络缓冲区里苦苦排队,最终引发大面积的超时报错。

界限定义: 在 MySQL 里,执行超过 1 秒算慢查询;但在纯内存操作的 Redis 里,执行超过 10 毫秒(甚至在极高并发下超过 1 毫秒),就已经是不折不扣的慢查询了!


二、 布下天罗地网:如何配置慢查询日志?

Redis 自带了一个极度好用的内存日志系统——Slow Log。它专门用来记录那些执行时间超标的命令。

打开你的 redis.conf 配置文件,找到以下两个极其关键的参数:

1. slowlog-log-slower-than (执行时间阈值)

  • 含义: 告诉 Redis,执行时间超过多少微秒 (microseconds) 的命令要被记录下来。(1 秒 = 1000 毫秒 = 1000,000 微秒)
  • 默认值: 10000(即 10 毫秒)。
  • 🌟 大厂实战推荐: 在高并发的互联网电商架构中,10 毫秒太长了!我们通常会把它调整为 1000(即 1 毫秒),严密监控任何微小的卡顿。

2. slowlog-max-len (日志队列长度)

  • 含义: 慢查询日志是保存在 Redis 内存中的一个先进先出 (FIFO) 队列,不是写在硬盘上的!这个参数控制队列最多能存多少条记录。
  • 默认值: 128。
  • 🌟 大厂实战推荐: 128 很容易被一波突发的流量冲刷掉(旧日志会被新日志挤出去,导致你案发后上去查,发现证据都没了)。建议配置为 1000 左右,占用不了几 KB 内存,但能保留足够的“犯罪现场”。

(如果你不想重启服务器,可以直接在客户端动态修改配置:CONFIG SET slowlog-log-slower-than 1000)


三、 抓捕归案:排查慢查询的核心命令

当线上出现卡顿预警时,立刻连上 Redis 客户端,敲下你的神探指令:

1. 查看慢查询日志:SLOWLOG GET [n]

这是最常用的命令,用来获取最近的 n 条慢查询记录。不加 n 则默认拉取最近 10 条。

Bash

127.0.0.1:6379> SLOWLOG GET 2
1) 1) (integer) 14               # 1. 日志的唯一递增 ID
   2) (integer) 1682345678       # 2. 命令执行时的 Unix 时间戳 (案发时间)
   3) (integer) 15432            # 3. 命令真正的执行耗时:15432 微秒 (约 15 毫秒)
   4) 1) "HGETALL"               # 4. 执行的具体命令和参数 (罪魁祸首)
      2) "heima:user:bad_hash"
   5) "192.168.1.102:54321"      # 5. 发送该命令的客户端 IP 和端口 (揪出猪队友)
   6) ""                         # 6. 客户端名称 (如果有设置的话)

(通过上面的结果,你瞬间就能定位到:是哪台服务器上的代码,在什么时间,执行了哪个耗时 15 毫秒的命令!)

2. 查看日志队列长度:SLOWLOG LEN

看看当前内存里存了多少条慢查询记录。

3. 清空日志队列:SLOWLOG RESET

当你排查完一波问题并修复后,可以清空队列,方便下次观察。


四、 面试高频杀招:慢查询的“四大元凶”及破解之道

面试官极其喜欢问:“你在项目中遇到过慢查询吗?一般是什么原因造成的?怎么优化的?”

💡 满分防身话术(四大元凶):

  1. 元凶一:在生产环境执行了全量扫描命令 (KEYS *)

    • 危害: 这是绝对的死刑!KEYS * 会在一瞬间遍历整个内存里所有的 Key,极其耗时。
    • 破解: 严禁在代码中使用。如果非要模糊搜索,必须使用 SCAN 命令进行游标分页渐进式扫描。
  2. 元凶二:对 BigKey 进行了全量提取 (HGETALL, SMEMBERS)

    • 危害: 假设 Hash 表里有 1 万个字段,HGETALL 会一次性把这 1 万个字段全读出来,不仅阻塞 CPU,还会撑爆网络带宽。
    • 破解: 尽量只获取需要的字段 (HMGET);如果非要全拿,同样使用 HSCAN / SSCAN 分批读取。
  3. 元凶三:极其复杂的集合运算 (SINTER, SUNION, ZUNIONSTORE)

    • 危害: 对两个包含几十万元素的 Set 求交集,算法复杂度极高,是名副其实的 CPU 杀手。
    • 破解: 绝对不要在接收前端高并发请求的主流程中做这种运算。应该把这种运算放到后台的定时任务中,或者干脆把数据拉回 Java 内存里去算。
  4. 元凶四:过大的 Pipeline 批处理

    • 危害: 之前学过,一次性打包 10 万条命令进 Pipeline,服务端也要花时间去全部执行完才能响应。
    • 破解: 将大的 Pipeline 拆分成每批 500~1000 条的小 Pipeline 循环发送。

学习总结

这节课,你掌握了 Redis 运维排查中最锋利的一把手术刀——Slow Log

从配置微秒级的报警阈值,到通过 SLOWLOG GET 还原案发现场,再到精准打击导致慢查询的四大元凶代码。这就是大厂高级研发工程师日常排查线上问题的标准 SOP(标准作业程序)。