Redis作为高性能的内存数据库,广泛应用于缓存、队列、实时统计等场景。但在实际使用中,开发者和运维人员常会遇到性能下降、内存溢出、主从同步失败等问题。本文将针对高频问题进行详细分析,并提供对应的解决方案和预防措施,助你快速定位并解决Redis疑难杂症。
一、内存使用过高,触发OOM(Out Of Memory)
现象:
-
客户端收到
OOM command not allowed
错误。 -
info memory
显示used_memory
接近或超过maxmemory
配置。
原因分析:
-
数据量过大,未合理设置过期时间或淘汰策略。
-
内存碎片率过高(
mem_fragmentation_ratio
> 1.5)。 -
大Key(如单个String值超过10MB)或大量Key集中过期。
解决方案:
-
设置内存淘汰策略:
# 修改redis.conf,设置最大内存及淘汰策略(推荐allkeys-lru或volatile-lru) maxmemory 4gb maxmemory-policy allkeys-lru
-
拆分大Key:将大Hash拆分为多个小Key,或使用
HSCAN
分批处理。 -
优化过期策略:避免大批量Key同时过期,可添加随机过期时间偏移。
预防措施:
-
监控
used_memory
和mem_fragmentation_ratio
,使用redis-cli --bigkeys
定期扫描大Key。 -
业务层增加数据压缩(如Snappy)或使用更高效的数据结构(如用Hash代替多个String)。
二、延迟(Latency)飙升,响应变慢
现象:
-
客户端请求响应时间波动,超过10ms。
-
redis-cli --latency
检测到周期性高延迟。
原因分析:
-
慢查询:执行时间超过1ms的命令(如
KEYS *
、大范围ZRANGE
)。 -
持久化阻塞:RDB生成或AOF重写占用主线程。
-
网络问题:带宽打满或连接数过多。
-
Swap使用:物理内存不足触发内存交换。
解决方案:
预防措施:
三、主从复制失败或数据不一致
现象:
1.从节点状态为 wait_bgsave
或 reconnecting
。
2.info replication
显示 master_link_status:down
。
原因分析:
3.主从网络不通或端口未开放。
4.主节点持久化时内存不足,导致bgsave
失败。
5.从节点写入(未设置 read-only
)。
解决方案:
-
排查慢查询:
# 查看最近慢查询日志 SLOWLOG GET 10 # 设置慢查询阈值(单位:微秒) CONFIG SET slowlog-log-slower-than 1000
-
异步持久化:
-
主节点关闭持久化,由从节点执行
bgsave
。 -
使用AOF时,选择
appendfsync everysec
(平衡性能与安全)。
-
-
优化网络:
-
使用连接池,避免频繁创建连接。
-
分片集群减少单节点压力。
-
-
避免使用
KEYS
,改用SCAN
分页遍历。 -
监控
instantaneous_ops_per_sec
和connected_clients
,合理配置tcp-backlog
。 -
检查主从连接:
# 在从节点执行,查看复制状态 REPLICAOF 主节点IP 端口 INFO replication
-
处理全量同步失败:
-
主节点确保有足够内存执行
bgsave
。 -
若数据量过大,可手动生成RDB并传输给从节点。
-
-
修复数据不一致:
# 主节点计算键差异 redis-cli -h 主节点 info keyspace # 从节点执行校验 redis-cli --eval check_replica.lua
预防措施:
-
主从节点配置相同的
hash-slots
(集群模式)。 -
启用
replica-serve-stale-data yes
避免从节点因同步中断拒绝查询。
四、缓存击穿、穿透、雪崩
场景与解决方案:
问题 | 现象 | 解决方案 |
---|---|---|
缓存击穿 | 热点Key过期后,大量请求击穿到DB | 1. 互斥锁(Redis SETNX) 2. 永不过期,逻辑过期时间更新 |
缓存穿透 | 大量查询不存在的数据 | 1. 布隆过滤器拦截 2. 空值缓存(SET null 300) |
缓存雪崩 | 大量Key同时过期,DB压力激增 | 1. 随机过期时间 2. 集群分片 3. 熔断降级(如Hystrix) |
五、客户端连接数过多或Timeout
排查步骤:
-
查看当前连接数:
redis-cli info clients # connected_clients
-
分析连接来源:
redis-cli client list | awk '{print $2}' | cut -d= -f2 | sort | uniq -c
-
释放空闲连接:
# 设置超时时间(秒) CONFIG SET timeout 60
六、持久化故障导致数据丢失
RDB与AOF选择建议:
-
高可靠性:AOF(appendfsync always) + RDB定时备份。
-
高性能:AOF(appendfsync everysec) + RDB每小时备份。
-
恢复流程:
# 先加载AOF,再加载RDB(若AOF启用)
redis-server --appendonly yes --dbfilename dump.rdb
总结:监控与最佳实践
-
必备监控项:
-
内存使用率、连接数、延迟、命中率(
keyspace_hits/(keyspace_hits+keyspace_misses)
)。 -
推荐工具:
RedisInsight
、Prometheus + Grafana
。
-
-
运维建议:
-
生产环境至少部署一主一从+哨兵。
-
避免单机多实例时开启Swap。
-
定期执行
redis-check-aof
和redis-check-rdb
检测持久化文件完整性。
-
通过以上方案,可解决90%的Redis常见问题。建议结合业务场景设计缓存策略,并在关键环节添加熔断降级机制,保障系统稳定性。