redis主线程卡顿主因是fork耗时高、appendfsync always、swap启用及大key删除;需监控latest_fork_usec、aof_delayed_fsync等指标,优化配置并避免大key。

fork 耗时高导致主线程卡顿
Redis 在执行 RDB 快照或 AOF rewrite 时,必须调用 fork 创建子进程。这个操作不是纯复制内存,而是依赖操作系统 Copy-on-Write(COW)机制——但 fork 瞬间要拷贝整个进程的虚拟内存页表,耗时与 Redis 占用的内存大小强相关。10GB 实例 fork 可能卡住 50ms,20GB 以上常达 100–300ms,期间主线程完全停止处理请求。
验证方式:redis-cli info stats | grep latest_fork_usec。如果值持续 >100000(即 >100ms),就是明确信号。
- 避免在业务高峰触发 RDB/AOF rewrite,改用
CONFIG SET save ""关闭自动保存,手动在低峰期SAVE或BGSAVE - 主从架构中,只在从库开启 AOF,主库禁用(
appendonly no),减少主库压力 - 控制单实例内存 ≤20GB,超大实例拆分到多个节点更稳妥
appendfsync always 模式同步刷盘
AOF 持久化默认配置 appendfsync everysec,每秒刷一次磁盘;但如果设为 appendfsync always,每个写命令都会调用 fsync() 强制落盘,I/O 成瓶颈,吞吐量断崖式下降,尤其在机械盘或高负载 SSD 上。
检查当前设置:redis-cli config get appendfsync。若返回 always,基本可确认是主因。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 生产环境强烈建议保持
everysec,它在性能和安全性间取得合理平衡 - 除非业务要求绝对不丢数据(如金融核心交易),否则不要用
always - 若必须用
always,需确保磁盘 I/O 能力充足(NVMe SSD + 专用挂载点),并监控redis-cli info persistence | grep aof_delayed_fsync,该值非 0 表示 fsync 积压
内存不足触发 swap 或碎片率飙升
即使没超 maxmemory,物理内存不足也会让 OS 把 Redis 部分内存页 swap 到磁盘。一旦发生,used_memory_rss / used_memory(即 mem_fragmentation_ratio)会远大于 1.5,甚至 >3,并伴随 INFO memory 中 mem_allocator 显示 jemalloc 但 used_memory_rss 暴涨。
swap 的代价是毫秒级延迟变成几十毫秒,且不可预测——你看到的“偶发慢”很可能就来自这里。
- 用
redis-cli info memory查看used_memory_rss和mem_fragmentation_ratio,比值 >1.5 就要警惕 - 用
free -h和cat /proc/meminfo | grep Swap确认系统是否启用 swap,生产环境应禁用(swapoff -a) - 定期执行
MEMORY PURGE(Redis ≥4.0)释放 jemalloc 内部碎片,或重启实例(需配合高可用方案)
大 key 删除拖慢淘汰逻辑
当 Redis 内存达到 maxmemory 后,每次写入前都要执行淘汰策略(如 allkeys-lru)。如果被选中的 key 是一个包含 10 万个字段的 HASH 或 5MB 的 STRING,删除它本身就会阻塞主线程数十毫秒。
这类问题不会立刻暴露,而是在内存持续逼近上限后,“写入变慢”才突然明显,且 SLOWLOG GET 里能看到大量 DEL 或 UNLINK 命令耗时异常。
- 用
redis-cli --bigkeys扫描潜在大 key(注意:线上慎用,建议在从库或低峰期运行) - 对已知大 key,改用
UNLINK替代DEL,后者同步删,前者异步删 - 业务层避免生成大 key:比如把大 Hash 拆成多个小 Hash,用
HSCAN分批读取
INFO 和 SLOWLOG 把现象锚定到具体环节,再动手。










