Redis阻塞的全场景成因详解

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

Redis采用单线程主线程处理核心命令的架构,主线程一旦被耗时操作占用,后续所有请求都会排队等待,最终表现为Redis阻塞、客户端响应超时。以下是所有可能引发Redis阻塞的场景,按成因分类逐一说明:

一、命令执行层面阻塞(最常见、高频故障)

这类阻塞源于客户端滥用高耗时命令、操作异常数据,直接占用主线程CPU资源,是生产环境最主要的阻塞诱因。

  • 慢查询/全量遍历命令滥用:执行时间复杂度为O(n)的高危命令,且n值极大时,主线程会持续占用CPU无法切换。典型命令包括KEYS *(全库遍历键)、HGETALL/SMEMBERS(全量读取哈希/集合)、SORT(集合排序)、FLUSHALL/FLUSHDB(清空全库)。这类命令会遍历海量数据,耗时从数百毫秒到数秒不等,直接阻塞主线程。
  • 大Key相关操作阻塞:单Key存储超大体积数据(如MB级字符串、百万级成员的哈希/集合),无论是读写还是删除都会阻塞。DEL删除大Key是重灾区:Redis需同步递归释放所有元素内存,耗时极长;读取大Key会占用大量网络IO和主线程处理时间,高并发下加剧阻塞。
  • 阻塞式命令误用:使用BLPOP/BRPOP(阻塞列表弹出)、SUBSCRIBE(订阅阻塞)等命令时,若长时间无数据触发,客户端连接会持续占用主线程资源;若大量客户端同时发起阻塞命令,会导致连接积压、主线程无法响应其他请求。
  • LUA脚本执行异常:EVAL执行的LUA脚本存在死循环、超长逻辑,或操作海量数据时,LUA脚本会独占主线程直至执行完毕,期间所有命令排队阻塞;Redis默认限制脚本最长执行时间,超时后虽可终止,但仍会造成短时阻塞。

二、内存与数据淘汰阻塞

Redis内存管理机制触发异常时,主线程需同步处理内存回收、数据迁移,进而引发阻塞。

  • 集中过期Key淘汰阻塞:若大量Key设置相同过期时间,到期后Redis主线程会同步执行惰性删除+定期删除,批量回收内存耗时极长;尤其过期Key包含大Key时,阻塞时长会大幅增加,高峰期极易引发服务雪崩。
  • 内存满仓触发主动淘汰:Redis内存达到maxmemory上限,且开启内存淘汰策略(LRU/LFU/TTL等)时,主线程需先淘汰足够Key释放内存,才能处理新写入请求;淘汰海量Key时,主线程持续占用,导致请求阻塞。
  • Rehash与内存碎片整理阻塞:Redis哈希桶扩容(Rehash)、主动内存碎片整理时,主线程需同步执行数据迁移和内存规整;数据量越大、碎片越严重,阻塞时长越久,高并发场景下表现尤为明显。

三、持久化机制阻塞(核心底层阻塞)

Redis RDB/AOF持久化涉及磁盘IO、进程fork操作,部分环节会同步阻塞主线程,是底层架构导致的常见阻塞。

  • RDB fork阻塞:执行BGSAVE生成RDB时,主线程需调用fork创建子进程;fork操作会同步复制主线程内存页表,内存越大、页表越长,fork耗时越久,高峰期甚至阻塞数秒。Linux透明大页开启时,fork阻塞会进一步加剧。
  • AOF刷盘/重写阻塞:AOF日志采用fsync持久化时,若配置为always(每次命令都刷盘),磁盘IO延迟会直接传导至主线程;AOF重写过程中,若磁盘性能差、AOF文件过大,重写子进程异常会间接导致主线程积压;重写完成后替换AOF文件的瞬间,也可能引发短时阻塞。
  • 磁盘IO瓶颈阻塞:Redis所在磁盘满、磁盘读写延迟高(如机械盘、云盘性能不足),持久化写入、日志输出都会卡住主线程,进而扩散至所有客户端请求。

四、主从/集群同步阻塞

