Redis常见阻塞原因总结
Redis 可能出现阻塞的情况主要包括以下几种原因,并针对不同的场景提供优化方案:
1. 慢查询阻塞
原因
- 执行耗时较长的命令,如 keys *、hgetall、smembers、flushall。
- 查询的数据量过大,导致单个命令执行时间过长。
- CPU 资源占用过高,影响 Redis 的响应速度。
优化方案
- 使用 SCAN替代KEYS,避免一次性扫描整个数据库。
- 使用 HSCAN、SSCAN、ZSCAN代替HGETALL、SMEMBERS等大数据操作。
- 优化数据结构,减少大 Key 的使用,改用分片存储。
- 开启慢查询日志(slowlog-log-slower-than参数),排查耗时操作并优化。
2. 持久化(RDB/AOF)阻塞
原因
- RDB 触发 BGSAVE进程时,fork 进程占用大量 CPU 和内存。
- AOF 追加模式下,AOF 文件过大,重写(BGREWRITEAOF)时影响性能。
- AOF 同步写入 (appendfsync always) 可能导致 I/O 阻塞。
优化方案
-  调整 RDB 触发策略 ,避免频繁 fork 进程: - 适当延长 save配置中的触发时间间隔。
- 业务高峰期可临时关闭自动 RDB 触发,改为手动触发。
 
- 适当延长 
-  AOF 配置优化: - 使用 appendfsync everysec代替always,减少磁盘 I/O。
- 定期 BGREWRITEAOF避免 AOF 过大。
- 业务高峰期避免 AOF 重写,改为低峰时段执行。
 
- 使用 
3. 内存不足导致 OOM(Out of Memory)
原因
- 数据增长超出可用内存,Redis 进程可能被 OOM 终止。
- 内存淘汰策略未配置,导致无法存入新数据。
优化方案
- 设置 maxmemory限制 Redis 的最大内存,避免超过物理机可用内存。
- 选择合适的淘汰策略: - volatile-lru(淘汰最近最少使用的可过期 key)。
- allkeys-lru(淘汰所有 key 中最近最少使用的)。
- volatile-ttl(淘汰快过期的 key)。
- noeviction(禁止淘汰,超出内存后返回错误)。
 
- 使用数据压缩(如 zstd、snappy)减少大 key 占用的空间。
- 定期清理无用数据,减少 Redis 负担。
4. 过多客户端连接
原因
- 短连接频繁创建,导致 Redis 处理大量 TCP 连接,增加 CPU 开销。
- maxclients限制过低,导致新连接被拒绝。
优化方案
- 使用连接池,如 JedisPool(Java)、hiredis(C)。
- 提升 maxclients配置,避免连接数过低导致客户端无法访问。
- 开启 timeout设置,自动关闭长时间未活跃的连接,减少资源占用。
5. 事务(MULTI/EXEC)阻塞
原因
- 事务(MULTI+EXEC)中的命令过多,导致单个事务执行时间过长。
- 在 WATCH监视的大 key 变更时,可能导致大量请求重试。
优化方案
- 避免事务中包含 O(n) 复杂度的命令(如 LRANGE、HGETALL)。
- 拆分事务,减少每个事务的执行时间。
- 避免大 key 监视,改用更细粒度的数据结构。
6. Lua 脚本执行阻塞
原因
- Redis 单线程执行 Lua 脚本,长时间运行的脚本会阻塞其他请求。
- EVAL语句包含 O(n) 复杂度操作,影响整体性能。
优化方案
- 使用 EVALSHA复用已加载的 Lua 脚本,避免重复编译。
- 限制 Lua 脚本的执行时间,可使用 redis-cli --intrinsic-latency进行监测。
- 复杂计算逻辑迁移到应用层,减少 Redis 计算压力。
7. 网络带宽/流量过高
原因
- MONITOR命令开启时,Redis 会记录所有请求,影响性能。
- Redis 传输的数据量过大,可能导致带宽不足。
优化方案
-  关闭 MONITOR,避免实时记录影响性能。
-  启用 TCP_NODELAY,减少 TCP 延迟。
-  使用 pipeline进行批量请求,减少网络往返次数。
-  优化数据结构 ,减少大 key 的传输,例如: - 使用 HyperLogLog代替Set进行基数统计。
- 用 Bitmaps代替List进行状态记录。
 
- 使用 
总结
| 问题类型 | 优化方案 | 
|---|---|
| 慢查询 | 使用 SCAN代替KEYS,优化数据结构 | 
| 持久化 | 调整 RDB 触发策略,优化 AOF 配置 | 
| 内存不足 | 配置 maxmemory,使用合适的淘汰策略 | 
| 连接过多 | 使用连接池,提高 maxclients | 
| 事务阻塞 | 拆分事务,避免大 key 监视 | 
| Lua 阻塞 | 限制脚本执行时间,优化计算逻辑 | 
| 网络流量 | 关闭 MONITOR,使用pipeline | 
通过这些优化手段,可以有效减少 Redis 阻塞,提高系统性能和稳定性。
