Redis从库负载高需按顺序排查:先确认slave-read-only是否为yes,再查慢命令(如KEYS、SMEMBERS)、复制中断导致的全量同步、过期键清理及client-output-buffer-limit配置是否合理。

从库负载高,先确认是否被误写入
Redis 从库默认是只读的,但这个只读是软限制——slave-read-only 配置为 yes 时,仅拒绝客户端的写命令(如 SET、DEL),不阻止 Lua 脚本内执行写操作,也不拦截通过 CONFIG SET slave-read-only no 动态关闭只读的误操作。
检查当前从库是否真的只读:
redis-cli -h your-slave-ip -p 6379 CONFIG GET slave-read-only
若返回 ["slave-read-only","no"],立刻修复:
- 临时生效:
CONFIG SET slave-read-only yes - 永久生效:在从库配置文件中确保有
slave-read-only yes,并重启或重载配置(CONFIG REWRITE) - 特别注意:某些旧版 Redis(slave-read-only;5.0+ 改为
replica-read-only,但兼容旧名;若用redis.conf模板自动生成配置,需核对实际加载的配置项名
KEYS * 或类似全量扫描命令正在拖垮从库
从库和主库共享同一套命令执行逻辑,KEYS * 这类命令在从库上执行同样会阻塞主线程,且因从库通常承担读流量,更容易暴露问题。尤其当主库已禁用 KEYS(例如通过 rename-command KEYS ""),但运维或监控脚本仍直连从库执行,就容易漏掉这层风险。
排查方式:
- 在从库上运行
CLIENT LIST,找cmd=keys或cmd=scan且idle值异常大的连接 - 启用慢日志:
CONFIG SET slowlog-log-slower-than 10000(记录 >10ms 的操作),再查SLOWLOG GET 10 - 重点盯
KEYS pattern、SMEMBERS huge-set、HGETALL huge-hash这类 O(N) 命令,它们在大数据量下极易打满 CPU
修复建议:
- 禁用
KEYS:在从库配置中添加rename-command KEYS ""(注意:主从配置可不同,从库单独加更安全) - 改用
SCAN:必须带COUNT参数(如SCAN 0 COUNT 100),避免单次响应过大;注意SCAN不保证一次遍历完,业务需自行处理游标迭代 - 监控侧避免轮询式
KEYS:比如健康检查脚本用PING即可,无需扫 key
从库 CPU 高但没发现明显慢命令?检查复制积压与网络延迟
有时候 INFO replication 显示 master_last_io_seconds_ago 很大(>10),或 repl_backlog_active 为 0,说明复制中断过;恢复时从库可能要重同步(full sync),触发 bgsave + RDB 传输 + 加载,CPU 和磁盘 I/O 会陡增——这阶段看起来像“负载高”,实则不是业务请求导致。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
关键指标检查顺序:
redis-cli INFO replication | grep -E "(role|master_link_status|master_last_io_seconds_ago|repl_backlog_active|connected_slaves)"- 若
master_link_status:down,先看网络(telnet 主库端口)、主库是否 OOM 或夯住 - 若
master_last_io_seconds_ago持续 >30,检查主从间带宽、防火墙、TCP keepalive 是否过短(Linux 默认 2 小时,可能被中间设备断连) - 从库
INFO stats中expired_keys/evicted_keys突增,也可能推高 CPU(过期键清理是惰性+定期混合策略)
只读设置和 KEY 扫描之外,别忽略 client-output-buffer-limit
从库作为读节点,如果挂了大量长连接(比如未正确复用连接的微服务),又恰好有 big value(如大 JSON 字符串、序列化对象),Redis 会把响应暂存在 client output buffer 中。一旦 buffer 超限,Redis 会强制断开连接,同时触发 buffer 回收逻辑,造成 CPU 波动。
检查当前设置:
CONFIG GET client-output-buffer-limit
典型返回:["client-output-buffer-limit","normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60"]
重点关注 slave 行第三列(硬限制超时秒数)和第二列(软限制字节数):
- 若从库读请求返回数据普遍 >64MB,考虑调大第二列(如
536870912= 512MB),但需评估内存余量 - 第三列 60 秒太短,高延迟链路下易误杀;设为 300 更稳妥
- 修改后需
CONFIG REWRITE持久化,否则重启丢失
真正难定位的是:这些 buffer 压力不体现在 INFO clients 的 client_longest_output_list 上,而藏在 client_biggest_input_buf 和 blocked_clients 里——后者为 0 不代表安全,buffer 溢出是瞬时事件,得靠 MONITOR 或 redis-cli --latency 配合抓包确认。

















