本文从系统部署维护视角梳理 Redis 缓存服务常见故障类型、排查步骤、证据保留方法及长期治理策略,帮助开发与运维团队建立可复用的故障响应流程。

软件定制开发团队
"真正有价值的技术内容,应该能帮助客户更快判断方向、预算和落地路径。"
排查任何 Redis 故障之前,必须知道“正常是什么样子”。没有基线就谈不上异常。
基线数据至少包含以下三项:
如果 Redis 实例运行在云托管服务(如阿里云、腾讯云、AWS ElastiCache),还需记录连接数限制、最大内存策略(maxmemory-policy)等配置快照。
没有基线时,排查只能依赖经验猜测,效率低下且容易误判。
应用日志中出现“connection timeout”“max number of clients reached”“Cannot connect to Redis”等错误。监控面板显示连接数达到上限(默认 10000,可通过 maxclients 配置修改)。
1. 检查当前连接数:`INFO clients` 输出中的 connected_clients 字段。
2. 对比 maxclients 配置:`CONFIG GET maxclients`。如果 connected_clients 已接近或等于 maxclients,说明连接池耗尽。
3. 检查是否存在连接泄漏:查看应用端的连接池配置,确认是否在每次操作后归还连接。常见错误是使用了短连接或未正确关闭连接池。
4. 检查是否遭受恶意攻击或爬虫:通过 `CLIENT LIST` 查看所有连接来源 IP,如果某个 IP 的连接数异常高,考虑防火墙限流。
连接数耗尽通常发生在以下条件下:
临时增加 maxclients(例如 `CONFIG SET maxclients 20000`),同时重启应用端连接池。但注意:maxclients 不能超过操作系统允许的最大文件句柄数(`ulimit -n`)。永久修复需要调整应用端连接池策略并增加监控告警。
业务响应时间从 1-2 ms 突然上升到 50-200 ms,甚至超时。Redis 监控面板显示延迟曲线陡增。
1. 启用慢查询日志:设置 `SLOWLOG GET 100` 查看最近 100 条慢查询。默认慢查询阈值是 10 ms(可通过 slowlog-log-slower-than 调整)。
2. 分析慢查询命令类型:常见慢命令包括 KEYS、SMEMBERS、HGETALL、ZRANGE(未加 LIMIT)、大量数据的 SORT 等。KEYS 命令在百万级 key 规模下会导致 Redis 阻塞数秒。
3. 检查是否存在大 key:使用 `MEMORY USAGE key` 或 `DEBUG OBJECT key` 估算单个 key 的内存占用。大 key 通常指单个 key 占用超过 10 MB 或包含超过 1 万个元素。大 key 的删除操作(DEL)也会阻塞主线程。
4. 检查是否触发了持久化操作:如果启用 AOF 持久化且设置 `appendfsync always`,每次写入都会同步磁盘,性能会显著下降。`appendfsync everysec` 是多数生产环境的推荐值。
5. 检查网络带宽:使用 `INFO STATS` 观察 instantaneous_input_kbps 和 instantaneous_output_kbps,如果接近网络接口上限,延迟也会上升。
慢查询的核心原因是 Redis 是单线程处理命令。任何耗时超过几毫秒的命令都会阻塞后续所有请求。大 key 的读写、全量扫描命令、频繁的持久化同步是主要诱因。
Redis 日志中出现“OOM command not allowed when used memory > 'maxmemory'”错误。或者,业务发现部分缓存数据突然消失,命中率骤降。
1. 检查当前内存使用:`INFO MEMORY` 中的 used_memory_human 和 maxmemory_human。
2. 确认淘汰策略:`CONFIG GET maxmemory-policy`。默认策略是 noeviction,即内存写满后拒绝写入。其他策略包括 allkeys-lru、allkeys-lfu、volatile-lru、volatile-ttl 等。
3. 分析内存占用分布:使用 `MEMORY STATS` 或第三方工具(如 redis-rdb-tools)分析 RDB 文件,找出占用内存最多的 key 类型和 key 前缀。
4. 检查是否有未设置过期时间的 key 持续增长。如果策略是 volatile-lru,只有设置了过期时间的 key 才会被淘汰,未设过期时间的 key 会永久占用内存。
内存溢出通常发生在以下场景:
读操作从从库获取到过期数据或与主库数据不一致。监控显示从库的 repl_backlog_histlen 持续增长,或 master_repl_offset 与 slave_repl_offset 差距过大。
1. 检查主从复制状态:`INFO REPLICATION` 中的 master_link_status、slave_lag(单位秒)、master_repl_offset 和 slave_repl_offset。
2. 确认从库是否处于同步中:如果 master_link_status 为 down,说明复制链路断开。常见原因包括网络抖动、主库内存不足触发 OOM killer、主库重启。
3. 检查复制积压缓冲区大小:`CONFIG GET repl-backlog-size`。默认 1 MB,如果主库写入量较大且从库延迟时间较长,积压缓冲区可能被覆盖,导致从库需要全量重同步。
4. 检查从库是否启用了读写分离且读取过期数据:Redis 默认不会主动删除过期 key,而是在访问时惰性删除。从库可能返回已过期但尚未被删除的数据。需要确认业务是否依赖从库读取实时数据。
主从延迟在以下条件下更容易发生:
Redis 重启后部分数据丢失,或 AOF 文件损坏导致无法启动。
1. 检查持久化配置:`CONFIG GET save`(RDB 触发条件)、`CONFIG GET appendonly`(是否开启 AOF)、`CONFIG GET appendfsync`(AOF 同步策略)。
2. 查看日志:检查 Redis 日志中是否有“Can't save in background: fork: Cannot allocate memory”或“AOF: rewrite failed”等错误。
3. 检查磁盘空间:`INFO PERSISTENCE` 中的 rdb_last_bgsave_status 和 aof_last_rewrite_status。如果磁盘空间不足,RDB 或 AOF 写入会失败。
4. 检查系统内存:RDB 持久化时 Redis 会 fork 子进程,如果系统内存不足,fork 可能失败。建议预留至少 1-2 GB 空闲内存,或启用 overcommit_memory(`sysctl vm.overcommit_memory=1`)。
数据丢失通常发生在以下情况:
故障发生时,不要急于重启或恢复。先保留以下证据,否则可能丢失定位线索:
保留证据后,再执行重启或切换操作。
基于上述故障类型,整理一份可定期执行的维护清单,降低故障发生概率。
单次排查只能解决眼前问题,长期治理需要建立制度化的流程。
首先,建立故障分类标签库。将每次故障按类型(连接、内存、延迟、持久化、复制)和严重等级(P0-P3)记录,积累足够样本后,可以发现系统薄弱环节。例如,如果每月都出现连接数耗尽,说明连接池配置或容量规划存在系统性问题。
其次,制定标准操作手册(SOP)。对每种故障类型,编写清晰的排查步骤、恢复命令和验证方法。SOP 应包含回退方案,即恢复操作失败后的备选计划。例如,主从延迟的 SOP 中,如果调整 repl-backlog-size 无效,下一步是检查主库的写入源是否存在异常流量。
最后,定期进行故障演练。每季度至少一次,在预发环境模拟 Redis 故障(如模拟主库宕机、模拟内存写满),验证 SOP 的有效性和团队的响应速度。演练后形成改进项,持续更新 SOP。
在 SystemDo 参与过的多个企业项目中,我们发现:故障排查效率最高的团队,不是技术最强的团队,而是证据保留最完整的团队。每次故障后,花 15 分钟整理一份“故障复盘+证据归档”,长期坚持下来,多数常见故障都能在 10 分钟内定位根因。
Redis 缓存服务的故障排查,核心在于三点:有基线、留证据、建流程。没有基线就无法判断异常程度;不留证据就会丢失关键线索;不建流程就只能每次从零开始。
上述故障类型和排查顺序,覆盖了生产环境中 90% 以上的 Redis 问题。但需要强调的是,每套系统的业务模型、数据规模、部署架构都不同,本文提供的排查步骤需要结合自身环境调整。例如,一个每秒处理 10 万次写入的金融系统,其故障排查的重点和优先级与一个日均请求量不足 1 万的内部管理系统完全不同。
最后,如果团队缺乏专职运维人员,建议优先使用云托管的 Redis 服务(如阿里云 Redis、AWS ElastiCache),其自动故障转移、自动备份、监控告警功能可以大幅降低运维负担。自建 Redis 虽然成本更低,但需要投入足够的运维资源,否则故障恢复时间可能远超预期。
继续了解企业数字化、SEO / GEO、AI 自动化和软件定制开发中的常见问题。