Redis常见阻塞原因总结

Redis常见阻塞原因总结

Redis 可能出现阻塞的情况主要包括以下几种原因,并针对不同的场景提供优化方案:


1. 慢查询阻塞

原因
  • 执行耗时较长的命令,如 keys *hgetallsmembersflushall
  • 查询的数据量过大,导致单个命令执行时间过长。
  • CPU 资源占用过高,影响 Redis 的响应速度。
优化方案
  • 使用 SCAN 替代 KEYS,避免一次性扫描整个数据库。
  • 使用 HSCANSSCANZSCAN 代替 HGETALLSMEMBERS 等大数据操作。
  • 优化数据结构,减少大 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(禁止淘汰,超出内存后返回错误)。
  • 使用数据压缩 (如 zstdsnappy)减少大 key 占用的空间。
  • 定期清理无用数据,减少 Redis 负担。

4. 过多客户端连接

原因
  • 短连接频繁创建,导致 Redis 处理大量 TCP 连接,增加 CPU 开销。
  • maxclients 限制过低,导致新连接被拒绝。
优化方案
  • 使用连接池 ,如 JedisPool(Java)、hiredis(C)。
  • 提升 maxclients 配置,避免连接数过低导致客户端无法访问。
  • 开启 timeout 设置,自动关闭长时间未活跃的连接,减少资源占用。

5. 事务(MULTI/EXEC)阻塞

原因
  • 事务(MULTI + EXEC)中的命令过多,导致单个事务执行时间过长。
  • WATCH 监视的大 key 变更时,可能导致大量请求重试。
优化方案
  • 避免事务中包含 O(n) 复杂度的命令 (如 LRANGEHGETALL)。
  • 拆分事务,减少每个事务的执行时间。
  • 避免大 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 阻塞,提高系统性能和稳定性。

相关推荐
THXW.1 小时前
【Java项目与数据库、Maven的关系详解】
java·数据库·maven
DONG9132 小时前
关系型数据库:原理、演进与生态全景——从理论基石到云原生的深度巡礼
数据库·sql·mysql·database
老纪的技术唠嗑局4 小时前
硬件成本降52%,快钱支付引入OceanBase后的降本增效
数据库·架构
不是二师兄的八戒5 小时前
阿里云KMS完全指南:从零开始的密钥管理实践
数据库·阿里云·云计算
茁壮成长的露露5 小时前
openGauss逻辑备份恢复工具gs_dump/gs_restore
数据库·gaussdb
朱皮皮呀6 小时前
Redis缓存详解:内存淘汰和缓存的预热、击穿、雪崩、穿透的原理与策略
数据库·redis·缓存
Lucky GGBond6 小时前
Vue 项目中主从表异步保存实战:缓存导致接口不执行问题排查与解决
缓存
小句7 小时前
MySQL索引
数据库·mysql
TDengine (老段)7 小时前
TDengine IDMP 基本功能(3.数据三化处理)
大数据·数据库·物联网·ai·语言模型·时序数据库·tdengine
GreatSQL8 小时前
GreatSQL备份报错"PROCESS权限不足"分析与解决
数据库