bgsave会让磁盘IO跑满,因其是全量内存快照序列化后一次性大块连续写盘,云环境使用低IOPS云盘(如ESSD PL0,仅300–1000 IOPS)时易打满IO队列,表现为“No space left on device”错误(实际空间充足)、rdb_bgsave_in_progress卡死、P99延迟飙升、iostat中await > 50ms且avgqu-sz > 1。

为什么bgsave会让磁盘IO跑满
bgsave不是“后台安静写入”,而是全量内存快照序列化 + 一次性的大块连续写盘。尤其在云环境,若用的是入门级ESSD PL0或普通SSD(IOPS仅300–1000),一次几百MB的RDB写入就足以打满IO队列。现象是:No space left on device报错(实际空间充足)、rdb_bgsave_in_progress卡死、Redis延迟P99飙升,iostat -x 1里await > 50ms、avgqu-sz > 1。
调大save触发间隔是最直接有效的缓解手段
默认save 900 1意味着“15分钟内任意1个key变更就触发bgsave”,高写入场景下等于每分钟都在刷盘。这不是bug,是配置和业务节奏严重不匹配。
- 先查真实变更节奏:
redis-cli info stats | grep changes_since_last_save+redis-cli info server | grep uptime_in_seconds,算出平均每分钟变更数 - 再设合理阈值:比如平均1分钟改200个key,
save 300 1000(5分钟+1000变更)比默认save 60 10000更稳 - 禁用某条规则必须注释整行,如
# save 900 1;别写save "",旧版本可能解析异常 - 改完
redis.conf后必须redis-cli config rewrite或重启,否则config get save仍返回旧值
启用repl-diskless-sync跳过主节点落盘(仅限全量同步)
这个配置不减少RDB生成,但让主节点把RDB内容直接通过socket发给从库,绕过本地磁盘写入。但它不是开个开关就完事:
- 必须配对设置
repl-diskless-sync-delay 5(防多个从库同时触发fork) - 必须调大缓冲区:
client-output-buffer-limit slave 256mb 64mb 60 - 检查是否真生效:日志里出现
Background saving started但**没有**RDB saved on disk才说明走无盘路径 - 注意:它只影响主从全量同步,不影响定时
bgsave,所以仍需调save参数
确认RDB真正落盘路径并监控对应磁盘
dir配置决定RDB写哪,而它常指向独立挂载点(如/data/redis)。你查df -h /看到还有40%空间,但df -h $(redis-cli config get dir | tail -1)可能已到98%——这才是bgsave失败的根因。
- 务必用
redis-cli config get dir拿到真实路径,再df -h查该路径所在分区 - 云数据库(如阿里云Redis)要盯控制台“磁盘使用率”,SSH进不去真实文件系统
- 临时救急可删
temp-*.rdb和旧.rdb(确认从库已追平),但别碰正在用的dump.rdb - 长期必须加告警:
disk_usage_percent > 85%,阈值不能只看Redis内存
真正的难点不在命令怎么敲,而在于你得清楚:这次调save间隔,是准备接受最多丢5分钟数据,还是已有AOF+从库兜底;以及那个dir路径,到底有没有被其他日志或临时文件悄悄占满。











