什么情况下可能会导致 Redis 阻塞?
更多面试题请看这里:https://interview.raoyunsoft.com/
面试题专栏会持续更新欢迎关注订阅
Redis 阻塞通常由内部和外部两类原因引发,以下是具体场景分析:
一、内部原因
-
CPU 负载过高
- 复杂命令执行(如
KEYS *
、FLUSHALL
)占用大量 CPU 资源 - 大数据量聚合操作(如
SINTER
计算超大集合交集) - 单线程模型下,一个耗时操作会阻塞后续所有请求
graph TDA[客户端请求] --> B{是否耗时命令?}B -- 是 --> C[阻塞主线程]B -- 否 --> D[正常处理]
- 复杂命令执行(如
-
持久化资源竞争
- RDB 生成:
bgsave
时 fork 子进程,若数据量过大(如 20GB+),fork 操作可能阻塞主线程数百毫秒 - AOF 重写:与 RDB 类似,fork 期间会暂停服务
- AOF 同步策略:
appendfsync always
模式频繁触发磁盘写入
- RDB 生成:
-
API 使用不当
- 滥用阻塞命令(如
BLPOP
超时设置过长) - 未控制大 Key 操作(如 10MB 的 String 类型频繁读写)
- Lua 脚本执行超时(默认 5 秒限制)
- 滥用阻塞命令(如
二、外部原因
-
服务器资源瓶颈
- CPU 竞争:宿主机其他进程(如日志采集)抢占 CPU
- 内存不足:触发 Swap 导致响应延迟飙升
- 网络问题:
- 网卡带宽打满(如大量
MGET
操作) - TCP 重传率过高(网络丢包)
- 网卡带宽打满(如大量
-
操作系统限制
- THP 大页内存:Linux 透明大页导致 fork 延迟增加
- 文件描述符耗尽:连接数超过
ulimit
限制 - NUMA 架构:内存分配跨 Node 访问引发延迟
-
客户端问题
- 慢查询未拆分(如百万级
HGETALL
) - 连接池配置不合理(如最大连接数不足)
- 客户端缓冲区溢出(大量 PUB/SUB 消息积压)
- 慢查询未拆分(如百万级
关键阻塞场景对比
类型 | 典型场景 | 影响时长 | 解决方案 |
---|---|---|---|
CPU 阻塞 | SORT 10GB 列表 | 秒级 | 拆分数据或改用 SCAN |
持久化 | fork 50GB 数据集 | 100ms~2s | 关闭 THP,控制数据集 |
网络阻塞 | 千兆网卡传输 5GB 数据 | 毫秒~秒级 | 压缩数据或分片操作 |
内存压力 | 触发 Swap | 持续恶化 | 增加内存或限制 maxmemory |
💡 经验提示:可通过
SLOWLOG
命令捕获阻塞操作,结合redis-cli --latency
实时监控响应延迟。