save会彻底卡住redis,直到写完rdb文件;执行时主线程停止处理所有客户端请求,同步且不可中断,仅适用于离线调试或极小数据量场景。

SAVE会彻底卡住Redis,直到写完RDB文件
执行 SAVE 时,Redis主线程会停止处理所有客户端请求,包括读、写、PING、INFO 等,直到整个数据集序列化完成并刷盘。这个过程是同步的、不可中断的。
常见错误现象:执行 SAVE 后发现 redis-cli 连接超时、应用报“Connection refused”或响应延迟飙升——不是网络问题,是Redis自己停摆了。
- 适用场景极窄:仅限离线调试、小数据量(
- 不建议在生产环境直接调用,尤其当
info memory显示used_memory_human超过 500MB 时,阻塞可能长达数秒甚至分钟 -
SAVE成功后返回OK,但你得等它返回才能继续操作——没返回前什么都干不了
BGSAVE只在fork瞬间阻塞,其余时间完全不影响服务
BGSAVE 的核心动作是 fork() 一个子进程,之后主线程立刻恢复响应。真正耗时的 RDB 写入由子进程承担,父进程不受影响。
容易踩的坑:fork 阶段虽短,但内存越大,fork 越慢。可通过 info stats 查看 latest_fork_usec(单位微秒),若超过 100000(即 100ms),说明机器内存压力大或页表复杂,需警惕。
Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。
- 执行
BGSAVE立即返回Background saving started,不是OK - 同一时间只允许一个
BGSAVE或SAVE运行;若已有子进程在做 RDB 或 AOF rewrite,BGSAVE会直接返回Background saving already in progress - 执行期间,新来的
SAVE命令会被拒绝,避免父子进程同时调用rdbSave()引发竞争
两者底层都调用rdbSave,但调用时机和上下文完全不同
SAVE 和 BGSAVE 最终都走到同一个函数 rdbSave(),区别在于谁调用、在哪调用:
-
SAVE:主线程直接调用rdbSave(),全程单线程阻塞 -
BGSAVE:主线程 fork 后,子进程调用rdbSave(),主线程继续跑 event loop - 自动触发的 RDB(如配置
save 60 10000)走的是BGSAVE路径,不是SAVE - shutdown 时的 RDB 持久化也默认用
BGSAVE逻辑,除非配置了stop-writes-on-bgsave-error no且上一次失败
别依赖SAVE做备份,BGSAVE也不等于零开销
很多人以为 BGSAVE “完全无感”,其实它有隐性成本:
- fork 会复制父进程页表,如果开启 transparent huge pages(THP),可能导致 fork 延迟激增——线上 Redis 建议关闭 THP
- 子进程与父进程共享物理内存页,但一旦父进程修改某 key,OS 会触发 copy-on-write,实际内存占用可能翻倍
- RDB 文件写入本身消耗磁盘 I/O,若磁盘已满或 IOPS 扛不住,子进程可能卡住,进而拖慢主线程后续 fork(因为要等前一个结束)
-
dump.rdb是覆盖写,多个BGSAVE并发?不可能。只会串行排队,第二个得等第一个彻底退出
真正该关心的不是“用哪个命令”,而是“是否需要持久化”以及“RDB 是否真能反映业务一致性”。比如正在做事务、或依赖 Lua 脚本原子性写入,RDB 快照那一刻的状态未必是你期望的“一致点”。