Redis主从复制、集群槽迁移涉及数据全量/增量同步,同步环节异常会引发从节点或集群节点阻塞。

  • 主从全量复制阻塞:从节点初次同步、断连重同步时,需加载主节点传输的RDB文件;RDB文件过大时,从节点主线程会持续阻塞直至加载完成,期间无法处理读写请求。
  • 增量复制积压阻塞:主节点复制积压缓冲区不足,从节点断连后无法增量同步,被迫触发全量复制;同时主节点大量写入导致缓冲区溢出,会加剧主从同步延迟,间接引发客户端阻塞。
  • 集群槽迁移/扩容阻塞:集群模式下槽迁移、节点扩容时,需批量迁移Key数据;若迁移大Key、海量Key,节点主线程会同步处理迁移逻辑,导致请求响应变慢甚至阻塞;迁移冲突、网络中断也会加重阻塞时长。

五、网络与连接层面阻塞

网络异常、连接积压会导致Redis无法正常接收/响应请求,表现为外部阻塞。

  • TCP连接队列满阻塞:高并发下客户端连接数暴增,TCP全连接队列、半连接队列溢出,Redis无法接收新连接,已建立连接的请求也会排队阻塞;netstat可观测到大量TIME_WAIT、SYN_RECV状态连接。
  • 网络IO延迟/丢包:客户端与Redis节点网络抖动、延迟高、丢包严重,主线程等待网络数据传输,导致命令处理超时;网卡带宽打满、软中断过高,也会占用系统资源,间接阻塞Redis。
  • 连接泄露/积压阻塞:客户端未正常释放连接,导致Redis连接数达到maxclients上限,新连接被拒绝;大量闲置连接占用文件句柄,主线程需轮询处理无效连接,挤占正常请求处理资源。

六、系统与环境层面阻塞(外部隐性阻塞)

服务器系统资源、内核参数异常,会间接抢占Redis资源,导致主线程无法正常运行。

  • CPU资源抢占阻塞:服务器其他进程(如MySQL、Java应用)占用大量CPU核心,Redis主线程无法获取CPU时间片,出现调度延迟;CPU上下文切换过于频繁,也会降低主线程执行效率,引发阻塞。
  • Swap内存交换阻塞:Redis实例占用物理内存过高,系统触发Swap交换,Redis数据被换出到磁盘;主线程访问数据时需从磁盘读取,速度骤降千倍,直接导致严重阻塞,这是生产环境致命隐性问题。
  • 系统参数限制阻塞:文件句柄数(open files)不足、内核tcp-backlog参数过小、内存overcommit配置不合理,都会限制Redis正常运行,引发连接、持久化环节的阻塞。

核心总结:Redis阻塞本质是主线程被占用、无法及时处理请求,排查优先定位慢查询、大Key、持久化fork、Swap内存四大高频点,再结合网络、系统资源逐层排查。

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

Redis生产 文章被收录于专栏

聚焦Redis 生产环境实战,从问题现象、根因分析、排查流程、解决方案、预防机制五大维度,系统拆解 Redis 线上高频故障与性能瓶颈,提供可直接落地的运维、开发与调优方案,助力构建高可用、高性能、高可靠的 Redis 服务体系

全部评论

相关推荐

● 自我介绍● 项目中使用的MySQL是哪个版本,有没有使用过MySQL8● 如何实现分库分表,项目中的数据表数量是多少,如何优化(https://javaguide.cn/database/mysql/mysql-high-performance-optimization-specification-recommendations.html)● MySQL常见的索引有哪些(https://javaguide.cn/database/mysql/mysql-index.html)● 聚集索引,最左匹配原则● 使用的中间件有哪些● ES的使用场景,ES是什么,底层是基于内存还是硬盘(https://www.yuque.com/snailclimb/mf2z3k/simu3iyhd87kgp3e)存储机制是 “内存 + 硬盘” 结合:硬盘持久化数据,内存缓存索引加速检索,内存影响速度,硬盘决定容量。(By豆包)● Redis的使用场景,分布式锁的使用场景(https://javaguide.cn/distributed-system/distributed-lock.html)● STW是什么吗在 Java 中,STW 是 Stop-The-World 的缩写,中文译作 “全局停顿” 或 “停止所有线程”,是 JVM(Java 虚拟机)在执行某些关键操作时,暂停所有用户线程执行的一种机制。(By豆包)● 接口如何实现幂等(https://www.yuque.com/snailclimb/mf2z3k/mlnfrc6kk95kmli6)● 接口如何做限流(https://javaguide.cn/high-availability/limit-request.html)● SpringBoot切面是什么,切面底层原理是什么● 项目中的AOP切面日志如何实现
查看13道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务